Skip to content

Commit fbbda78

Browse files
committed
more tests
1 parent e237516 commit fbbda78

File tree

4 files changed

+150
-10
lines changed

4 files changed

+150
-10
lines changed

Sources/PackageGraph/PackageGraph+Loading.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,10 @@ private func createResolvedPackages(
270270
} else {
271271
return packageObservabilityScope.emit(error)
272272
}
273+
} else if resolvedPackage.package.manifest.canonicalPackageLocation == dependencyPackageRef.canonicalLocation &&
274+
resolvedPackage.package.manifest.packageLocation != dependencyPackageRef.locationString &&
275+
!resolvedPackage.allowedToOverride {
276+
packageObservabilityScope.emit(info: "dependency on '\(resolvedPackage.package.identity)' is represented by similar locations ('\(resolvedPackage.package.manifest.packageLocation)' and '\(dependencyPackageRef.locationString)') which are treated as the same canonical location '\(dependencyPackageRef.canonicalLocation)'.")
273277
}
274278

275279
// checks if two dependencies have the same explicit name which can cause target based dependency package lookup issue

Sources/PackageModel/PackageIdentity.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ struct PackageIdentityParser {
384384
/// ```
385385
/// file:///Users/mona/LinkedList → /Users/mona/LinkedList
386386
/// ```
387-
public struct CanonicalPackageLocation: Equatable {
387+
public struct CanonicalPackageLocation: Equatable, CustomStringConvertible {
388388
/// A textual representation of this instance.
389389
public let description: String
390390

Sources/SPMTestSupport/Observability.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,17 @@ public func testDiagnostics(
9090
line: UInt = #line,
9191
handler: (DiagnosticsTestResult) throws -> Void
9292
) {
93-
let diagnostics = problemsOnly ? diagnostics.filter({ $0.severity >= .warning }) : diagnostics
93+
testDiagnostics(diagnostics, minSeverity: problemsOnly ? .warning : .debug, file: file, line: line, handler: handler)
94+
}
95+
96+
public func testDiagnostics(
97+
_ diagnostics: [Basics.Diagnostic],
98+
minSeverity: Basics.Diagnostic.Severity,
99+
file: StaticString = #file,
100+
line: UInt = #line,
101+
handler: (DiagnosticsTestResult) throws -> Void
102+
) {
103+
let diagnostics = diagnostics.filter{ $0.severity >= minSeverity }
94104
let testResult = DiagnosticsTestResult(diagnostics)
95105

96106
do {

Tests/WorkspaceTests/WorkspaceTests.swift

Lines changed: 134 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4112,15 +4112,15 @@ final class WorkspaceTests: XCTestCase {
41124112
],
41134113
products: [],
41144114
dependencies: [
4115-
.sourceControl(url: "https://localhost/bar", requirement: .upToNextMajor(from: "1.0.0")),
4116-
.sourceControl(url: "https://localhost/baz", requirement: .upToNextMajor(from: "1.0.0"))
4115+
.sourceControl(url: "https://localhost/org/bar", requirement: .upToNextMajor(from: "1.0.0")),
4116+
.sourceControl(url: "https://localhost/org/baz", requirement: .upToNextMajor(from: "1.0.0"))
41174117
]
41184118
),
41194119
],
41204120
packages: [
41214121
MockPackage(
41224122
name: "Bar",
4123-
url: "https://localhost/bar",
4123+
url: "https://localhost/org/bar",
41244124
targets: [
41254125
MockTarget(name: "Bar", dependencies: [
41264126
.product(name: "Baz", package: "Baz")
@@ -4130,13 +4130,24 @@ final class WorkspaceTests: XCTestCase {
41304130
MockProduct(name: "Bar", targets: ["Bar"])
41314131
],
41324132
dependencies: [
4133-
.sourceControl(url: "https://localhost/Baz", requirement: .upToNextMajor(from: "1.0.0"))
4133+
.sourceControl(url: "https://localhost/org/Baz", requirement: .upToNextMajor(from: "1.0.0"))
41344134
],
41354135
versions: ["1.0.0"]
41364136
),
41374137
MockPackage(
41384138
name: "Baz",
4139-
url: "https://localhost/baz",
4139+
url: "https://localhost/org/baz",
4140+
targets: [
4141+
MockTarget(name: "Baz"),
4142+
],
4143+
products: [
4144+
MockProduct(name: "Baz", targets: ["Baz"])
4145+
],
4146+
versions: ["1.0.0"]
4147+
),
4148+
MockPackage(
4149+
name: "Baz",
4150+
url: "https://localhost/org/Baz",
41404151
targets: [
41414152
MockTarget(name: "Baz"),
41424153
],
@@ -4155,14 +4166,19 @@ final class WorkspaceTests: XCTestCase {
41554166
result.checkTarget("Foo") { result in result.check(dependencies: "Bar", "Baz") }
41564167
result.checkTarget("Bar") { result in result.check(dependencies: "Baz") }
41574168
}
4158-
XCTAssertNoDiagnostics(diagnostics)
4169+
testDiagnostics(diagnostics, minSeverity: .info) { result in
4170+
result.checkUnordered(
4171+
diagnostic: "dependency on 'baz' is represented by similar locations ('https://localhost/org/baz' and 'https://localhost/org/Baz') which are treated as the same canonical location 'localhost/org/baz'.",
4172+
severity: .info
4173+
)
4174+
}
41594175
}
41604176
workspace.checkManagedDependencies { result in
41614177
result.check(dependency: "bar", at: .checkout(.version("1.0.0")))
41624178
result.check(dependency: "baz", at: .checkout(.version("1.0.0")))
4163-
XCTAssertEqual(result.managedDependencies[.plain("bar")]?.packageRef.locationString, "https://localhost/bar")
4179+
XCTAssertEqual(result.managedDependencies[.plain("bar")]?.packageRef.locationString, "https://localhost/org/bar")
41644180
// root casing should win, so testing for lower case
4165-
XCTAssertEqual(result.managedDependencies[.plain("baz")]?.packageRef.locationString, "https://localhost/baz")
4181+
XCTAssertEqual(result.managedDependencies[.plain("baz")]?.packageRef.locationString, "https://localhost/org/baz")
41664182
}
41674183
}
41684184

@@ -8109,6 +8125,116 @@ final class WorkspaceTests: XCTestCase {
81098125
}
81108126
}
81118127

8128+
func testDuplicateTransitiveIdentityWithSimilarURLs() throws {
8129+
let sandbox = AbsolutePath("/tmp/ws/")
8130+
let fs = InMemoryFileSystem()
8131+
8132+
let workspace = try MockWorkspace(
8133+
sandbox: sandbox,
8134+
fileSystem: fs,
8135+
roots: [
8136+
MockPackage(
8137+
name: "Root",
8138+
targets: [
8139+
MockTarget(name: "RootTarget", dependencies: [
8140+
.product(name: "FooProduct", package: "foo"),
8141+
.product(name: "BarProduct", package: "bar"),
8142+
.product(name: "BazProduct", package: "baz")
8143+
]),
8144+
],
8145+
products: [],
8146+
dependencies: [
8147+
.sourceControl(url: "https://github.com/org/foo.git", requirement: .upToNextMajor(from: "1.0.0")),
8148+
.sourceControl(url: "https://github.com/org/bar.git", requirement: .upToNextMajor(from: "1.0.0")),
8149+
.sourceControl(url: "https://github.com/org/baz.git", requirement: .upToNextMajor(from: "1.0.0")),
8150+
],
8151+
toolsVersion: .v5_6
8152+
),
8153+
],
8154+
packages: [
8155+
MockPackage(
8156+
name: "FooPackage",
8157+
url: "https://github.com/org/foo.git",
8158+
targets: [
8159+
MockTarget(name: "FooTarget"),
8160+
],
8161+
products: [
8162+
MockProduct(name: "FooProduct", targets: ["FooTarget"]),
8163+
],
8164+
versions: ["1.0.0"]
8165+
),
8166+
MockPackage(
8167+
name: "BarPackage",
8168+
url: "https://github.com/org/bar.git",
8169+
targets: [
8170+
MockTarget(name: "BarTarget", dependencies: [
8171+
.product(name: "FooProduct", package: "Foo"),
8172+
.product(name: "BazProduct", package: "baz"),
8173+
]),
8174+
],
8175+
products: [
8176+
MockProduct(name: "BarProduct", targets: ["BarTarget"]),
8177+
],
8178+
dependencies: [
8179+
.sourceControl(url: "https://github.com/ORG/Foo.git", requirement: .upToNextMajor(from: "1.0.0")),
8180+
.sourceControl(url: "https://github.com/org/baz", requirement: .upToNextMajor(from: "1.0.0")),
8181+
],
8182+
versions: ["1.0.0"]
8183+
),
8184+
MockPackage(
8185+
name: "BazPackage",
8186+
url: "https://github.com/org/baz.git",
8187+
targets: [
8188+
MockTarget(name: "BazTarget"),
8189+
],
8190+
products: [
8191+
MockProduct(name: "BazProduct", targets: ["BazTarget"]),
8192+
],
8193+
versions: ["1.0.0"]
8194+
),
8195+
// URL with different casing
8196+
MockPackage(
8197+
name: "FooPackage",
8198+
url: "https://github.com/ORG/Foo.git",
8199+
targets: [
8200+
MockTarget(name: "FooTarget"),
8201+
],
8202+
products: [
8203+
MockProduct(name: "FooProduct", targets: ["FooTarget"]),
8204+
],
8205+
versions: ["1.0.0"]
8206+
),
8207+
// URL with no .git extension
8208+
MockPackage(
8209+
name: "BazPackage",
8210+
url: "https://github.com/org/baz",
8211+
targets: [
8212+
MockTarget(name: "BazTarget"),
8213+
],
8214+
products: [
8215+
MockProduct(name: "BazProduct", targets: ["BazTarget"]),
8216+
],
8217+
versions: ["1.0.0"]
8218+
),
8219+
]
8220+
)
8221+
8222+
// 9/2021 this is currently emitting a warning only to support backwards compatibility
8223+
// we will escalate this to an error in a few versions to tighten up the validation
8224+
try workspace.checkPackageGraph(roots: ["Root"]) { graph, diagnostics in
8225+
testDiagnostics(diagnostics, minSeverity: .info) { result in
8226+
result.checkUnordered(
8227+
diagnostic: "dependency on 'foo' is represented by similar locations ('https://github.com/org/foo.git' and 'https://github.com/ORG/Foo.git') which are treated as the same canonical location 'github.com/org/foo'.",
8228+
severity: .info
8229+
)
8230+
result.checkUnordered(
8231+
diagnostic: "dependency on 'baz' is represented by similar locations ('https://github.com/org/baz.git' and 'https://github.com/org/baz') which are treated as the same canonical location 'github.com/org/baz'.",
8232+
severity: .info
8233+
)
8234+
}
8235+
}
8236+
}
8237+
81128238
func testDuplicateNestedTransitiveIdentityWithNames() throws {
81138239
let sandbox = AbsolutePath("/tmp/ws/")
81148240
let fs = InMemoryFileSystem()

0 commit comments

Comments
 (0)