Skip to content

Commit d7a5d51

Browse files
committed
tests
1 parent 742aa34 commit d7a5d51

File tree

5 files changed

+231
-22
lines changed

5 files changed

+231
-22
lines changed

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,11 @@ private func createResolvedPackages(
558558
var duplicateTargetsAddressed = [String]()
559559
for potentiallyDuplicatePackage in potentiallyDuplicatePackages {
560560
// more than three target matches, or all targets in the package match
561-
if potentiallyDuplicatePackage.value.count > 3 || potentiallyDuplicatePackage.value.sorted() == potentiallyDuplicatePackage.key.package1.targets.map({ $0.name }).sorted() {
561+
if potentiallyDuplicatePackage.value.count > 3 ||
562+
(potentiallyDuplicatePackage.value.sorted() == potentiallyDuplicatePackage.key.package1.targets.map({ $0.name }).sorted()
563+
&&
564+
potentiallyDuplicatePackage.value.sorted() == potentiallyDuplicatePackage.key.package2.targets.map({ $0.name }).sorted())
565+
{
562566
switch (potentiallyDuplicatePackage.key.package1.identity.registry, potentiallyDuplicatePackage.key.package2.identity.registry) {
563567
case (.some(let registryIdentity), .none):
564568
observabilityScope.emit(

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,17 @@ extension ModuleError: CustomStringConvertible {
141141
case .embedInCodeNotSupported(let target):
142142
return "embedding resources in code not supported for C-family language target \(target)"
143143
case .duplicateModules(let package, let otherPackage, let targets):
144-
let targets = targets.sorted().joined(separator: "', '")
145-
return "multiple identical targets '\(targets)' appear in package '\(package)' and '\(otherPackage)', this may indicate that the two packages are the same and can be de-duplicated by using mirrors. if they are not duplicate consider using the `moduleAliases` parameter in manifest to provide unique names"
146-
case .duplicateModulesScmAndRegistry(let regsitryPackage, let scmPackage, let targets):
147-
let targets = targets.sorted().joined(separator: "', '")
148-
return "multiple identical targets '\(targets)' appear in registry package '\(regsitryPackage)' and source control package '\(scmPackage)', this may indicate that the two packages are the same and can be de-duplicated by activating the automatic source-control to registry replacement, or by using mirrors. if they are not duplicate consider using the `moduleAliases` parameter in manifest to provide unique names"
144+
var targetsDescription = "'\(targets.sorted().prefix(3).joined(separator: "', '"))'"
145+
if targets.count > 3 {
146+
targetsDescription += " and \(targets.count - 3) others"
147+
}
148+
return "multiple similar targets \(targetsDescription) appear in package '\(package)' and '\(otherPackage)', this may indicate that the two packages are the same and can be de-duplicated by using mirrors. if they are not duplicate consider using the `moduleAliases` parameter in manifest to provide unique names"
149+
case .duplicateModulesScmAndRegistry(let registryPackage, let scmPackage, let targets):
150+
var targetsDescription = "'\(targets.sorted().prefix(3).joined(separator: "', '"))'"
151+
if targets.count > 3 {
152+
targetsDescription += " and \(targets.count - 3) others"
153+
}
154+
return "multiple similar targets \(targetsDescription) appear in registry package '\(registryPackage)' and source control package '\(scmPackage)', this may indicate that the two packages are the same and can be de-duplicated by activating the automatic source-control to registry replacement, or by using mirrors. if they are not duplicate consider using the `moduleAliases` parameter in manifest to provide unique names"
149155
}
150156
}
151157
}

Sources/SPMTestSupport/ManifestExtensions.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,43 @@ extension Manifest {
161161
)
162162
}
163163

164+
public static func createRegistryManifest(
165+
displayName: String,
166+
identity: PackageIdentity,
167+
path: AbsolutePath = .root,
168+
defaultLocalization: String? = nil,
169+
platforms: [PlatformDescription] = [],
170+
version: TSCUtility.Version? = nil,
171+
toolsVersion: ToolsVersion = .v4,
172+
pkgConfig: String? = nil,
173+
providers: [SystemPackageProviderDescription]? = nil,
174+
cLanguageStandard: String? = nil,
175+
cxxLanguageStandard: String? = nil,
176+
swiftLanguageVersions: [SwiftLanguageVersion]? = nil,
177+
dependencies: [PackageDependency] = [],
178+
products: [ProductDescription] = [],
179+
targets: [TargetDescription] = []
180+
) -> Manifest {
181+
Self.createManifest(
182+
displayName: displayName,
183+
path: path,
184+
packageKind: .registry(identity),
185+
packageLocation: identity.description,
186+
defaultLocalization: defaultLocalization,
187+
platforms: platforms,
188+
version: version,
189+
toolsVersion: toolsVersion,
190+
pkgConfig: pkgConfig,
191+
providers: providers,
192+
cLanguageStandard: cLanguageStandard,
193+
cxxLanguageStandard: cxxLanguageStandard,
194+
swiftLanguageVersions: swiftLanguageVersions,
195+
dependencies: dependencies,
196+
products: products,
197+
targets: targets
198+
)
199+
}
200+
164201
public static func createManifest(
165202
displayName: String,
166203
path: AbsolutePath = .root,
@@ -181,7 +218,7 @@ extension Manifest {
181218
) -> Manifest {
182219
return Manifest(
183220
displayName: displayName,
184-
path: path.basename == Manifest.filename ? path : path.appending(component: Manifest.filename) ,
221+
path: path.basename == Manifest.filename ? path : path.appending(component: Manifest.filename),
185222
packageKind: packageKind,
186223
packageLocation: packageLocation ?? path.pathString,
187224
defaultLocalization: defaultLocalization,

Tests/PackageGraphTests/PackageGraphTests.swift

Lines changed: 169 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,10 @@ class PackageGraphTests: XCTestCase {
263263

264264
func testDuplicateModules() throws {
265265
let fs = InMemoryFileSystem(emptyFiles:
266+
"/Foo/Sources/Foo/source.swift",
266267
"/Foo/Sources/Bar/source.swift",
267-
"/Bar/Sources/Bar/source.swift"
268+
"/Bar/Sources/Bar/source.swift",
269+
"/Bar/Sources/Baz/source.swift"
268270
)
269271

270272
let observability = ObservabilitySystem.makeForTesting()
@@ -278,13 +280,15 @@ class PackageGraphTests: XCTestCase {
278280
.localSourceControl(path: .init(path: "/Bar"), requirement: .upToNextMajor(from: "1.0.0"))
279281
],
280282
targets: [
283+
TargetDescription(name: "Foo"),
281284
TargetDescription(name: "Bar"),
282285
]),
283286
Manifest.createRootManifest(
284287
displayName: "Bar",
285288
path: .init(path: "/Bar"),
286289
targets: [
287290
TargetDescription(name: "Bar"),
291+
TargetDescription(name: "Baz"),
288292
]),
289293
],
290294
observabilityScope: observability.topScope
@@ -356,9 +360,13 @@ class PackageGraphTests: XCTestCase {
356360

357361
func testSeveralDuplicateModules() throws {
358362
let fs = InMemoryFileSystem(emptyFiles:
363+
"/Fourth/Sources/Fourth/source.swift",
359364
"/Fourth/Sources/Bar/source.swift",
365+
"/Third/Sources/Third/source.swift",
360366
"/Third/Sources/Bar/source.swift",
367+
"/Second/Sources/Second/source.swift",
361368
"/Second/Sources/Foo/source.swift",
369+
"/First/Sources/First/source.swift",
362370
"/First/Sources/Foo/source.swift"
363371
)
364372

@@ -370,27 +378,30 @@ class PackageGraphTests: XCTestCase {
370378
displayName: "Fourth",
371379
path: .init(path: "/Fourth"),
372380
products: [
373-
ProductDescription(name: "Fourth", type: .library(.automatic), targets: ["Bar"])
381+
ProductDescription(name: "Fourth", type: .library(.automatic), targets: ["Fourth", "Bar"])
374382
],
375383
targets: [
384+
TargetDescription(name: "Fourth"),
376385
TargetDescription(name: "Bar"),
377386
]),
378387
Manifest.createFileSystemManifest(
379388
displayName: "Third",
380389
path: .init(path: "/Third"),
381390
products: [
382-
ProductDescription(name: "Third", type: .library(.automatic), targets: ["Bar"])
391+
ProductDescription(name: "Third", type: .library(.automatic), targets: ["Third", "Bar"])
383392
],
384393
targets: [
394+
TargetDescription(name: "Third"),
385395
TargetDescription(name: "Bar"),
386396
]),
387397
Manifest.createFileSystemManifest(
388398
displayName: "Second",
389399
path: .init(path: "/Second"),
390400
products: [
391-
ProductDescription(name: "Second", type: .library(.automatic), targets: ["Foo"])
401+
ProductDescription(name: "Second", type: .library(.automatic), targets: ["Second", "Foo"])
392402
],
393403
targets: [
404+
TargetDescription(name: "Second"),
394405
TargetDescription(name: "Foo"),
395406
]),
396407
Manifest.createRootManifest(
@@ -401,22 +412,27 @@ class PackageGraphTests: XCTestCase {
401412
.localSourceControl(path: .init(path: "/Third"), requirement: .upToNextMajor(from: "1.0.0")),
402413
.localSourceControl(path: .init(path: "/Fourth"), requirement: .upToNextMajor(from: "1.0.0")),
403414
],
415+
products: [
416+
ProductDescription(name: "First", type: .library(.automatic), targets: ["First", "Foo"])
417+
],
404418
targets: [
419+
TargetDescription(name: "First"),
405420
TargetDescription(name: "Foo", dependencies: ["Second", "Third", "Fourth"]),
406421
]),
407422
],
408423
observabilityScope: observability.topScope
409424
)
410425

411426
testDiagnostics(observability.diagnostics) { result in
412-
result.check(diagnostic: "multiple targets named 'Bar' in: 'fourth', 'third'; consider using the `moduleAliases` parameter in manifest to provide unique names", severity: .error)
413-
result.check(diagnostic: "multiple targets named 'Foo' in: 'first', 'second'; consider using the `moduleAliases` parameter in manifest to provide unique names", severity: .error)
427+
result.checkUnordered(diagnostic: "multiple targets named 'Bar' in: 'fourth', 'third'; consider using the `moduleAliases` parameter in manifest to provide unique names", severity: .error)
428+
result.checkUnordered(diagnostic: "multiple targets named 'Foo' in: 'first', 'second'; consider using the `moduleAliases` parameter in manifest to provide unique names", severity: .error)
414429
}
415430
}
416431

417432
func testNestedDuplicateModules() throws {
418433
let fs = InMemoryFileSystem(emptyFiles:
419434
"/Fourth/Sources/First/source.swift",
435+
"/Fourth/Sources/Fourth/source.swift",
420436
"/Third/Sources/Third/source.swift",
421437
"/Second/Sources/Second/source.swift",
422438
"/First/Sources/First/source.swift"
@@ -430,9 +446,10 @@ class PackageGraphTests: XCTestCase {
430446
displayName: "Fourth",
431447
path: .init(path: "/Fourth"),
432448
products: [
433-
ProductDescription(name: "Fourth", type: .library(.automatic), targets: ["First"])
449+
ProductDescription(name: "Fourth", type: .library(.automatic), targets: ["Fourth", "First"])
434450
],
435451
targets: [
452+
TargetDescription(name: "Fourth"),
436453
TargetDescription(name: "First"),
437454
]),
438455
Manifest.createFileSystemManifest(
@@ -480,6 +497,151 @@ class PackageGraphTests: XCTestCase {
480497
}
481498
}
482499

500+
func testPotentiallyDuplicatePackages() throws {
501+
let fs = InMemoryFileSystem(emptyFiles:
502+
"/First/Sources/Foo/source.swift",
503+
"/First/Sources/Bar/source.swift",
504+
"/Second/Sources/Foo/source.swift",
505+
"/Second/Sources/Bar/source.swift"
506+
)
507+
508+
let observability = ObservabilitySystem.makeForTesting()
509+
_ = try loadPackageGraph(
510+
fileSystem: fs,
511+
manifests: [
512+
Manifest.createRootManifest(
513+
displayName: "First",
514+
path: .init(path: "/First"),
515+
dependencies: [
516+
.localSourceControl(path: .init(path: "/Second"), requirement: .upToNextMajor(from: "1.0.0")),
517+
],
518+
products: [
519+
ProductDescription(name: "First", type: .library(.automatic), targets: ["Foo", "Bar"])
520+
],
521+
targets: [
522+
TargetDescription(name: "Foo"),
523+
TargetDescription(name: "Bar"),
524+
]),
525+
Manifest.createLocalSourceControlManifest(
526+
displayName: "Second",
527+
path: .init(path: "/Second"),
528+
products: [
529+
ProductDescription(name: "Second", type: .library(.automatic), targets: ["Foo", "Bar"])
530+
],
531+
targets: [
532+
TargetDescription(name: "Foo"),
533+
TargetDescription(name: "Bar"),
534+
]),
535+
],
536+
observabilityScope: observability.topScope
537+
)
538+
539+
testDiagnostics(observability.diagnostics) { result in
540+
result.check(diagnostic: .contains("multiple similar targets 'Bar', 'Foo' appear in package 'first' and 'second'"), severity: .error)
541+
}
542+
}
543+
544+
func testPotentiallyDuplicatePackagesManyTargets() throws {
545+
let fs = InMemoryFileSystem(emptyFiles:
546+
"/First/Sources/Foo/source.swift",
547+
"/First/Sources/Bar/source.swift",
548+
"/First/Sources/Baz/source.swift",
549+
"/First/Sources/Qux/source.swift",
550+
"/First/Sources/Quux/source.swift",
551+
"/Second/Sources/Foo/source.swift",
552+
"/Second/Sources/Bar/source.swift",
553+
"/Second/Sources/Baz/source.swift",
554+
"/Second/Sources/Qux/source.swift",
555+
"/Second/Sources/Quux/source.swift"
556+
)
557+
558+
let observability = ObservabilitySystem.makeForTesting()
559+
_ = try loadPackageGraph(
560+
fileSystem: fs,
561+
manifests: [
562+
Manifest.createRootManifest(
563+
displayName: "First",
564+
path: .init(path: "/First"),
565+
dependencies: [
566+
.localSourceControl(path: .init(path: "/Second"), requirement: .upToNextMajor(from: "1.0.0")),
567+
],
568+
products: [
569+
ProductDescription(name: "First", type: .library(.automatic), targets: ["Foo", "Bar", "Baz", "Qux", "Quux"])
570+
],
571+
targets: [
572+
TargetDescription(name: "Foo"),
573+
TargetDescription(name: "Bar"),
574+
TargetDescription(name: "Baz"),
575+
TargetDescription(name: "Qux"),
576+
TargetDescription(name: "Quux"),
577+
]),
578+
Manifest.createLocalSourceControlManifest(
579+
displayName: "Second",
580+
path: .init(path: "/Second"),
581+
products: [
582+
ProductDescription(name: "Second", type: .library(.automatic), targets: ["Foo", "Bar", "Baz", "Qux", "Quux"])
583+
],
584+
targets: [
585+
TargetDescription(name: "Foo"),
586+
TargetDescription(name: "Bar"),
587+
TargetDescription(name: "Baz"),
588+
TargetDescription(name: "Qux"),
589+
TargetDescription(name: "Quux"),
590+
]),
591+
],
592+
observabilityScope: observability.topScope
593+
)
594+
595+
testDiagnostics(observability.diagnostics) { result in
596+
result.check(diagnostic: .contains("multiple similar targets 'Bar', 'Baz', 'Foo' and 2 others appear in package 'first' and 'second'"), severity: .error)
597+
}
598+
}
599+
600+
func testPotentiallyDuplicatePackagesRegistrySCM() throws {
601+
let fs = InMemoryFileSystem(emptyFiles:
602+
"/First/Sources/Foo/source.swift",
603+
"/First/Sources/Bar/source.swift",
604+
"/Second/Sources/Foo/source.swift",
605+
"/Second/Sources/Bar/source.swift"
606+
)
607+
608+
let observability = ObservabilitySystem.makeForTesting()
609+
_ = try loadPackageGraph(
610+
fileSystem: fs,
611+
manifests: [
612+
Manifest.createRootManifest(
613+
displayName: "First",
614+
path: .init(path: "/First"),
615+
dependencies: [
616+
.registry(identity: "test.second", requirement: .upToNextMajor(from: "1.0.0")),
617+
],
618+
products: [
619+
ProductDescription(name: "First", type: .library(.automatic), targets: ["Foo", "Bar"])
620+
],
621+
targets: [
622+
TargetDescription(name: "Foo"),
623+
TargetDescription(name: "Bar"),
624+
]),
625+
Manifest.createRegistryManifest(
626+
displayName: "Second",
627+
identity: .plain("test.second"),
628+
path: .init(path: "/Second"),
629+
products: [
630+
ProductDescription(name: "Second", type: .library(.automatic), targets: ["Foo", "Bar"])
631+
],
632+
targets: [
633+
TargetDescription(name: "Foo"),
634+
TargetDescription(name: "Bar"),
635+
]),
636+
],
637+
observabilityScope: observability.topScope
638+
)
639+
640+
testDiagnostics(observability.diagnostics) { result in
641+
result.check(diagnostic: .contains("multiple similar targets 'Bar', 'Foo' appear in registry package 'test.second' and source control package 'first'"), severity: .error)
642+
}
643+
}
644+
483645
func testEmptyDependency() throws {
484646
let Bar: AbsolutePath = AbsolutePath("/Bar")
485647

0 commit comments

Comments
 (0)