Skip to content

Commit 96d8c16

Browse files
committed
Merge branch 'main' of https://github.com/swiftlang/swiftly into swift6_concurrency
2 parents 0b78eff + ea71330 commit 96d8c16

File tree

17 files changed

+990
-348
lines changed

17 files changed

+990
-348
lines changed

Package.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,28 @@ let package = Package(
5252
.target(
5353
name: "SwiftlyCore",
5454
dependencies: [
55+
"SwiftlyDownloadAPI",
56+
"SwiftlyWebsiteAPI",
5557
.product(name: "AsyncHTTPClient", package: "async-http-client"),
5658
.product(name: "NIOFoundationCompat", package: "swift-nio"),
5759
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
5860
.product(name: "OpenAPIAsyncHTTPClient", package: "swift-openapi-async-http-client"),
5961
],
62+
),
63+
.target(
64+
name: "SwiftlyDownloadAPI",
65+
dependencies: [
66+
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
67+
],
68+
plugins: [
69+
.plugin(name: "OpenAPIGenerator", package: "swift-openapi-generator"),
70+
]
71+
),
72+
.target(
73+
name: "SwiftlyWebsiteAPI",
74+
dependencies: [
75+
.product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"),
76+
],
6077
plugins: [
6178
.plugin(name: "OpenAPIGenerator", package: "swift-openapi-generator"),
6279
]

Sources/LinuxPlatform/Linux.swift

Lines changed: 106 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public struct Linux: Platform {
4242
"tar.gz"
4343
}
4444

45-
private static let skipVerificationMessage: String = "To skip signature verification, specify the --no-verify flag."
45+
private static let skipVerificationMessage: String =
46+
"To skip signature verification, specify the --no-verify flag."
4647

4748
public func verifySwiftlySystemPrerequisites() throws {
4849
// Check if the root CA certificates are installed on this system for NIOSSL to use.
@@ -67,10 +68,15 @@ public struct Linux: Platform {
6768
}
6869
}
6970

70-
public func verifySystemPrerequisitesForInstall(_ ctx: SwiftlyCoreContext, platformName: String, version _: ToolchainVersion, requireSignatureValidation: Bool) async throws -> String? {
71+
public func verifySystemPrerequisitesForInstall(
72+
_ ctx: SwiftlyCoreContext, platformName: String, version _: ToolchainVersion,
73+
requireSignatureValidation: Bool
74+
) async throws -> String? {
7175
// TODO: these are hard-coded until we have a place to query for these based on the toolchain version
7276
// These lists were copied from the dockerfile sources here: https://github.com/apple/swift-docker/tree/ea035798755cce4ec41e0c6dbdd320904cef0421/5.10
73-
let packages: [String] = switch platformName {
77+
let packages: [String] =
78+
switch platformName
79+
{
7480
case "ubuntu1804":
7581
[
7682
"libatomic1",
@@ -221,7 +227,9 @@ public struct Linux: Platform {
221227
[]
222228
}
223229

224-
let manager: String? = switch platformName {
230+
let manager: String? =
231+
switch platformName
232+
{
225233
case "ubuntu1804":
226234
"apt-get"
227235
case "ubuntu2004":
@@ -259,18 +267,19 @@ public struct Linux: Platform {
259267
}
260268

261269
let tmpFile = self.getTempFilePath()
262-
let _ = FileManager.default.createFile(atPath: tmpFile.path, contents: nil, attributes: [.posixPermissions: 0o600])
270+
let _ = FileManager.default.createFile(
271+
atPath: tmpFile.path, contents: nil, attributes: [.posixPermissions: 0o600]
272+
)
263273
defer {
264274
try? FileManager.default.removeItem(at: tmpFile)
265275
}
266276

267-
guard let url = URL(string: "https://www.swift.org/keys/all-keys.asc") else {
268-
throw SwiftlyError(message: "malformed URL to the swift gpg keys")
269-
}
270-
271-
try await ctx.httpClient.downloadFile(url: url, to: tmpFile)
277+
try await ctx.httpClient.getGpgKeys().download(to: tmpFile)
272278
if let mockedHomeDir = ctx.mockedHomeDir {
273-
try self.runProgram("gpg", "--import", tmpFile.path, quiet: true, env: ["GNUPGHOME": mockedHomeDir.appendingPathComponent(".gnupg").path])
279+
try self.runProgram(
280+
"gpg", "--import", tmpFile.path, quiet: true,
281+
env: ["GNUPGHOME": mockedHomeDir.appendingPathComponent(".gnupg").path]
282+
)
274283
} else {
275284
try self.runProgram("gpg", "--import", tmpFile.path, quiet: true)
276285
}
@@ -323,13 +332,17 @@ public struct Linux: Platform {
323332
}
324333
}
325334

326-
public func install(_ ctx: SwiftlyCoreContext, from tmpFile: URL, version: ToolchainVersion, verbose: Bool) async throws {
335+
public func install(
336+
_ ctx: SwiftlyCoreContext, from tmpFile: URL, version: ToolchainVersion, verbose: Bool
337+
) async throws {
327338
guard tmpFile.fileExists() else {
328339
throw SwiftlyError(message: "\(tmpFile) doesn't exist")
329340
}
330341

331342
if !self.swiftlyToolchainsDir(ctx).fileExists() {
332-
try FileManager.default.createDirectory(at: self.swiftlyToolchainsDir(ctx), withIntermediateDirectories: false)
343+
try FileManager.default.createDirectory(
344+
at: self.swiftlyToolchainsDir(ctx), withIntermediateDirectories: false
345+
)
333346
}
334347

335348
await ctx.print("Extracting toolchain...")
@@ -378,7 +391,9 @@ public struct Linux: Platform {
378391
try self.runProgram(tmpDir.appendingPathComponent("swiftly").path, "init")
379392
}
380393

381-
public func uninstall(_ ctx: SwiftlyCoreContext, _ toolchain: ToolchainVersion, verbose _: Bool) throws {
394+
public func uninstall(_ ctx: SwiftlyCoreContext, _ toolchain: ToolchainVersion, verbose _: Bool)
395+
throws
396+
{
382397
let toolchainDir = self.swiftlyToolchainsDir(ctx).appendingPathComponent(toolchain.name)
383398
try FileManager.default.removeItem(at: toolchainDir)
384399
}
@@ -393,7 +408,9 @@ public struct Linux: Platform {
393408
FileManager.default.temporaryDirectory.appendingPathComponent("swiftly-\(UUID())")
394409
}
395410

396-
public func verifySignature(_ ctx: SwiftlyCoreContext, archiveDownloadURL: URL, archive: URL, verbose: Bool) async throws {
411+
public func verifyToolchainSignature(
412+
_ ctx: SwiftlyCoreContext, toolchainFile: ToolchainFile, archive: URL, verbose: Bool
413+
) async throws {
397414
if verbose {
398415
await ctx.print("Downloading toolchain signature...")
399416
}
@@ -404,15 +421,15 @@ public struct Linux: Platform {
404421
try? FileManager.default.removeItem(at: sigFile)
405422
}
406423

407-
try await ctx.httpClient.downloadFile(
408-
url: archiveDownloadURL.appendingPathExtension("sig"),
409-
to: sigFile
410-
)
424+
try await ctx.httpClient.getSwiftToolchainFileSignature(toolchainFile).download(to: sigFile)
411425

412426
await ctx.print("Verifying toolchain signature...")
413427
do {
414428
if let mockedHomeDir = ctx.mockedHomeDir {
415-
try self.runProgram("gpg", "--verify", sigFile.path, archive.path, quiet: false, env: ["GNUPGHOME": mockedHomeDir.appendingPathComponent(".gnupg").path])
429+
try self.runProgram(
430+
"gpg", "--verify", sigFile.path, archive.path, quiet: false,
431+
env: ["GNUPGHOME": mockedHomeDir.appendingPathComponent(".gnupg").path]
432+
)
416433
} else {
417434
try self.runProgram("gpg", "--verify", sigFile.path, archive.path, quiet: !verbose)
418435
}
@@ -421,23 +438,65 @@ public struct Linux: Platform {
421438
}
422439
}
423440

424-
private func manualSelectPlatform(_ ctx: SwiftlyCoreContext, _ platformPretty: String?) async -> PlatformDefinition {
441+
public func verifySwiftlySignature(
442+
_ ctx: SwiftlyCoreContext, archiveDownloadURL: URL, archive: URL, verbose: Bool
443+
) async throws {
444+
if verbose {
445+
await ctx.print("Downloading swiftly signature...")
446+
}
447+
448+
let sigFile = self.getTempFilePath()
449+
let _ = FileManager.default.createFile(atPath: sigFile.path, contents: nil)
450+
defer {
451+
try? FileManager.default.removeItem(at: sigFile)
452+
}
453+
454+
try await ctx.httpClient.getSwiftlyReleaseSignature(
455+
url: archiveDownloadURL.appendingPathExtension("sig")
456+
).download(to: sigFile)
457+
458+
await ctx.print("Verifying swiftly signature...")
459+
do {
460+
if let mockedHomeDir = ctx.mockedHomeDir {
461+
try self.runProgram(
462+
"gpg", "--verify", sigFile.path, archive.path, quiet: false,
463+
env: ["GNUPGHOME": mockedHomeDir.appendingPathComponent(".gnupg").path]
464+
)
465+
} else {
466+
try self.runProgram("gpg", "--verify", sigFile.path, archive.path, quiet: !verbose)
467+
}
468+
} catch {
469+
throw SwiftlyError(message: "Signature verification failed: \(error).")
470+
}
471+
}
472+
473+
private func manualSelectPlatform(_ ctx: SwiftlyCoreContext, _ platformPretty: String?) async
474+
-> PlatformDefinition
475+
{
425476
if let platformPretty {
426-
print("\(platformPretty) is not an officially supported platform, but the toolchains for another platform may still work on it.")
477+
print(
478+
"\(platformPretty) is not an officially supported platform, but the toolchains for another platform may still work on it."
479+
)
427480
} else {
428-
print("This platform could not be detected, but a toolchain for one of the supported platforms may work on it.")
481+
print(
482+
"This platform could not be detected, but a toolchain for one of the supported platforms may work on it."
483+
)
429484
}
430485

431-
let selections = self.linuxPlatforms.enumerated().map { "\($0 + 1)) \($1.namePretty)" }.joined(separator: "\n")
486+
let selections = self.linuxPlatforms.enumerated().map { "\($0 + 1)) \($1.namePretty)" }.joined(
487+
separator: "\n")
432488

433-
print("""
434-
Please select the platform to use for toolchain downloads:
489+
print(
490+
"""
491+
Please select the platform to use for toolchain downloads:
435492
436-
0) Cancel
437-
\(selections)
438-
""")
493+
0) Cancel
494+
\(selections)
495+
""")
439496

440-
let choice = await ctx.readLine(prompt: "Pick one of the available selections [0-\(self.linuxPlatforms.count)] ") ?? "0"
497+
let choice =
498+
await ctx.readLine(prompt: "Pick one of the available selections [0-\(self.linuxPlatforms.count)] ")
499+
?? "0"
441500

442501
guard let choiceNum = Int(choice) else {
443502
fatalError("Installation canceled")
@@ -450,11 +509,15 @@ public struct Linux: Platform {
450509
return self.linuxPlatforms[choiceNum - 1]
451510
}
452511

453-
public func detectPlatform(_ ctx: SwiftlyCoreContext, disableConfirmation: Bool, platform: String?) async throws -> PlatformDefinition {
512+
public func detectPlatform(
513+
_ ctx: SwiftlyCoreContext, disableConfirmation: Bool, platform: String?
514+
) async throws -> PlatformDefinition {
454515
// We've been given a hint to use
455516
if let platform {
456517
guard let pd = linuxPlatforms.first(where: { $0.nameFull == platform }) else {
457-
fatalError("Unrecognized platform \(platform). Recognized values: \(self.linuxPlatforms.map(\.nameFull).joined(separator: ", ")).")
518+
fatalError(
519+
"Unrecognized platform \(platform). Recognized values: \(self.linuxPlatforms.map(\.nameFull).joined(separator: ", "))."
520+
)
458521
}
459522

460523
return pd
@@ -492,9 +555,13 @@ public struct Linux: Platform {
492555
} else if info.hasPrefix("ID_LIKE=") {
493556
idlike = String(info.dropFirst("ID_LIKE=".count)).replacingOccurrences(of: "\"", with: "")
494557
} else if info.hasPrefix("VERSION_ID=") {
495-
versionID = String(info.dropFirst("VERSION_ID=".count)).replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: ".", with: "")
558+
versionID = String(info.dropFirst("VERSION_ID=".count)).replacingOccurrences(
559+
of: "\"", with: ""
560+
).replacingOccurrences(of: ".", with: "")
496561
} else if info.hasPrefix("PRETTY_NAME=") {
497-
platformPretty = String(info.dropFirst("PRETTY_NAME=".count)).replacingOccurrences(of: "\"", with: "")
562+
platformPretty = String(info.dropFirst("PRETTY_NAME=".count)).replacingOccurrences(
563+
of: "\"", with: ""
564+
)
498565
}
499566
}
500567

@@ -532,7 +599,9 @@ public struct Linux: Platform {
532599
}
533600

534601
return .rhel9
535-
} else if let pd = [PlatformDefinition.ubuntu1804, .ubuntu2004, .ubuntu2204, .ubuntu2404, .debian12, .fedora39].first(where: { $0.name == id + versionID }) {
602+
} else if let pd = [
603+
PlatformDefinition.ubuntu1804, .ubuntu2004, .ubuntu2204, .ubuntu2404, .debian12, .fedora39,
604+
].first(where: { $0.name == id + versionID }) {
536605
return pd
537606
}
538607

@@ -562,7 +631,8 @@ public struct Linux: Platform {
562631
return "/bin/bash"
563632
}
564633

565-
public func findToolchainLocation(_ ctx: SwiftlyCoreContext, _ toolchain: ToolchainVersion) -> URL {
634+
public func findToolchainLocation(_ ctx: SwiftlyCoreContext, _ toolchain: ToolchainVersion) -> URL
635+
{
566636
self.swiftlyToolchainsDir(ctx).appendingPathComponent("\(toolchain.name)")
567637
}
568638

0 commit comments

Comments
 (0)