Skip to content

Commit 61b359f

Browse files
Merge pull request #3849 from SwiftPackageIndex/processing-env-variable
Inject SPI_PROCESSING env variable
2 parents 051dd6d + b82ab2d commit 61b359f

11 files changed

+75
-59
lines changed

Sources/App/Core/Dependencies/ShellClient.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ import ShellOut
1919

2020
@DependencyClient
2121
struct ShellClient {
22-
var run: @Sendable (ShellOutCommand, String) async throws -> String
22+
var run: @Sendable (ShellOutCommand, String, [String: String]?) async throws -> String
2323
}
2424

2525

2626
extension ShellClient {
2727
@discardableResult
28-
func run(command: ShellOutCommand, at path: String) async throws -> String {
29-
try await run(command, path)
28+
func run(command: ShellOutCommand, at path: String, environment: [String: String]? = nil) async throws -> String {
29+
try await run(command, path, environment)
3030
}
3131
}
3232

@@ -39,10 +39,15 @@ extension String {
3939
extension ShellClient: DependencyKey {
4040
static var liveValue: Self {
4141
.init(
42-
run: { command, path in
42+
run: { command, path, environment in
4343
@Dependency(\.logger) var logger
4444
do {
45-
let res = try await ShellOut.shellOut(to: command, at: path, logger: logger)
45+
let res = try await ShellOut.shellOut(
46+
to: command,
47+
at: path,
48+
logger: logger,
49+
environment: (environment ?? [:]).merging(["SPI_PROCESSING": "1"], uniquingKeysWith: { $1 })
50+
)
4651
if !res.stderr.isEmpty {
4752
logger.warning("stderr: \(res.stderr)")
4853
}

Tests/AppTests/AnalyzeErrorTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ extension AllTests.AnalyzeErrorTests {
6767
$0.environment.loadSPIManifest = { _ in nil }
6868
$0.fileManager.fileExists = { @Sendable _ in true }
6969
$0.logger = .testLogger(capturingLogger)
70-
$0.shell.run = { @Sendable cmd, path in
70+
$0.shell.run = { @Sendable cmd, path, _ in
7171
switch cmd {
7272
case _ where cmd.description.contains("git clone https://github.com/foo/1"):
7373
throw SimulatedError()
@@ -131,7 +131,7 @@ extension AllTests.AnalyzeErrorTests {
131131
$0.environment.loadSPIManifest = { _ in nil }
132132
$0.fileManager.fileExists = { @Sendable _ in true }
133133
$0.logger = .testLogger(capturingLogger)
134-
$0.shell.run = { @Sendable cmd, path in
134+
$0.shell.run = { @Sendable cmd, path, _ in
135135
switch cmd {
136136
case .gitCheckout(branch: "main", quiet: true) where path.hasSuffix("foo-1"):
137137
throw SimulatedError()
@@ -195,7 +195,7 @@ extension AllTests.AnalyzeErrorTests {
195195
$0.environment.allowSocialPosts = { true }
196196
$0.git = .analyzeErrorTestsMock
197197
$0.httpClient.mastodonPost = { @Sendable msg in socialPosts.withValue { $0.append(msg) } }
198-
$0.shell.run = defaultShellRun(command:path:)
198+
$0.shell.run = defaultShellRun(command:path:environment:)
199199
}
200200
}
201201
}
@@ -222,7 +222,7 @@ extension AllTests.AnalyzeErrorTests {
222222
}
223223

224224

225-
private func defaultShellRun(command: ShellOutCommand, path: String) throws -> String {
225+
private func defaultShellRun(command: ShellOutCommand, path: String, environment: [String: String]? = nil) throws -> String {
226226
switch command {
227227
case .swiftDumpPackage where path.hasSuffix("foo-1"):
228228
return packageSwift1

Tests/AppTests/AnalyzerTests.swift

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ extension AllTests.AnalyzerTests {
5959
}
6060
$0.git = .liveValue
6161
$0.httpClient.mastodonPost = { @Sendable _ in }
62-
$0.shell.run = { @Sendable cmd, path in
62+
$0.shell.run = { @Sendable cmd, path, _ in
6363
let trimmedPath = path.replacingOccurrences(of: checkoutDir.value!, with: ".")
6464
commands.withValue {
6565
$0.append(.init(command: cmd, path: trimmedPath)!)
@@ -249,7 +249,7 @@ extension AllTests.AnalyzerTests {
249249
"""
250250
}
251251
$0.httpClient.mastodonPost = { @Sendable _ in }
252-
$0.shell.run = { @Sendable cmd, path in
252+
$0.shell.run = { @Sendable cmd, path, _ in
253253
if cmd.description.hasSuffix("package dump-package") {
254254
return #"""
255255
{
@@ -320,7 +320,7 @@ extension AllTests.AnalyzerTests {
320320
$0.git.hasBranch = { @Sendable _, _ in false } // simulate analysis error via branch mismatch
321321
$0.git.lastCommitDate = { @Sendable _ in .t1 }
322322
$0.git.shortlog = { @Sendable _ in "" }
323-
$0.shell.run = { @Sendable _, _ in "" }
323+
$0.shell.run = { @Sendable _, _, _ in "" }
324324
} operation: {
325325
// setup
326326
do {
@@ -374,7 +374,7 @@ extension AllTests.AnalyzerTests {
374374
2\tPerson 2
375375
"""
376376
}
377-
$0.shell.run = { @Sendable cmd, path in
377+
$0.shell.run = { @Sendable cmd, path, _ in
378378
// first package fails
379379
if cmd.description.hasSuffix("swift package dump-package") && path.hasSuffix("foo-1") {
380380
return "bad data"
@@ -439,7 +439,7 @@ extension AllTests.AnalyzerTests {
439439
return false
440440
}
441441
$0.git = .liveValue
442-
$0.shell.run = { @Sendable cmd, path in
442+
$0.shell.run = { @Sendable cmd, path, _ in
443443
commands.withValue {
444444
$0.append(.init(command: cmd, path: path)!)
445445
}
@@ -500,7 +500,7 @@ extension AllTests.AnalyzerTests {
500500
let commands = QueueIsolated<[String]>([])
501501
try await withDependencies {
502502
$0.fileManager.fileExists = { @Sendable _ in true }
503-
$0.shell.run = { @Sendable cmd, path in
503+
$0.shell.run = { @Sendable cmd, path, _ in
504504
commands.withValue { $0.append(cmd.description) }
505505
return ""
506506
}
@@ -532,7 +532,7 @@ extension AllTests.AnalyzerTests {
532532
2\tPerson 2
533533
"""
534534
}
535-
$0.shell.run = { @Sendable cmd, _ in throw TestError.unknownCommand }
535+
$0.shell.run = { @Sendable cmd, _, _ in throw TestError.unknownCommand }
536536
} operation: {
537537
// setup
538538
let pkg = Package(id: .id0, url: "1".asGithubUrl.url)
@@ -641,7 +641,7 @@ extension AllTests.AnalyzerTests {
641641
if ref == .tag(1, 2, 3) { return .init(commit: "sha.1.2.3", date: .t1) }
642642
fatalError("unknown ref: \(ref)")
643643
}
644-
$0.shell.run = { @Sendable cmd, _ in throw TestError.unknownCommand }
644+
$0.shell.run = { @Sendable cmd, _, _ in throw TestError.unknownCommand }
645645
} operation: {
646646
//setup
647647
let pkgId = UUID()
@@ -777,7 +777,7 @@ extension AllTests.AnalyzerTests {
777777
try await withDependencies {
778778
$0.environment.loadSPIManifest = { _ in nil }
779779
$0.fileManager.fileExists = { @Sendable _ in true }
780-
$0.shell.run = { @Sendable cmd, _ in
780+
$0.shell.run = { @Sendable cmd, _, _ in
781781
commands.withValue {
782782
$0.append(cmd.description)
783783
}
@@ -938,7 +938,7 @@ extension AllTests.AnalyzerTests {
938938
2\tPerson 2
939939
"""
940940
}
941-
$0.shell.run = { @Sendable cmd, path in
941+
$0.shell.run = { @Sendable cmd, path, _ in
942942
if cmd.description.hasSuffix("swift package dump-package") {
943943
return #"""
944944
{
@@ -995,7 +995,7 @@ extension AllTests.AnalyzerTests {
995995
// claim every file exists, including our ficticious 'index.lock' for which
996996
// we want to trigger the cleanup mechanism
997997
$0.fileManager.fileExists = { @Sendable path in true }
998-
$0.shell.run = { @Sendable cmd, path in
998+
$0.shell.run = { @Sendable cmd, path, _ in
999999
commands.withValue { $0.append(cmd.description) }
10001000
return ""
10011001
}
@@ -1027,7 +1027,7 @@ extension AllTests.AnalyzerTests {
10271027
// claim every file exists, including our ficticious 'index.lock' for which
10281028
// we want to trigger the cleanup mechanism
10291029
$0.fileManager.fileExists = { @Sendable path in true }
1030-
$0.shell.run = { @Sendable cmd, path in
1030+
$0.shell.run = { @Sendable cmd, path, _ in
10311031
commands.withValue { $0.append(cmd.description) }
10321032
if cmd == .gitCheckout(branch: "master") {
10331033
throw TestError.simulatedCheckoutError
@@ -1132,29 +1132,40 @@ extension AllTests.AnalyzerTests {
11321132
try await withDependencies {
11331133
$0.logger = .noop
11341134
} operation: {
1135-
try await withTempDir { @Sendable tempDir in
1136-
let fixture = fixturesDirectory()
1137-
.appendingPathComponent("5.9-Package-swift").path
1138-
let fname = tempDir.appending("/Package.swift")
1139-
try await ShellOut.shellOut(to: .copyFile(from: fixture, to: fname))
1140-
var json = try await ShellClient.liveValue.run(command: .swiftDumpPackage, at: tempDir)
1141-
do { // "root" references tempDir's absolute path - replace it to make the test stable
1142-
if var obj = try JSONSerialization.jsonObject(with: Data(json.utf8)) as? [String: Any],
1143-
var packageKind = obj["packageKind"] as? [String: Any] {
1144-
packageKind["root"] = ["<tempdir>"]
1145-
obj["packageKind"] = packageKind
1146-
let data = try JSONSerialization.data(withJSONObject: obj,
1147-
options: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes])
1148-
json = String(decoding: data, as: UTF8.self)
1135+
try await withTempDir { @Sendable tempDir in
1136+
let fixture = fixturesDirectory()
1137+
.appendingPathComponent("5.9-Package-swift").path
1138+
let fname = tempDir.appending("/Package.swift")
1139+
try await ShellOut.shellOut(to: .copyFile(from: fixture, to: fname))
1140+
var json = try await ShellClient.liveValue.run(command: .swiftDumpPackage, at: tempDir)
1141+
do { // "root" references tempDir's absolute path - replace it to make the test stable
1142+
if var obj = try JSONSerialization.jsonObject(with: Data(json.utf8)) as? [String: Any],
1143+
var packageKind = obj["packageKind"] as? [String: Any] {
1144+
packageKind["root"] = ["<tempdir>"]
1145+
obj["packageKind"] = packageKind
1146+
let data = try JSONSerialization.data(withJSONObject: obj,
1147+
options: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes])
1148+
json = String(decoding: data, as: UTF8.self)
1149+
}
11491150
}
1150-
}
11511151
#if os(macOS)
1152-
assertSnapshot(of: json, as: .init(pathExtension: "json", diffing: .lines), named: "macos")
1152+
assertSnapshot(of: json, as: .init(pathExtension: "json", diffing: .lines), named: "macos")
11531153
#elseif os(Linux)
1154-
assertSnapshot(of: json, as: .init(pathExtension: "json", diffing: .lines), named: "linux")
1154+
assertSnapshot(of: json, as: .init(pathExtension: "json", diffing: .lines), named: "linux")
11551155
#endif
1156+
}
11561157
}
11571158
}
1159+
1160+
@Test func processingEnvironmentVariable() async throws {
1161+
try await withDependencies {
1162+
$0.logger = .noop
1163+
$0.shell = .liveValue
1164+
} operation: {
1165+
@Dependency(\.shell) var shell
1166+
let res = try await shell.run(command: .init(command: "printenv", arguments: ["SPI_PROCESSING"]), at: "/tmp")
1167+
#expect(res == "1")
1168+
}
11581169
}
11591170

11601171
@Test func issue_577() async throws {
@@ -1193,7 +1204,7 @@ extension AllTests.AnalyzerTests {
11931204
let commands = QueueIsolated<[String]>([])
11941205
try await withDependencies {
11951206
$0.fileManager.fileExists = { @Sendable _ in true }
1196-
$0.shell.run = { @Sendable cmd, _ in
1207+
$0.shell.run = { @Sendable cmd, _, _ in
11971208
commands.withValue { $0.append(cmd.description) }
11981209
if cmd == .gitFetchAndPruneTags { throw TestError.simulatedFetchError }
11991210
return ""
@@ -1297,7 +1308,7 @@ extension AllTests.AnalyzerTests {
12971308
if path.hasSuffix("github.com-foo-1") { return false }
12981309
return true
12991310
}
1300-
$0.shell.run = { @Sendable cmd, path in
1311+
$0.shell.run = { @Sendable cmd, path, _ in
13011312
if cmd == .gitClone(url: url, to: repoDir) {
13021313
struct ShellOutError: Error {}
13031314
throw ShellOutError()
@@ -1355,7 +1366,7 @@ extension AllTests.AnalyzerTests {
13551366
1\tPerson 2
13561367
"""
13571368
}
1358-
$0.shell.run = { @Sendable _, _ in "" }
1369+
$0.shell.run = { @Sendable _, _, _ in "" }
13591370
} operation: {
13601371
let pkgId = UUID()
13611372
let pkg = Package(id: pkgId, url: "1".asGithubUrl.url, processingStage: .ingestion)
@@ -1427,7 +1438,7 @@ extension AllTests.AnalyzerTests {
14271438
try await withDependencies { // third scenario: everything throws
14281439
$0.git.getTags = { @Sendable _ in throw TestError.unspecifiedError }
14291440
$0.git.revisionInfo = { @Sendable _, _ in throw TestError.unspecifiedError }
1430-
$0.shell.run = { @Sendable _, _ in throw TestError.unspecifiedError }
1441+
$0.shell.run = { @Sendable _, _, _ in throw TestError.unspecifiedError }
14311442
} operation: {
14321443
// MUT
14331444
try await Analyze.analyze(client: app.client,
@@ -1464,7 +1475,7 @@ extension AllTests.AnalyzerTests {
14641475
"""
14651476
}
14661477
$0.logger = .testLogger(capturingLogger)
1467-
$0.shell.run = { @Sendable _, _ in return "" }
1478+
$0.shell.run = { @Sendable _, _, _ in return "" }
14681479
} operation: {
14691480
let pkgId = UUID()
14701481
let pkg = Package(id: pkgId, url: "1".asGithubUrl.url, processingStage: .ingestion)
@@ -1526,7 +1537,7 @@ extension AllTests.AnalyzerTests {
15261537
throw Error()
15271538
}
15281539
}
1529-
$0.shell.run = { @Sendable cmd, path in
1540+
$0.shell.run = { @Sendable cmd, path, _ in
15301541
// simulate error in getPackageInfo by failing checkout
15311542
if cmd == .gitCheckout(branch: "main") {
15321543
throw Error()
@@ -1569,7 +1580,7 @@ extension AllTests.AnalyzerTests {
15691580
$0.git.lastCommitDate = { @Sendable _ in .t1 }
15701581
$0.git.revisionInfo = { @Sendable _, _ in .init(commit: "sha1", date: .t0) }
15711582
$0.git.shortlog = { @Sendable _ in "10\tPerson 1" }
1572-
$0.shell.run = { @Sendable cmd, path in
1583+
$0.shell.run = { @Sendable cmd, path, _ in
15731584
if cmd == .swiftDumpPackage { return .packageDump(name: "foo1") }
15741585
return ""
15751586
}

Tests/AppTests/ErrorReportingTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ extension AllTests.ErrorReportingTests {
6464
try await withDependencies {
6565
$0.fileManager.fileExists = { @Sendable _ in true }
6666
$0.logger = .testLogger(capturingLogger)
67-
$0.shell.run = { @Sendable cmd, _ in
67+
$0.shell.run = { @Sendable cmd, _, _ in
6868
if cmd.description == "git tag" { return "1.0.0" }
6969
// returning a blank string will cause an exception when trying to
7070
// decode it as the manifest result - we use this to simulate errors

Tests/AppTests/GitTests.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ extension AllTests.GitTests {
4545

4646
@Test func revInfo() async throws {
4747
try await withDependencies {
48-
$0.shell.run = { @Sendable cmd, _ in
48+
$0.shell.run = { @Sendable cmd, _, _ in
4949
if cmd.description == #"git log -n1 --format=tformat:"%H-%ct" 2.2.1"# {
5050
return "63c973f3c2e632a340936c285e94d59f9ffb01d5-1536799579"
5151
}
@@ -62,7 +62,7 @@ extension AllTests.GitTests {
6262
// Ensure we look up by tag name and not semver
6363
// https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/139
6464
try await withDependencies {
65-
$0.shell.run = { @Sendable cmd, _ in
65+
$0.shell.run = { @Sendable cmd, _, _ in
6666
if cmd.description == #"git log -n1 --format=tformat:"%H-%ct" v2.2.1"# {
6767
return "63c973f3c2e632a340936c285e94d59f9ffb01d5-1536799579"
6868
}
@@ -83,8 +83,8 @@ private enum TestError: Error {
8383
}
8484

8585

86-
func mock(for command: String, _ result: String) -> @Sendable (ShellOutCommand, String) throws -> String {
87-
{ @Sendable cmd, path in
86+
func mock(for command: String, _ result: String) -> @Sendable (ShellOutCommand, String, [String: String]?) throws -> String {
87+
{ @Sendable cmd, path, _ in
8888
guard cmd.description == command else { throw TestError.unknownCommand }
8989
return result
9090
}

Tests/AppTests/IngestionTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ extension AllTests.IngestionTests {
473473
$0.git.lastCommitDate = { @Sendable _ in .t0 }
474474
$0.git.revisionInfo = { @Sendable _, _ in .init(commit: "sha0", date: .t0) }
475475
$0.git.shortlog = { @Sendable _ in "" }
476-
$0.shell.run = { @Sendable cmd, _ in
476+
$0.shell.run = { @Sendable cmd, _, _ in
477477
if cmd.description.hasSuffix("package dump-package") {
478478
return .packageDump(name: "foo")
479479
}

Tests/AppTests/MastodonTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ extension AllTests.MastodonTests {
5555
Issue.record("message must only be set once")
5656
}
5757
}
58-
$0.shell.run = { @Sendable cmd, path in
58+
$0.shell.run = { @Sendable cmd, path, _ in
5959
if cmd.description.hasSuffix("swift package dump-package") {
6060
return #"{ "name": "Mock", "products": [], "targets": [] }"#
6161
}

Tests/AppTests/PackageController+routesTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,7 @@ extension AllTests.PackageController_routesTests {
15331533
}
15341534
$0.git.shortlog = { @Sendable _ in "2\tauthor" }
15351535
$0.httpClient.fetchDocumentation = { @Sendable _ in .ok(body: .mockIndexHTML()) }
1536-
$0.shell.run = { @Sendable cmd, _ in
1536+
$0.shell.run = { @Sendable cmd, _, _ in
15371537
if cmd.description == "swift package dump-package" { return .mockManifest }
15381538
return ""
15391539
}

Tests/AppTests/PackageTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ extension AllTests.PackageTests {
338338
$0.packageListRepository.fetchPackageList = { @Sendable _ in [url.url] }
339339
$0.packageListRepository.fetchPackageDenyList = { @Sendable _ in [] }
340340
$0.packageListRepository.fetchCustomCollections = { @Sendable _ in [] }
341-
$0.shell.run = { @Sendable cmd, path in
341+
$0.shell.run = { @Sendable cmd, path, _ in
342342
if cmd.description.hasSuffix("swift package dump-package") {
343343
return #"{ "name": "Mock", "products": [] }"#
344344
}

Tests/AppTests/PipelineTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ extension AllTests.PipelineTests {
198198
$0.packageListRepository.fetchPackageDenyList = { @Sendable _ in [] }
199199
$0.packageListRepository.fetchCustomCollections = { @Sendable _ in [] }
200200
$0.packageListRepository.fetchCustomCollection = { @Sendable _, _ in [] }
201-
$0.shell.run = { @Sendable cmd, path in
201+
$0.shell.run = { @Sendable cmd, path, _ in
202202
if cmd.description.hasSuffix("swift package dump-package") {
203203
return #"{ "name": "Mock", "products": [], "targets": [] }"#
204204
}

0 commit comments

Comments
 (0)