Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions Sources/SwiftlyCore/Commands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension SystemCommand {
self.read(path: path, keys: keys)
}

public struct ReadCommand: Output {
public struct ReadCommand {
var dscl: DsclCommand
var path: FilePath?
var keys: [String]
Expand Down Expand Up @@ -76,7 +76,7 @@ extension SystemCommand {
}
}

extension SystemCommand.DsclCommand.ReadCommand {
extension SystemCommand.DsclCommand.ReadCommand: Output {
public func properties(_ p: Platform) async throws -> [(key: String, value: String)] {
let output = try await self.output(p)
guard let output else { return [] }
Expand All @@ -90,3 +90,63 @@ extension SystemCommand.DsclCommand.ReadCommand {
return props
}
}

extension SystemCommand {
public static func lipo(executable: Executable = LipoCommand.defaultExecutable, inputFiles: FilePath...) -> LipoCommand {
Self.lipo(executable: executable, inputFiles: inputFiles)
}

public static func lipo(executable: Executable = LipoCommand.defaultExecutable, inputFiles: [FilePath]) -> LipoCommand {
LipoCommand(executable: executable, inputFiles: inputFiles)
}

public struct LipoCommand {
public static var defaultExecutable: Executable { .name("lipo") }

var executable: Executable
var inputFiles: [FilePath]

public init(executable: Executable, inputFiles: [FilePath]) {
self.executable = executable
self.inputFiles = inputFiles
}

func config() -> Configuration {
var args: [String] = []

args += self.inputFiles.map(\.string)

return Configuration(
executable: self.executable,
arguments: Arguments(args),
environment: .inherit
)
}

public func create(output: FilePath) -> CreateCommand {
CreateCommand(self, output: output)
}

public struct CreateCommand {
var lipo: LipoCommand
var output: FilePath

init(_ lipo: LipoCommand, output: FilePath) {
self.lipo = lipo
self.output = output
}

public func config() -> Configuration {
var c = self.lipo.config()

var args = c.arguments.storage.map(\.description) + ["-create", "-output", "\(self.output)"]

c.arguments = .init(args)

return c
}
}
}
}

extension SystemCommand.LipoCommand.CreateCommand: Runnable {}
2 changes: 2 additions & 0 deletions Sources/SwiftlyCore/FileManager+FilePath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,6 @@ extension FilePath {
public static func / (left: FilePath, right: String) -> FilePath {
left.appending(right)
}

public var parent: FilePath { self.removingLastComponent() }
}
2 changes: 1 addition & 1 deletion Sources/SwiftlyCore/ModeledCommandLine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public protocol Runnable {
}

extension Runnable {
public func run(_ p: Platform, quiet: Bool) async throws {
public func run(_ p: Platform, quiet: Bool = false) async throws {
let c = self.config()
let executable = switch c.executable.storage {
case let .executable(name):
Expand Down
11 changes: 11 additions & 0 deletions Tests/SwiftlyTests/CommandLineTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,15 @@ public struct CommandLineTests {
#expect(properties.count == 1) // Only one shell for the current user
#expect(properties[0].key == "UserShell") // The one property key should be the one that is requested
}

@Test func testLipo() {
var config = sys.lipo(inputFiles: "swiftly1", "swiftly2").create(output: "swiftly-universal").config()

#expect(config.executable == .name("lipo"))
#expect(config.arguments.storage.map(\.description) == ["swiftly1", "swiftly2", "-create", "-output", "swiftly-universal"])

config = sys.lipo(inputFiles: "swiftly").create(output: "swiftly-universal-with-one-arch").config()
#expect(config.executable == .name("lipo"))
#expect(config.arguments.storage.map(\.description) == ["swiftly", "-create", "-output", "swiftly-universal-with-one-arch"])
}
}
26 changes: 19 additions & 7 deletions Tools/build-swiftly-release/BuildSwiftlyRelease.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ArgumentParser
import Foundation
import SwiftlyCore
import SystemPackage

#if os(macOS)
import MacOSPlatform
Expand All @@ -14,6 +15,9 @@ let currentPlatform = MacOS()
let currentPlatform = Linux()
#endif

typealias fs = FileSystem
typealias sys = SystemCommand

public struct SwiftPlatform: Codable {
public var name: String?
public var checksum: String?
Expand Down Expand Up @@ -392,7 +396,6 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {

try await self.checkGitRepoStatus(git)

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.")
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.")
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.")

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

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

try runProgram(lipo, ".build/x86_64-apple-macosx/release/swiftly", ".build/arm64-apple-macosx/release/swiftly", "-create", "-o", "\(swiftlyBinDir)/swiftly")
try await sys.lipo(
inputFiles: ".build/x86_64-apple-macosx/release/swiftly", ".build/arm64-apple-macosx/release/swiftly"
)
.create(output: swiftlyBinDir / "swiftly")
.run(currentPlatform)

let swiftlyLicenseDir = FileManager.default.currentDirectoryPath + "/.build/release/.swiftly/license"
try? FileManager.default.createDirectory(atPath: swiftlyLicenseDir, withIntermediateDirectories: true)
Expand All @@ -423,7 +430,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
try runProgram(
pkgbuild,
"--root",
swiftlyBinDir + "/..",
"\(swiftlyBinDir.parent)",
"--install-location",
".swiftly",
"--version",
Expand All @@ -438,7 +445,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
try runProgram(
pkgbuild,
"--root",
swiftlyBinDir + "/..",
"\(swiftlyBinDir.parent)",
"--install-location",
".swiftly",
"--version",
Expand Down Expand Up @@ -479,7 +486,12 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {

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

try runProgram(lipo, ".build/x86_64-apple-macosx/debug/test-swiftly", ".build/arm64-apple-macosx/debug/test-swiftly", "-create", "-o", "\(swiftlyBinDir)/swiftly")
try await sys.lipo(
inputFiles: ".build/x86_64-apple-macosx/debug/test-swiftly", ".build/arm64-apple-macosx/debug/test-swiftly"
)
.create(output: swiftlyBinDir / "swiftly")
.run(currentPlatform)

try runProgram(tar, "--directory=.build/x86_64-apple-macosx/debug", "-czf", testArchive.path, "test-swiftly")

print(testArchive.path)
Expand Down