Skip to content

Commit 4f402d7

Browse files
committed
Added support for properly creating relative paths even when the pivot isn't a full prefix of the path. Also fixed Xcode project generation at non-root path.
1 parent 57c869a commit 4f402d7

File tree

5 files changed

+28
-3
lines changed

5 files changed

+28
-3
lines changed

Sources/Utility/Path.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,24 @@ public struct Path {
8686
if path.starts(with: pivot) {
8787
let relativePortion = path.dropFirst(pivot.count)
8888
return join(Array(relativePortion))
89+
} else if path.starts(with: pivot.prefix(1)) {
90+
//only the first matches, so we will be able to find a relative
91+
//path by adding jumps back the directory tree
92+
var newPath = ArraySlice(path)
93+
var newPivot = ArraySlice(pivot)
94+
repeat {
95+
//remove all shared components in the prefix
96+
newPath = newPath.dropFirst()
97+
newPivot = newPivot.dropFirst()
98+
} while newPath.prefix(1) == newPivot.prefix(1)
99+
100+
//as we found the first differing point, the final path is
101+
//a) as many ".." as there are components in newPivot
102+
//b) what's left in newPath
103+
var final = Array(repeating: "..", count: newPivot.count)
104+
final.append(contentsOf: newPath)
105+
let relativePath = Path.join(final)
106+
return relativePath
89107
} else {
90108
let prefix = abs.path ? "/" : ""
91109
return prefix + join(path)

Sources/Xcodeproj/generate().swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public func generate(path path: String, package: Package, modules: [SwiftModule]
2323

2424
////// the pbxproj file describes the project and its targets
2525
try open(rootdir, "project.pbxproj") { fwrite in
26-
pbxproj(package: package, modules: modules, products: products, printer: fwrite)
26+
pbxproj(projectPath: path, package: package, modules: modules, products: products, printer: fwrite)
2727
}
2828

2929
////// the scheme acts like an aggregate target for all our targets

Sources/Xcodeproj/pbxproj().swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
import PackageType
1616
import Utility
1717

18-
public func pbxproj(package package: Package, modules: [SwiftModule], products _: [Product], printer print: (String) -> Void) {
18+
public func pbxproj(projectPath projectPath: String, package: Package, modules: [SwiftModule], products _: [Product], printer print: (String) -> Void) {
1919

20-
let srcroot = package.path
20+
let srcroot = projectPath
2121
let nontests = modules.filter{ !($0 is TestModule) }
2222
let tests = modules.filter{ $0 is TestModule }
2323

Tests/Utility/FileTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ extension RelativePathTests {
131131
("testAbsolute", testAbsolute),
132132
("testRelative", testRelative),
133133
("testMixed", testMixed),
134+
("testRelativeCommonSubprefix", testRelativeCommonSubprefix)
134135
]
135136
}
136137
}

Tests/Utility/PathTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,10 @@ class RelativePathTests: XCTestCase {
210210
func testMixed() {
211211
XCTAssertEqual("3/4", Path(try! getcwd() + "/1/2/3/4").relative(to: "1/2"))
212212
}
213+
214+
func testRelativeCommonSubprefix() {
215+
XCTAssertEqual("../4", Path("/1/2/4").relative(to: "/1/2/3"))
216+
XCTAssertEqual("../4/5", Path("/1/2/4/5").relative(to: "/1/2/3"))
217+
XCTAssertEqual("../../../4/5", Path("/1/2/4/5").relative(to: "/1/2/3/6/7"))
218+
}
213219
}

0 commit comments

Comments
 (0)