Skip to content

Commit df0e91c

Browse files
authored
Model lipo invocations with a modeled command structure and a test (#331)
* Add a computed property parent for getting the parent of a FilePath
1 parent b81c9cc commit df0e91c

File tree

5 files changed

+95
-10
lines changed

5 files changed

+95
-10
lines changed

Sources/SwiftlyCore/Commands.swift

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extension SystemCommand {
4848
self.read(path: path, keys: keys)
4949
}
5050

51-
public struct ReadCommand: Output {
51+
public struct ReadCommand {
5252
var dscl: DsclCommand
5353
var path: FilePath?
5454
var keys: [String]
@@ -76,7 +76,7 @@ extension SystemCommand {
7676
}
7777
}
7878

79-
extension SystemCommand.DsclCommand.ReadCommand {
79+
extension SystemCommand.DsclCommand.ReadCommand: Output {
8080
public func properties(_ p: Platform) async throws -> [(key: String, value: String)] {
8181
let output = try await self.output(p)
8282
guard let output else { return [] }
@@ -90,3 +90,63 @@ extension SystemCommand.DsclCommand.ReadCommand {
9090
return props
9191
}
9292
}
93+
94+
extension SystemCommand {
95+
public static func lipo(executable: Executable = LipoCommand.defaultExecutable, inputFiles: FilePath...) -> LipoCommand {
96+
Self.lipo(executable: executable, inputFiles: inputFiles)
97+
}
98+
99+
public static func lipo(executable: Executable = LipoCommand.defaultExecutable, inputFiles: [FilePath]) -> LipoCommand {
100+
LipoCommand(executable: executable, inputFiles: inputFiles)
101+
}
102+
103+
public struct LipoCommand {
104+
public static var defaultExecutable: Executable { .name("lipo") }
105+
106+
var executable: Executable
107+
var inputFiles: [FilePath]
108+
109+
public init(executable: Executable, inputFiles: [FilePath]) {
110+
self.executable = executable
111+
self.inputFiles = inputFiles
112+
}
113+
114+
func config() -> Configuration {
115+
var args: [String] = []
116+
117+
args += self.inputFiles.map(\.string)
118+
119+
return Configuration(
120+
executable: self.executable,
121+
arguments: Arguments(args),
122+
environment: .inherit
123+
)
124+
}
125+
126+
public func create(output: FilePath) -> CreateCommand {
127+
CreateCommand(self, output: output)
128+
}
129+
130+
public struct CreateCommand {
131+
var lipo: LipoCommand
132+
var output: FilePath
133+
134+
init(_ lipo: LipoCommand, output: FilePath) {
135+
self.lipo = lipo
136+
self.output = output
137+
}
138+
139+
public func config() -> Configuration {
140+
var c = self.lipo.config()
141+
142+
var args = c.arguments.storage.map(\.description) + ["-create", "-output", "\(self.output)"]
143+
144+
c.arguments = .init(args)
145+
146+
return c
147+
}
148+
}
149+
}
150+
}
151+
152+
extension SystemCommand.LipoCommand.CreateCommand: Runnable {}

Sources/SwiftlyCore/FileManager+FilePath.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,6 @@ extension FilePath {
199199
public static func / (left: FilePath, right: String) -> FilePath {
200200
left.appending(right)
201201
}
202+
203+
public var parent: FilePath { self.removingLastComponent() }
202204
}

Sources/SwiftlyCore/ModeledCommandLine.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public protocol Runnable {
126126
}
127127

128128
extension Runnable {
129-
public func run(_ p: Platform, quiet: Bool) async throws {
129+
public func run(_ p: Platform, quiet: Bool = false) async throws {
130130
let c = self.config()
131131
let executable = switch c.executable.storage {
132132
case let .executable(name):

Tests/SwiftlyTests/CommandLineTests.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,15 @@ public struct CommandLineTests {
2828
#expect(properties.count == 1) // Only one shell for the current user
2929
#expect(properties[0].key == "UserShell") // The one property key should be the one that is requested
3030
}
31+
32+
@Test func testLipo() {
33+
var config = sys.lipo(inputFiles: "swiftly1", "swiftly2").create(output: "swiftly-universal").config()
34+
35+
#expect(config.executable == .name("lipo"))
36+
#expect(config.arguments.storage.map(\.description) == ["swiftly1", "swiftly2", "-create", "-output", "swiftly-universal"])
37+
38+
config = sys.lipo(inputFiles: "swiftly").create(output: "swiftly-universal-with-one-arch").config()
39+
#expect(config.executable == .name("lipo"))
40+
#expect(config.arguments.storage.map(\.description) == ["swiftly", "-create", "-output", "swiftly-universal-with-one-arch"])
41+
}
3142
}

Tools/build-swiftly-release/BuildSwiftlyRelease.swift

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import ArgumentParser
22
import Foundation
33
import SwiftlyCore
4+
import SystemPackage
45

56
#if os(macOS)
67
import MacOSPlatform
@@ -14,6 +15,9 @@ let currentPlatform = MacOS()
1415
let currentPlatform = Linux()
1516
#endif
1617

18+
typealias fs = FileSystem
19+
typealias sys = SystemCommand
20+
1721
public struct SwiftPlatform: Codable {
1822
public var name: String?
1923
public var checksum: String?
@@ -392,7 +396,6 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
392396

393397
try await self.checkGitRepoStatus(git)
394398

395-
let lipo = try await self.assertTool("lipo", message: "In order to make a universal binary there needs to be the `lipo` tool that is installed on macOS.")
396399
let pkgbuild = try await self.assertTool("pkgbuild", message: "In order to make pkg installers there needs to be the `pkgbuild` tool that is installed on macOS.")
397400
let strip = try await self.assertTool("strip", message: "In order to strip binaries there needs to be the `strip` tool that is installed on macOS.")
398401

@@ -405,10 +408,14 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
405408
try runProgram(strip, ".build/\(arch)-apple-macosx/release/swiftly")
406409
}
407410

408-
let swiftlyBinDir = FileManager.default.currentDirectoryPath + "/.build/release/.swiftly/bin"
409-
try? FileManager.default.createDirectory(atPath: swiftlyBinDir, withIntermediateDirectories: true)
411+
let swiftlyBinDir = fs.cwd / ".build/release/.swiftly/bin"
412+
try? await fs.mkdir(.parents, atPath: swiftlyBinDir)
410413

411-
try runProgram(lipo, ".build/x86_64-apple-macosx/release/swiftly", ".build/arm64-apple-macosx/release/swiftly", "-create", "-o", "\(swiftlyBinDir)/swiftly")
414+
try await sys.lipo(
415+
inputFiles: ".build/x86_64-apple-macosx/release/swiftly", ".build/arm64-apple-macosx/release/swiftly"
416+
)
417+
.create(output: swiftlyBinDir / "swiftly")
418+
.run(currentPlatform)
412419

413420
let swiftlyLicenseDir = FileManager.default.currentDirectoryPath + "/.build/release/.swiftly/license"
414421
try? FileManager.default.createDirectory(atPath: swiftlyLicenseDir, withIntermediateDirectories: true)
@@ -423,7 +430,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
423430
try runProgram(
424431
pkgbuild,
425432
"--root",
426-
swiftlyBinDir + "/..",
433+
"\(swiftlyBinDir.parent)",
427434
"--install-location",
428435
".swiftly",
429436
"--version",
@@ -438,7 +445,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
438445
try runProgram(
439446
pkgbuild,
440447
"--root",
441-
swiftlyBinDir + "/..",
448+
"\(swiftlyBinDir.parent)",
442449
"--install-location",
443450
".swiftly",
444451
"--version",
@@ -479,7 +486,12 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
479486

480487
let testArchive = releaseDir.appendingPathComponent("test-swiftly-macos.tar.gz")
481488

482-
try runProgram(lipo, ".build/x86_64-apple-macosx/debug/test-swiftly", ".build/arm64-apple-macosx/debug/test-swiftly", "-create", "-o", "\(swiftlyBinDir)/swiftly")
489+
try await sys.lipo(
490+
inputFiles: ".build/x86_64-apple-macosx/debug/test-swiftly", ".build/arm64-apple-macosx/debug/test-swiftly"
491+
)
492+
.create(output: swiftlyBinDir / "swiftly")
493+
.run(currentPlatform)
494+
483495
try runProgram(tar, "--directory=.build/x86_64-apple-macosx/debug", "-czf", testArchive.path, "test-swiftly")
484496

485497
print(testArchive.path)

0 commit comments

Comments
 (0)