Skip to content

Commit 5dec1f9

Browse files
committed
cleaned up boilerplate code for calling Subprocess.run
1 parent 636d64f commit 5dec1f9

4 files changed

Lines changed: 72 additions & 64 deletions

File tree

CLAUDE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,24 @@ Two implementations exist:
1313
## Building and Running
1414

1515
```bash
16-
# Build and run
16+
# Build and run (use Numbers.app for testing)
1717
swift build
18-
.build/debug/quickpkg /Applications/SomeApp.app
18+
.build/debug/quickpkg /Applications/Numbers.app
1919

2020
# Release build
2121
swift build -c release
2222

2323
# Test with verbosity (-v, -vv, or -vvv)
24-
.build/debug/quickpkg -vvv /Applications/SomeApp.app
24+
.build/debug/quickpkg -vvv /Applications/Numbers.app
2525

2626
# Test scripts option
27-
.build/debug/quickpkg /Applications/SomeApp.app --scripts testscripts/
27+
.build/debug/quickpkg /Applications/Numbers.app --scripts testscripts/
2828

2929
# Build distribution package (default)
30-
.build/debug/quickpkg /Applications/SomeApp.app
30+
.build/debug/quickpkg /Applications/Numbers.app
3131

3232
# Build component package
33-
.build/debug/quickpkg /Applications/SomeApp.app --component
33+
.build/debug/quickpkg /Applications/Numbers.app --component
3434
```
3535

3636
## Architecture

