Skip to content

Commit dc38c78

Browse files
committed
Fix --quiet option not working with swift run #8844
Use the log level to determine whether a message should be log or not. If log level is error, log only error messages and ignore all other messages. This fixes the issue for swift run command, and it benefits the swift build command as well. Add a small refactoring to remove duplicated decleration of the isVerbose property from different targets.
1 parent 94b14f2 commit dc38c78

File tree

11 files changed

+191
-30
lines changed

11 files changed

+191
-30
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// swift-tools-version: 5.6
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "TestableExe",
6+
targets: [
7+
.executableTarget(
8+
name: "Test",
9+
path: "."
10+
),
11+
]
12+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
print("done")

Sources/Basics/Observability.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,14 @@ public struct Diagnostic: Sendable, CustomStringConvertible {
443443
public var isBold: Bool {
444444
return true
445445
}
446+
447+
public var isVerbose: Bool {
448+
self <= .info
449+
}
450+
451+
public var isQuiet: Bool {
452+
self >= .error
453+
}
446454
}
447455
}
448456

Sources/Build/BuildOperation.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,9 +1049,3 @@ extension BuildSubset {
10491049
}
10501050
}
10511051
}
1052-
1053-
extension Basics.Diagnostic.Severity {
1054-
var isVerbose: Bool {
1055-
return self <= .info
1056-
}
1057-
}

Sources/Build/LLBuildProgressTracker.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
241241
}
242242

