Skip to content

Commit 9947c62

Browse files
authored
Change the default install path for macOS pkgs (#259)
Correct productbuild issue when creating a pkg Set the default swiftly home and binary locations on macOS to ~/.swiftly
1 parent 400e6a9 commit 9947c62

File tree

7 files changed

+32
-45
lines changed

7 files changed

+32
-45
lines changed

Sources/LinuxPlatform/Linux.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ public struct Linux: Platform {
2020

2121
public init() {}
2222

23-
public var appDataDirectory: URL {
23+
public var defaultSwiftlyHomeDirectory: URL {
2424
if let dir = ProcessInfo.processInfo.environment["XDG_DATA_HOME"] {
25-
return URL(fileURLWithPath: dir)
25+
return URL(fileURLWithPath: dir).appendingPathComponent("swiftly", isDirectory: true)
2626
} else {
2727
return FileManager.default.homeDirectoryForCurrentUser
28-
.appendingPathComponent(".local/share", isDirectory: true)
28+
.appendingPathComponent(".local/share/swiftly", isDirectory: true)
2929
}
3030
}
3131

Sources/MacOSPlatform/MacOS.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ public struct SwiftPkgInfo: Codable {
1313
public struct MacOS: Platform {
1414
public init() {}
1515

16-
public var appDataDirectory: URL {
16+
public var defaultSwiftlyHomeDirectory: URL {
1717
FileManager.default.homeDirectoryForCurrentUser
18-
.appendingPathComponent("Library/Application Support", isDirectory: true)
18+
.appendingPathComponent(".swiftly", isDirectory: true)
1919
}
2020

2121
public var swiftlyBinDir: URL {
2222
SwiftlyCore.mockedHomeDir.map { $0.appendingPathComponent("bin", isDirectory: true) }
2323
?? ProcessInfo.processInfo.environment["SWIFTLY_BIN_DIR"].map { URL(fileURLWithPath: $0) }
2424
?? FileManager.default.homeDirectoryForCurrentUser
25-
.appendingPathComponent("Library/Application Support/swiftly/bin", isDirectory: true)
25+
.appendingPathComponent(".swiftly/bin", isDirectory: true)
2626
}
2727

2828
public var swiftlyToolchainsDir: URL {
@@ -99,7 +99,7 @@ public struct MacOS: Platform {
9999
} else {
100100
homeDir = SwiftlyCore.mockedHomeDir ?? FileManager.default.homeDirectoryForCurrentUser
101101

102-
let installDir = homeDir.appendingPathComponent("usr/local")
102+
let installDir = homeDir.appendingPathComponent(".swiftly")
103103
try FileManager.default.createDirectory(atPath: installDir.path, withIntermediateDirectories: true)
104104

105105
// In the case of a mock for testing purposes we won't use the installer, perferring a manual process because
@@ -114,10 +114,11 @@ public struct MacOS: Platform {
114114
throw SwiftlyError(message: "Payload file could not be found at \(tmpDir).")
115115
}
116116

117-
try runProgram("tar", "-C", installDir.path, "-xf", payload.path)
117+
SwiftlyCore.print("Extracting the swiftly package into \(installDir.path)...")
118+
try runProgram("tar", "-C", installDir.path, "-xvf", payload.path, quiet: false)
118119
}
119120

120-
try self.runProgram(homeDir.appendingPathComponent("usr/local/bin/swiftly").path, "init")
121+
try self.runProgram(homeDir.appendingPathComponent(".swiftly/bin/swiftly").path, "init")
121122
}
122123

123124
public func uninstall(_ toolchain: ToolchainVersion, verbose: Bool) throws {

Sources/Swiftly/Init.swift

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ internal struct Init: SwiftlyCommand {
8080
\(Swiftly.currentPlatform.swiftlyHomeDir.path) - Data and configuration files directory including toolchains
8181
\(Swiftly.currentPlatform.swiftlyBinDir.path) - Executables installation directory
8282
83-
These locations can be changed with SWIFTLY_HOME and SWIFTLY_BIN environment variables and run this again.
83+
These locations can be changed with SWIFTLY_HOME_DIR and SWIFTLY_BIN_DIR environment variables and run this again.
8484
\(installMsg)
8585
""")
8686

@@ -89,22 +89,6 @@ internal struct Init: SwiftlyCommand {
8989
}
9090
}
9191

92-
// Ensure swiftly doesn't overwrite any existing executables without getting confirmation first.
93-
let swiftlyBinDir = Swiftly.currentPlatform.swiftlyBinDir
94-
let swiftlyBinDirContents = (try? FileManager.default.contentsOfDirectory(atPath: swiftlyBinDir.path)) ?? [String]()
95-
let willBeOverwritten = Set(["swiftly"]).intersection(swiftlyBinDirContents)
96-
if !willBeOverwritten.isEmpty && !overwrite {
97-
SwiftlyCore.print("The following existing executables will be overwritten:")
98-
99-
for executable in willBeOverwritten {
100-
SwiftlyCore.print(" \(swiftlyBinDir.appendingPathComponent(executable).path)")
101-
}
102-
103-
guard SwiftlyCore.promptForConfirmation(defaultBehavior: false) else {
104-
throw SwiftlyError(message: "Swiftly installation has been cancelled")
105-
}
106-
}
107-
10892
let shell = if let s = ProcessInfo.processInfo.environment["SHELL"] {
10993
s
11094
} else {
@@ -239,14 +223,16 @@ internal struct Init: SwiftlyCommand {
239223
(postInstall, pathChanged) = try await Install.execute(version: latestVersion, &config, useInstalledToolchain: true, verifySignature: true, verbose: verbose, assumeYes: assumeYes)
240224
}
241225

242-
if addEnvToProfile && !quietShellFollowup {
226+
if addEnvToProfile {
243227
try Data(sourceLine.utf8).append(to: profileHome)
244228

245-
SwiftlyCore.print("""
246-
To begin using installed swiftly from your current shell, first run the following command:
247-
\(sourceLine)
229+
if !quietShellFollowup {
230+
SwiftlyCore.print("""
231+
To begin using installed swiftly from your current shell, first run the following command:
232+
\(sourceLine)
248233
249-
""")
234+
""")
235+
}
250236
}
251237

252238
// Fish doesn't have path caching, so this might only be needed for bash/zsh

Sources/SwiftlyCore/Platform.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ public struct RunProgramError: Swift.Error {
3939
}
4040

4141
public protocol Platform {
42-
/// The platform-specific location on disk where applications are
43-
/// supposed to store their custom data.
44-
var appDataDirectory: URL { get }
42+
/// The platform-specific defaut location on disk for swiftly's home
43+
/// directory.
44+
var defaultSwiftlyHomeDirectory: URL { get }
4545

4646
/// The directory which stores the swiftly executable itself as well as symlinks
4747
/// to executables in the "bin" directory of the active toolchain.
@@ -130,7 +130,7 @@ extension Platform {
130130
public var swiftlyHomeDir: URL {
131131
SwiftlyCore.mockedHomeDir
132132
?? ProcessInfo.processInfo.environment["SWIFTLY_HOME_DIR"].map { URL(fileURLWithPath: $0) }
133-
?? self.appDataDirectory.appendingPathComponent("swiftly", isDirectory: true)
133+
?? self.defaultSwiftlyHomeDirectory
134134
}
135135

136136
/// The URL of the configuration file in swiftly's home directory.

Tests/SwiftlyTests/SwiftlyTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ public class MockToolchainDownloader: HTTPRequestExecutor {
729729
#elseif os(macOS)
730730
public func makeMockedSwiftly(from _: URL) throws -> Data {
731731
let tmp = FileManager.default.temporaryDirectory.appendingPathComponent("swiftly-\(UUID())")
732-
let swiftlyDir = tmp.appendingPathComponent("swiftly", isDirectory: true)
732+
let swiftlyDir = tmp.appendingPathComponent(".swiftly", isDirectory: true)
733733
let swiftlyBinDir = swiftlyDir.appendingPathComponent("bin")
734734

735735
try FileManager.default.createDirectory(
@@ -766,7 +766,7 @@ public class MockToolchainDownloader: HTTPRequestExecutor {
766766
"--root",
767767
swiftlyDir.path,
768768
"--install-location",
769-
"usr/local",
769+
".swiftly",
770770
"--version",
771771
"\(self.latestSwiftlyVersion)",
772772
"--identifier",

Tests/SwiftlyTests/UninstallTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,10 @@ final class UninstallTests: SwiftlyTests {
301301
func testUninstallNotInstalled() async throws {
302302
let toolchains = Set([Self.oldStable, Self.newStable, Self.newMainSnapshot, Self.oldReleaseSnapshot])
303303
try await self.withMockedHome(homeName: Self.homeName, toolchains: toolchains, inUse: Self.newMainSnapshot) {
304-
var config = try await Config.load()
304+
var config = try Config.load()
305305
config.inUse = Self.newMainSnapshot
306306
config.installedToolchains.remove(Self.newMainSnapshot)
307-
try await config.save()
307+
try config.save()
308308

309309
var uninstall = try self.parseCommand(Uninstall.self, ["uninstall", "-y", Self.newMainSnapshot.name])
310310
_ = try await uninstall.run()

Tools/build-swiftly-release/BuildSwiftlyRelease.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,12 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
399399
try runProgram(strip, ".build/\(arch)-apple-macosx/release/swiftly")
400400
}
401401

402-
let swiftlyBinDir = FileManager.default.currentDirectoryPath + "/.build/release/usr/local/bin"
402+
let swiftlyBinDir = FileManager.default.currentDirectoryPath + "/.build/release/.swiftly/bin"
403403
try? FileManager.default.createDirectory(atPath: swiftlyBinDir, withIntermediateDirectories: true)
404404

405405
try runProgram(lipo, ".build/x86_64-apple-macosx/release/swiftly", ".build/arm64-apple-macosx/release/swiftly", "-create", "-o", "\(swiftlyBinDir)/swiftly")
406406

407-
let swiftlyLicenseDir = FileManager.default.currentDirectoryPath + "/.build/release/usr/local/share/doc/swiftly/license"
407+
let swiftlyLicenseDir = FileManager.default.currentDirectoryPath + "/.build/release/.swiftly/license"
408408
try? FileManager.default.createDirectory(atPath: swiftlyLicenseDir, withIntermediateDirectories: true)
409409
try await self.collectLicenses(swiftlyLicenseDir)
410410

@@ -418,7 +418,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
418418
"--root",
419419
swiftlyBinDir + "/..",
420420
"--install-location",
421-
"usr/local",
421+
".swiftly",
422422
"--version",
423423
self.version,
424424
"--identifier",
@@ -433,7 +433,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
433433
"--root",
434434
swiftlyBinDir + "/..",
435435
"--install-location",
436-
"usr/local",
436+
".swiftly",
437437
"--version",
438438
self.version,
439439
"--identifier",
@@ -455,9 +455,9 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
455455
try distFileContents.write(to: distFile, atomically: true, encoding: .utf8)
456456

457457
if let cert = cert {
458-
try runProgram("productbuild", "--distribution", distFile.path, "--package-path", pkgFile.path, "--sign", cert, pkgFileReconfigured.path)
458+
try runProgram("productbuild", "--distribution", distFile.path, "--package-path", pkgFile.deletingLastPathComponent().path, "--sign", cert, pkgFileReconfigured.path)
459459
} else {
460-
try runProgram("productbuild", "--distribution", distFile.path, "--package-path", pkgFile.path, pkgFileReconfigured.path)
460+
try runProgram("productbuild", "--distribution", distFile.path, "--package-path", pkgFile.deletingLastPathComponent().path, pkgFileReconfigured.path)
461461
}
462462
try FileManager.default.removeItem(at: pkgFile)
463463
try FileManager.default.copyItem(atPath: pkgFileReconfigured.path, toPath: pkgFile.path)

0 commit comments

Comments
 (0)