Sources/quickpkg/ArchiveExtractor.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ struct ArchiveExtractor: Sendable {
1414
func extractZip(_ archivePath: URL, to destinationDir: URL) async throws {
1515
logger.log("Extracting zip: \(archivePath.path) to \(destinationDir.path)", level: 1)
1616

17-
let arguments = ["/usr/bin/unzip", "-q", archivePath.path, "-d", destinationDir.path]
18-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
17+
let command: FilePath = "/usr/bin/unzip"
18+
let arguments: Arguments = ["-q", archivePath.path, "-d", destinationDir.path]
19+
logger.log("Executing: \(command) \(arguments)", level: 3)
1920

2021
let result = try await Subprocess.run(
21-
.path(FilePath(arguments[0])),
22-
arguments: Arguments(Array(arguments.dropFirst())),
22+
.path(command),
23+
arguments: arguments,
2324
output: .string(limit: .max),
2425
error: .string(limit: .max)
2526
)
@@ -33,13 +34,14 @@ struct ArchiveExtractor: Sendable {
3334
func extractXip(_ archivePath: URL, to destinationDir: URL) async throws {
3435
logger.log("Extracting xip: \(archivePath.path) to \(destinationDir.path)", level: 1)
3536

36-
let arguments = ["/usr/bin/xip", "--expand", archivePath.path]
37-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
37+
let command: FilePath = "/usr/bin/xip"
38+
let arguments: Arguments = ["--expand", archivePath.path]
39+
logger.log("Executing: \(command) \(arguments)", level: 3)
3840

3941
// xip --expand extracts to the current directory, so we need to run it from the destination
4042
let result = try await Subprocess.run(
41-
.path(FilePath(arguments[0])),
42-
arguments: Arguments(Array(arguments.dropFirst())),
43+
.path(command),
44+
arguments: arguments,
4345
workingDirectory: FilePath(destinationDir.path),
4446
output: .string(limit: .max),
4547
error: .string(limit: .max)

Sources/quickpkg/DMGManager.swift

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ actor DMGManager {
1818

1919
/// Check if a DMG has a Software License Agreement
2020
func hasSLA(at path: URL) async throws -> Bool {
21-
let arguments = ["/usr/bin/hdiutil", "imageinfo", path.path, "-plist"]
22-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
21+
let command: FilePath = "/usr/bin/hdiutil"
22+
let arguments: Arguments = ["imageinfo", path.path, "-plist"]
23+
logger.log("Executing: \(command) \(arguments)", level: 3)
2324

2425
let result = try await Subprocess.run(
25-
.path(FilePath(arguments[0])),
26-
arguments: Arguments(Array(arguments.dropFirst())),
26+
.path(command),
27+
arguments: arguments,
2728
output: .string(limit: .max),
2829
error: .string(limit: .max)
2930
)
@@ -42,12 +43,13 @@ actor DMGManager {
4243

4344
/// Check if DMG is already mounted and return mount points
4445
func existingMountPoints(for dmgPath: URL) async throws -> [URL]? {
45-
let arguments = ["/usr/bin/hdiutil", "info", "-plist"]
46-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
46+
let command: FilePath = "/usr/bin/hdiutil"
47+
let arguments: Arguments = ["info", "-plist"]
48+
logger.log("Executing: \(command) \(arguments)", level: 3)
4749

4850
let result = try await Subprocess.run(
49-
.path(FilePath(arguments[0])),
50-
arguments: Arguments(Array(arguments.dropFirst())),
51+
.path(command),
52+
arguments: arguments,
5153
output: .string(limit: .max),
5254
error: .string(limit: .max)
5355
)
@@ -108,25 +110,25 @@ actor DMGManager {
108110
}
109111

110112
// Mount the DMG
111-
let arguments = [
112-
"/usr/bin/hdiutil",
113+
let command: FilePath = "/usr/bin/hdiutil"
114+
let arguments: Arguments = [
113115
"attach",
114116
dmgPath.path,
115117
"-mountrandom", "/private/tmp",
116118
"-plist",
117119
"-nobrowse"
118120
]
119121

120-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
122+
logger.log("Executing: \(command) \(arguments)", level: 3)
121123

122124
let terminationStatus: TerminationStatus
123125
let standardOutput: String?
124126
let standardError: String?
125127

126128
if sla {
127129
let result = try await Subprocess.run(
128-
.path(FilePath(arguments[0])),
129-
arguments: Arguments(Array(arguments.dropFirst())),
130+
.path(command),
131+
arguments: arguments,
130132
input: .string("Y\n"),
131133
output: .string(limit: .max),
132134
error: .string(limit: .max)
@@ -136,8 +138,8 @@ actor DMGManager {
136138
standardError = result.standardError
137139
} else {
138140
let result = try await Subprocess.run(
139-
.path(FilePath(arguments[0])),
140-
arguments: Arguments(Array(arguments.dropFirst())),
141+
.path(command),
142+
arguments: arguments,
141143
output: .string(limit: .max),
142144
error: .string(limit: .max)
143145
)
@@ -184,12 +186,13 @@ actor DMGManager {
184186

185187
guard mountPoint.fileExists else { return }
186188

187-
let arguments = ["/usr/bin/hdiutil", "detach", mountPoint.path]
188-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
189+
let command: FilePath = "/usr/bin/hdiutil"
190+
let arguments: Arguments = ["detach", mountPoint.path]
191+
logger.log("Executing: \(command) \(arguments)", level: 3)
189192

190193
let result = try await Subprocess.run(
191-
.path(FilePath(arguments[0])),
192-
arguments: Arguments(Array(arguments.dropFirst())),
194+
.path(command),
195+
arguments: arguments,
193196
output: .string(limit: .max),
194197
error: .string(limit: .max)
195198
)

Sources/quickpkg/PackageBuilder.swift

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ struct PackageBuilder: Sendable {
1818
installLocation: String,
1919
outputPlist: URL
2020
) async throws {
21-
let arguments = [
22-
"/usr/bin/pkgbuild",
21+
let command: FilePath = "/usr/bin/pkgbuild"
22+
let arguments: Arguments = [
2323
"--analyze",
2424
"--root", payloadDir.path,
2525
"--identifier", identifier,
@@ -28,11 +28,11 @@ struct PackageBuilder: Sendable {
2828
outputPlist.path
2929
]
3030

31-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
31+
logger.log("Executing: \(command) \(arguments)", level: 3)
3232

3333
let result = try await Subprocess.run(
34-
.path(FilePath(arguments[0])),
35-
arguments: Arguments(Array(arguments.dropFirst())),
34+
.path(command),
35+
arguments: arguments,
3636
output: .string(limit: .max),
3737
error: .string(limit: .max)
3838
)
@@ -78,11 +78,12 @@ struct PackageBuilder: Sendable {
7878

7979
// Remove quarantine extended attributes from payload
8080
logger.log("Removing quarantine attributes from payload", level: 1)
81-
let xattrArgs = ["/usr/bin/xattr", "-dr", "com.apple.quarantine", payloadDir.path]
82-
logger.log("Executing: \(xattrArgs.joined(separator: " "))", level: 3)
81+
let xattrCommand: FilePath = "/usr/bin/xattr"
82+
let xattrArgs: Arguments = ["-dr", "com.apple.quarantine", payloadDir.path]
83+
logger.log("Executing: \(xattrCommand) \(xattrArgs)", level: 3)
8384
_ = try await Subprocess.run(
84-
.path(FilePath(xattrArgs[0])),
85-
arguments: Arguments(Array(xattrArgs.dropFirst())),
85+
.path(xattrCommand),
86+
arguments: xattrArgs,
8687
output: .discarded,
8788
error: .discarded
8889
)
@@ -96,8 +97,8 @@ struct PackageBuilder: Sendable {
9697
}
9798

9899
// Build the pkgbuild command
99-
var arguments = [
100-
"/usr/bin/pkgbuild",
100+
let pkgbuildCommand: FilePath = "/usr/bin/pkgbuild"
101+
var pkgbuildArgs: [String] = [
101102
"--root", payloadDir.path,
102103
"--component-plist", componentPlist.path,
103104
"--identifier", identifier,
@@ -106,44 +107,45 @@ struct PackageBuilder: Sendable {
106107
]
107108

108109
if let scriptsDir = scripts {
109-
arguments += ["--scripts", scriptsDir.path]
110+
pkgbuildArgs += ["--scripts", scriptsDir.path]
110111
logger.log("Scripts path: \(scriptsDir.path)", level: 1)
111112
}
112113

113114
if let ownership = ownership {
114-
arguments += ["--ownership", ownership.rawValue]
115+
pkgbuildArgs += ["--ownership", ownership.rawValue]
115116
}
116117

117-
arguments += ["--compression", compression.rawValue]
118+
pkgbuildArgs += ["--compression", compression.rawValue]
118119

119120
if let minOSVersion = minOSVersion {
120-
arguments += ["--min-os-version", minOSVersion]
121+
pkgbuildArgs += ["--min-os-version", minOSVersion]
121122
logger.log("Minimum OS version: \(minOSVersion)", level: 1)
122123
}
123124

124125
// Only sign with pkgbuild for component packages
125126
if packageType == .component {
126127
if let sign = sign {
127-
arguments += ["--sign", sign]
128+
pkgbuildArgs += ["--sign", sign]
128129
}
129130

130131
if let keychain = keychain {
131-
arguments += ["--keychain", keychain]
132+
pkgbuildArgs += ["--keychain", keychain]
132133
}
133134

134135
if let cert = cert {
135-
arguments += ["--cert", cert]
136+
pkgbuildArgs += ["--cert", cert]
136137
}
137138
}
138139

139-
arguments.append(pkgbuildOutput)
140+
pkgbuildArgs.append(pkgbuildOutput)
140141

141142
logger.log("Building component package: \(pkgbuildOutput)", level: 1)
142-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
143+
let arguments = Arguments(pkgbuildArgs)
144+
logger.log("Executing: \(pkgbuildCommand) \(arguments)", level: 3)
143145

144146
let result = try await Subprocess.run(
145-
.path(FilePath(arguments[0])),
146-
arguments: Arguments(Array(arguments.dropFirst())),
147+
.path(pkgbuildCommand),
148+
arguments: arguments,
147149
output: .string(limit: .max),
148150
error: .string(limit: .max)
149151
)
@@ -176,33 +178,34 @@ struct PackageBuilder: Sendable {
176178
keychain: String?,
177179
cert: String?
178180
) async throws {
179-
var arguments = [
180-
"/usr/bin/productbuild",
181+
let command: FilePath = "/usr/bin/productbuild"
182+
var productbuildArgs: [String] = [
181183
"--package", componentPackage,
182184
"--identifier", identifier,
183185
"--version", version
184186
]
185187

186188
if let sign = sign {
187-
arguments += ["--sign", sign]
189+
productbuildArgs += ["--sign", sign]
188190
}
189191

190192
if let keychain = keychain {
191-
arguments += ["--keychain", keychain]
193+
productbuildArgs += ["--keychain", keychain]
192194
}
193195

194196
if let cert = cert {
195-
arguments += ["--cert", cert]
197+
productbuildArgs += ["--cert", cert]
196198
}
197199

198-
arguments.append(outputPath)
200+
productbuildArgs.append(outputPath)
199201

200202
logger.log("Building distribution package: \(outputPath)", level: 1)
201-
logger.log("Executing: \(arguments.joined(separator: " "))", level: 3)
203+
let arguments = Arguments(productbuildArgs)
204+
logger.log("Executing: \(command) \(arguments)", level: 3)
202205

203206
let result = try await Subprocess.run(
204-
.path(FilePath(arguments[0])),
205-
arguments: Arguments(Array(arguments.dropFirst())),
207+
.path(command),
208+
arguments: arguments,
206209
output: .string(limit: .max),
207210
error: .string(limit: .max)
208211
)

0 commit comments

Comments
 (0)