243243
func commandStatusChanged(_ command: SPMLLBuild.Command, kind: CommandStatusKind) {
244-
guard !self.logLevel.isVerbose else { return }
244+
guard !self.logLevel.isVerbose,
245+
!self.logLevel.isQuiet
246+
else { return }
245247
guard command.shouldShowStatus else { return }
246248
guard !self.swiftParsers.keys.contains(command.name) else { return }
247249

@@ -285,7 +287,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
285287

286288
self.delegate?.buildSystem(self.buildSystem, didFinishCommand: BuildSystemCommand(command))
287289

288-
if !self.logLevel.isVerbose {
290+
if !self.logLevel.isVerbose && !self.logLevel.isQuiet {
289291
let targetName = self.swiftParsers[command.name]?.targetName
290292
self.taskTracker.commandFinished(command, result: result, targetName: targetName)
291293
self.updateProgress()
@@ -395,6 +397,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
395397

396398
/// Invoked right before running an action taken before building.
397399
func preparationStepStarted(_ name: String) {
400+
guard !self.logLevel.isQuiet else { return }
398401
self.queue.async {
399402
self.taskTracker.buildPreparationStepStarted(name)
400403
self.updateProgress()
@@ -404,6 +407,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
404407
/// Invoked when an action taken before building emits output.
405408
/// when verboseOnly is set to true, the output will only be printed in verbose logging mode
406409
func preparationStepHadOutput(_ name: String, output: String, verboseOnly: Bool) {
410+
guard !logLevel.isQuiet else { return }
407411
self.queue.async {
408412
self.progressAnimation.clear()
409413
if !verboseOnly || self.logLevel.isVerbose {
@@ -416,6 +420,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
416420
/// Invoked right after running an action taken before building. The result
417421
/// indicates whether the action succeeded, failed, or was cancelled.
418422
func preparationStepFinished(_ name: String, result: CommandResult) {
423+
guard !self.logLevel.isQuiet else { return }
419424
self.queue.async {
420425
self.taskTracker.buildPreparationStepFinished(name)
421426
self.updateProgress()
@@ -431,7 +436,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
431436
self.outputStream.send("\(text)\n")
432437
self.outputStream.flush()
433438
}
434-
} else {
439+
} else if !self.logLevel.isQuiet {
435440
self.taskTracker.swiftCompilerDidOutputMessage(message, targetName: parser.targetName)
436441
self.updateProgress()
437442
}
@@ -466,6 +471,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
466471
}
467472

468473
func buildStart(configuration: BuildConfiguration) {
474+
guard !logLevel.isQuiet else { return }
469475
self.queue.sync {
470476
self.progressAnimation.clear()
471477
self.outputStream.send("Building for \(configuration == .debug ? "debugging" : "production")...\n")
@@ -484,7 +490,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
484490
self.progressAnimation.complete(success: success)
485491
self.delegate?.buildSystem(self.buildSystem, didFinishWithResult: success)
486492

487-
if success {
493+
if !self.logLevel.isQuiet, success {
488494
let message = self.cancelled ? "Build \(subsetString)cancelled!" : "Build \(subsetString)complete!"
489495
self.progressAnimation.clear()
490496
self.outputStream.send("\(message) (\(duration.descriptionInSeconds))\n")

Sources/CoreCommands/SwiftCommandObservabilityHandler.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,3 @@ extension ObservabilityMetadata {
221221
}
222222
}
223223
}
224-
225-
extension Basics.Diagnostic.Severity {
226-
fileprivate var isVerbose: Bool {
227-
return self <= .info
228-
}
229-
}

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
378378
}
379379

380380
func emitEvent(_ message: SwiftBuild.SwiftBuildMessage, buildState: inout BuildState) throws {
381+
guard !self.logLevel.isQuiet else { return }
381382
switch message {
382383
case .buildCompleted(let info):
383384
progressAnimation.complete(success: info.result == .ok)
@@ -477,6 +478,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
477478

478479
switch operation.state {
479480
case .succeeded:
481+
guard !self.logLevel.isQuiet else { return }
480482
progressAnimation.update(step: 100, total: 100, text: "")
481483
progressAnimation.complete(success: true)
482484
let duration = ContinuousClock.Instant.now - buildStartTime
@@ -816,12 +818,6 @@ extension String {
816818
}
817819
}
818820

819-
extension Basics.Diagnostic.Severity {
820-
var isVerbose: Bool {
821-
self <= .info
822-
}
823-
}
824-
825821
fileprivate extension SwiftBuild.SwiftBuildMessage.DiagnosticInfo.Location {
826822
var userDescription: String? {
827823
switch self {

Sources/XCBuildSupport/XCBuildDelegate.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,14 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
6969
queue.async {
7070
self.didEmitProgressOutput = true
7171
let text = self.logLevel.isVerbose ? [info.executionDescription, info.commandLineDisplayString].compactMap { $0 }.joined(separator: "\n") : info.executionDescription
72-
self.progressAnimation.update(step: self.percentComplete, total: 100, text: text)
72+
if !self.logLevel.isQuiet {
73+
self.progressAnimation.update(step: self.percentComplete, total: 100, text: text)
74+
}
7375
self.buildSystem.delegate?.buildSystem(self.buildSystem, willStartCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.executionDescription, verboseDescription: info.commandLineDisplayString))
7476
self.buildSystem.delegate?.buildSystem(self.buildSystem, didStartCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.executionDescription, verboseDescription: info.commandLineDisplayString))
7577
}
7678
case .taskOutput(let info):
79+
guard !self.logLevel.isQuiet else { return }
7780
queue.async {
7881
self.progressAnimation.clear()
7982
self.outputStream.send("\(info.data)\n")
@@ -84,24 +87,28 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
8487
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.result.rawValue))
8588
}
8689
case .buildDiagnostic(let info):
90+
guard !self.logLevel.isQuiet else { return }
8791
queue.async {
8892
self.progressAnimation.clear()
8993
self.outputStream.send("\(info.message)\n")
9094
self.outputStream.flush()
9195
}
9296
case .taskDiagnostic(let info):
97+
guard !self.logLevel.isQuiet else { return }
9398
queue.async {
9499
self.progressAnimation.clear()
95100
self.outputStream.send("\(info.message)\n")
96101
self.outputStream.flush()
97102
}
98103
case .targetDiagnostic(let info):
104+
guard !self.logLevel.isQuiet else { return }
99105
queue.async {
100106
self.progressAnimation.clear()
101107
self.outputStream.send("\(info.message)\n")
102108
self.outputStream.flush()
103109
}
104110
case .buildOutput(let info):
111+
guard !self.logLevel.isQuiet else { return }
105112
queue.async {
106113
self.progressAnimation.clear()
107114
self.outputStream.send("\(info.data)\n")
@@ -121,7 +128,7 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
121128
self.outputStream.flush()
122129
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishWithResult: false)
123130
case .ok:
124-
if self.didEmitProgressOutput {
131+
if self.didEmitProgressOutput && !self.logLevel.isQuiet {
125132
self.progressAnimation.update(step: 100, total: 100, text: "Build succeeded")
126133
}
127134
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishWithResult: true)

Sources/XCBuildSupport/XcodeBuildSystem.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem {
244244
throw Diagnostics.fatalError
245245
}
246246

247+
guard !self.logLevel.isQuiet else { return }
247248
self.outputStream.send("Build complete!\n")
248249
self.outputStream.flush()
249250
}
@@ -412,9 +413,3 @@ extension BuildSubset {
412413
}
413414
}
414415
}
415-
416-
extension Basics.Diagnostic.Severity {
417-
var isVerbose: Bool {
418-
self <= .info
419-
}
420-
}

Tests/CommandsTests/BuildCommandTests.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,82 @@ struct BuildCommandTestCases {
13341334
}
13351335
}
13361336

1337+
@Test(
1338+
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
1339+
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
1340+
)
1341+
func swiftBuildQuietLogLevel(
1342+
buildSystem: BuildSystemProvider.Kind,
1343+
configuration: BuildConfiguration
1344+
) async throws {
1345+
try await withKnownIssue {
1346+
// GIVEN we have a simple test package
1347+
try await fixture(name: "Miscellaneous/SwiftBuild") { fixturePath in
1348+
//WHEN we build with the --quiet option
1349+
let (stdout, stderr) = try await executeSwiftBuild(
1350+
fixturePath,
1351+
configuration: configuration,
1352+
extraArgs: ["--quiet"],
1353+
buildSystem: buildSystem
1354+
)
1355+
// THEN we should not see any output in stderr
1356+
#expect(stderr.isEmpty)
1357+
// AND no content in stdout
1358+
#expect(stdout.isEmpty)
1359+
}
1360+
} when: {
1361+
ProcessInfo.hostOperatingSystem == .windows &&
1362+
buildSystem == .swiftbuild
1363+
}
1364+
}
1365+
1366+
@Test(
1367+
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
1368+
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
1369+
)
1370+
func swiftBuildQuietLogLevelWithError(
1371+
buildSystem: BuildSystemProvider.Kind,
1372+
configuration: BuildConfiguration
1373+
) async throws {
1374+
// GIVEN we have a simple test package
1375+
try await fixture(name: "Miscellaneous/SwiftBuild") { fixturePath in
1376+
let mainFilePath = fixturePath.appending("main.swift")
1377+
try localFileSystem.removeFileTree(mainFilePath)
1378+
try localFileSystem.writeFileContents(
1379+
mainFilePath,
1380+
string: """
1381+
print("done"
1382+
"""
1383+
)
1384+
1385+
//WHEN we build with the --quiet option
1386+
let error = await #expect(throws: SwiftPMError.self) {
1387+
try await executeSwiftBuild(
1388+
fixturePath,
1389+
configuration: .debug,
1390+
extraArgs: ["--quiet"],
1391+
buildSystem: buildSystem
1392+
)
1393+
}
1394+
1395+
guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = try #require(error) else {
1396+
Issue.record("Incorrect error was raised.")
1397+
return
1398+
}
1399+
1400+
if buildSystem == .swiftbuild {
1401+
// THEN we should see output in stderr
1402+
#expect(stderr.isEmpty == false)
1403+
// AND no content in stdout
1404+
#expect(stdout.isEmpty)
1405+
} else {
1406+
// THEN we should see content in stdout
1407+
#expect(stdout.isEmpty == false)
1408+
// AND no output in stderr
1409+
#expect(stderr.isEmpty)
1410+
}
1411+
}
1412+
}
13371413
}
13381414

13391415
extension Triple {

0 commit comments

Comments
 (0)