Skip to content

Commit 74dfa77

Browse files
authored
Build swiftly release cleanup (#335)
Remove the copies of bits of SwiftlyCore functionality in the build-swiftly-release script: runProgramEnv|Output SwiftlyRelease/SwiftlyPlatform (for JSON decoding from the REST endpoint) curl Remove the curl dependency from the release script using the AsyncHTTPClient instead to download libarchive. Migrate the release script from URLs and FileManager to the new FilePath and FileSystem component for improved readability, and type safety.
1 parent 0cae2fe commit 74dfa77

File tree

5 files changed

+155
-190
lines changed

5 files changed

+155
-190
lines changed

Sources/SwiftlyCore/Commands.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ extension SystemCommand {
922922
case arch(String)
923923
case configuration(String)
924924
case packagePath(FilePath)
925-
case pkgConfigPath(String)
925+
case pkgConfigPath(FilePath)
926926
case product(String)
927927
case swiftSdk(String)
928928
case staticSwiftStdlib

Sources/SwiftlyCore/ModeledCommandLine.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ public struct Configuration: Sendable {
1515
public var arguments: Arguments
1616
/// The environment to use when running the executable.
1717
public var environment: Environment
18+
19+
public init(executable: Executable, arguments: Arguments, environment: Environment) {
20+
self.executable = executable
21+
self.arguments = arguments
22+
self.environment = environment
23+
}
1824
}
1925

2026
public struct Executable: Sendable, Hashable {

Sources/SwiftlyWebsiteAPI/openapi.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ components:
284284
items:
285285
$ref: '#/components/schemas/Architecture'
286286
description: List of supported architectures.
287+
checksum:
288+
type: string
289+
description: SHA-256 Checksum of the static SDK, if this platform is the static SDK.
287290
required:
288291
- name
289292
- platform

Sources/TestSwiftly/TestSwiftly.swift

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,60 @@ let currentPlatform: Platform = MacOS.currentPlatform
1717
#error("Unsupported platform")
1818
#endif
1919

20+
typealias sys = SwiftlyCore.SystemCommand
2021
typealias fs = SwiftlyCore.FileSystem
2122

23+
func sh(executable: Executable = ShCommand.defaultExecutable, _ options: ShCommand.Option...) -> ShCommand {
24+
sh(executable: executable, options)
25+
}
26+
27+
func sh(executable: Executable = ShCommand.defaultExecutable, _ options: [ShCommand.Option]) -> ShCommand {
28+
ShCommand(executable: executable, options)
29+
}
30+
31+
struct ShCommand {
32+
static var defaultExecutable: Executable { .name("sh") }
33+
34+
var executable: Executable
35+
36+
var options: [Option]
37+
38+
enum Option {
39+
case login
40+
case command(String)
41+
42+
func args() -> [String] {
43+
switch self {
44+
case .login:
45+
["-l"]
46+
case let .command(command):
47+
["-c", command]
48+
}
49+
}
50+
}
51+
52+
init(executable: Executable, _ options: [Option]) {
53+
self.executable = executable
54+
self.options = options
55+
}
56+
57+
func config() -> Configuration {
58+
var args: [String] = []
59+
60+
for opt in self.options {
61+
args.append(contentsOf: opt.args())
62+
}
63+
64+
return Configuration(
65+
executable: self.executable,
66+
arguments: Arguments(args),
67+
environment: .inherit
68+
)
69+
}
70+
}
71+
72+
extension ShCommand: Runnable {}
73+
2274
@main
2375
struct TestSwiftly: AsyncParsableCommand {
2476
@Flag(name: [.customShort("y"), .long], help: "Disable confirmation prompts by assuming 'yes'")
@@ -40,11 +92,13 @@ struct TestSwiftly: AsyncParsableCommand {
4092
Foundation.exit(2)
4193
}
4294

95+
guard case let swiftlyArchive = FilePath(swiftlyArchive) else { fatalError("") }
96+
4397
print("Extracting swiftly release")
4498
#if os(Linux)
45-
try currentPlatform.runProgram("tar", "-zxvf", swiftlyArchive, quiet: false)
99+
try await sys.tar().extract(.verbose, .compressed, .archive(swiftlyArchive)).run(currentPlatform, quiet: false)
46100
#elseif os(macOS)
47-
try currentPlatform.runProgram("installer", "-pkg", swiftlyArchive, "-target", "CurrentUserHomeDirectory", quiet: false)
101+
try await sys.installer(.verbose, pkg: swiftlyArchive, target: "CurrentUserHomeDirectory").run(currentPlatform, quiet: false)
48102
#endif
49103

50104
#if os(Linux)
@@ -54,7 +108,7 @@ struct TestSwiftly: AsyncParsableCommand {
54108
#endif
55109

56110
var env = ProcessInfo.processInfo.environment
57-
let shell = try await currentPlatform.getShell()
111+
let shell = FilePath(try await currentPlatform.getShell())
58112
var customLoc: FilePath?
59113

60114
if self.customLocation {
@@ -66,37 +120,39 @@ struct TestSwiftly: AsyncParsableCommand {
66120
env["SWIFTLY_TOOLCHAINS_DIR"] = (customLoc! / "toolchains").string
67121

68122
try currentPlatform.runProgram(extractedSwiftly.string, "init", "--assume-yes", "--no-modify-profile", "--skip-install", quiet: false, env: env)
69-
try currentPlatform.runProgram(shell, "-l", "-c", ". \"\(customLoc! / "env.sh")\" && swiftly install --assume-yes latest --post-install-file=./post-install.sh", quiet: false, env: env)
123+
try await sh(executable: .path(shell), .login, .command(". \"\(customLoc! / "env.sh")\" && swiftly install --assume-yes latest --post-install-file=./post-install.sh")).run(currentPlatform, env: env, quiet: false)
70124
} else {
71125
print("Installing swiftly to the default location.")
72126
// Setting this environment helps to ensure that the profile gets sourced with bash, even if it is not in an interactive shell
73-
if shell.hasSuffix("bash") {
127+
if shell.ends(with: "bash") {
74128
env["BASH_ENV"] = (fs.home / ".profile").string
75-
} else if shell.hasSuffix("zsh") {
129+
} else if shell.ends(with: "zsh") {
76130
env["ZDOTDIR"] = fs.home.string
77-
} else if shell.hasSuffix("fish") {
131+
} else if shell.ends(with: "fish") {
78132
env["XDG_CONFIG_HOME"] = (fs.home / ".config").string
79133
}
80134

81135
try currentPlatform.runProgram(extractedSwiftly.string, "init", "--assume-yes", "--skip-install", quiet: false, env: env)
82-
try currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", quiet: false, env: env)
136+
try await sh(executable: .path(shell), .login, .command("swiftly install --assume-yes latest --post-install-file=./post-install.sh")).run(currentPlatform, env: env, quiet: false)
83137
}
84138

85139
var swiftReady = false
86140

87-
if NSUserName() == "root" && FileManager.default.fileExists(atPath: "./post-install.sh") {
88-
try currentPlatform.runProgram(shell, "./post-install.sh", quiet: false)
141+
if NSUserName() == "root" {
142+
if try await fs.exists(atPath: "./post-install.sh") {
143+
try currentPlatform.runProgram(shell.string, "./post-install.sh", quiet: false)
144+
}
89145
swiftReady = true
90-
} else if FileManager.default.fileExists(atPath: "./post-install.sh") {
146+
} else if try await fs.exists(atPath: "./post-install.sh") {
91147
print("WARNING: not running as root, so skipping the post installation steps and final swift verification.")
92148
} else {
93149
swiftReady = true
94150
}
95151

96152
if let customLoc = customLoc, swiftReady {
97-
try currentPlatform.runProgram(shell, "-l", "-c", ". \"\(customLoc / "env.sh")\" && swift --version", quiet: false, env: env)
153+
try await sh(executable: .path(shell), .login, .command(". \"\(customLoc / "env.sh")\" && swift --version")).run(currentPlatform, env: env, quiet: false)
98154
} else if swiftReady {
99-
try currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false, env: env)
155+
try await sh(executable: .path(shell), .login, .command("swift --version")).run(currentPlatform, env: env, quiet: false)
100156
}
101157
}
102158
}

0 commit comments

Comments
 (0)