Skip to content

Cherry-pick Fix --quiet option not working with swift run #8844 (#8858) #8907

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: release/6.2
Choose a base branch
from
Open
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
12 changes: 12 additions & 0 deletions Fixtures/Miscellaneous/SwiftBuild/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// swift-tools-version: 5.6
import PackageDescription

let package = Package(
name: "TestableExe",
targets: [
.executableTarget(
name: "Test",
path: "."
),
]
)
1 change: 1 addition & 0 deletions Fixtures/Miscellaneous/SwiftBuild/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("done")
8 changes: 8 additions & 0 deletions Sources/Basics/Observability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,14 @@ public struct Diagnostic: Sendable, CustomStringConvertible {
public var isBold: Bool {
return true
}

public var isVerbose: Bool {
self <= .info
}

public var isQuiet: Bool {
self >= .error
}
}
}

Expand Down
6 changes: 0 additions & 6 deletions Sources/Build/BuildOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1044,9 +1044,3 @@ extension BuildSubset {
}
}
}

extension Basics.Diagnostic.Severity {
var isVerbose: Bool {
return self <= .info
}
}
14 changes: 10 additions & 4 deletions Sources/Build/LLBuildProgressTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
}

func commandStatusChanged(_ command: SPMLLBuild.Command, kind: CommandStatusKind) {
guard !self.logLevel.isVerbose else { return }
guard !self.logLevel.isVerbose,
!self.logLevel.isQuiet
else { return }
guard command.shouldShowStatus else { return }
guard !self.swiftParsers.keys.contains(command.name) else { return }

Expand Down Expand Up @@ -285,7 +287,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut

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

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

/// Invoked right before running an action taken before building.
func preparationStepStarted(_ name: String) {
guard !self.logLevel.isQuiet else { return }
self.queue.async {
self.taskTracker.buildPreparationStepStarted(name)
self.updateProgress()
Expand All @@ -404,6 +407,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
/// Invoked when an action taken before building emits output.
/// when verboseOnly is set to true, the output will only be printed in verbose logging mode
func preparationStepHadOutput(_ name: String, output: String, verboseOnly: Bool) {
guard !logLevel.isQuiet else { return }
self.queue.async {
self.progressAnimation.clear()
if !verboseOnly || self.logLevel.isVerbose {
Expand All @@ -416,6 +420,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
/// Invoked right after running an action taken before building. The result
/// indicates whether the action succeeded, failed, or was cancelled.
func preparationStepFinished(_ name: String, result: CommandResult) {
guard !self.logLevel.isQuiet else { return }
self.queue.async {
self.taskTracker.buildPreparationStepFinished(name)
self.updateProgress()
Expand All @@ -431,7 +436,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
self.outputStream.send("\(text)\n")
self.outputStream.flush()
}
} else {
} else if !self.logLevel.isQuiet {
self.taskTracker.swiftCompilerDidOutputMessage(message, targetName: parser.targetName)
self.updateProgress()
}
Expand Down Expand Up @@ -466,6 +471,7 @@ final class LLBuildProgressTracker: LLBuildBuildSystemDelegate, SwiftCompilerOut
}

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

if success {
if !self.logLevel.isQuiet, success {
let message = self.cancelled ? "Build \(subsetString)cancelled!" : "Build \(subsetString)complete!"
self.progressAnimation.clear()
self.outputStream.send("\(message) (\(duration.descriptionInSeconds))\n")
Expand Down
6 changes: 0 additions & 6 deletions Sources/CoreCommands/SwiftCommandObservabilityHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,3 @@ extension ObservabilityMetadata {
}
}
}

extension Basics.Diagnostic.Severity {
fileprivate var isVerbose: Bool {
return self <= .info
}
}
8 changes: 2 additions & 6 deletions Sources/SwiftBuildSupport/SwiftBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
}

func emitEvent(_ message: SwiftBuild.SwiftBuildMessage, buildState: inout BuildState) throws {
guard !self.logLevel.isQuiet else { return }
switch message {
case .buildCompleted(let info):
progressAnimation.complete(success: info.result == .ok)
Expand Down Expand Up @@ -432,6 +433,7 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {

switch operation.state {
case .succeeded:
guard !self.logLevel.isQuiet else { return }
progressAnimation.update(step: 100, total: 100, text: "")
progressAnimation.complete(success: true)
let duration = ContinuousClock.Instant.now - buildStartTime
Expand Down Expand Up @@ -743,12 +745,6 @@ extension String {
}
}

extension Basics.Diagnostic.Severity {
var isVerbose: Bool {
self <= .info
}
}

fileprivate extension SwiftBuild.SwiftBuildMessage.DiagnosticInfo.Location {
var userDescription: String? {
switch self {
Expand Down
11 changes: 9 additions & 2 deletions Sources/XCBuildSupport/XCBuildDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
queue.async {
self.didEmitProgressOutput = true
let text = self.logLevel.isVerbose ? [info.executionDescription, info.commandLineDisplayString].compactMap { $0 }.joined(separator: "\n") : info.executionDescription
self.progressAnimation.update(step: self.percentComplete, total: 100, text: text)
if !self.logLevel.isQuiet {
self.progressAnimation.update(step: self.percentComplete, total: 100, text: text)
}
self.buildSystem.delegate?.buildSystem(self.buildSystem, willStartCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.executionDescription, verboseDescription: info.commandLineDisplayString))
self.buildSystem.delegate?.buildSystem(self.buildSystem, didStartCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.executionDescription, verboseDescription: info.commandLineDisplayString))
}
case .taskOutput(let info):
guard !self.logLevel.isQuiet else { return }
queue.async {
self.progressAnimation.clear()
self.outputStream.send("\(info.data)\n")
Expand All @@ -84,24 +87,28 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishCommand: BuildSystemCommand(name: "\(info.taskID)", description: info.result.rawValue))
}
case .buildDiagnostic(let info):
guard !self.logLevel.isQuiet else { return }
queue.async {
self.progressAnimation.clear()
self.outputStream.send("\(info.message)\n")
self.outputStream.flush()
}
case .taskDiagnostic(let info):
guard !self.logLevel.isQuiet else { return }
queue.async {
self.progressAnimation.clear()
self.outputStream.send("\(info.message)\n")
self.outputStream.flush()
}
case .targetDiagnostic(let info):
guard !self.logLevel.isQuiet else { return }
queue.async {
self.progressAnimation.clear()
self.outputStream.send("\(info.message)\n")
self.outputStream.flush()
}
case .buildOutput(let info):
guard !self.logLevel.isQuiet else { return }
queue.async {
self.progressAnimation.clear()
self.outputStream.send("\(info.data)\n")
Expand All @@ -121,7 +128,7 @@ extension XCBuildDelegate: XCBuildOutputParserDelegate {
self.outputStream.flush()
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishWithResult: false)
case .ok:
if self.didEmitProgressOutput {
if self.didEmitProgressOutput && !self.logLevel.isQuiet {
self.progressAnimation.update(step: 100, total: 100, text: "Build succeeded")
}
self.buildSystem.delegate?.buildSystem(self.buildSystem, didFinishWithResult: true)
Expand Down
7 changes: 1 addition & 6 deletions Sources/XCBuildSupport/XcodeBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem {
throw Diagnostics.fatalError
}

guard !self.logLevel.isQuiet else { return }
self.outputStream.send("Build complete!\n")
self.outputStream.flush()
}
Expand Down Expand Up @@ -408,9 +409,3 @@ extension BuildSubset {
}
}
}

extension Basics.Diagnostic.Severity {
var isVerbose: Bool {
self <= .info
}
}
79 changes: 79 additions & 0 deletions Tests/CommandsTests/BuildCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,85 @@ struct BuildCommandTestCases {
}
}

@Test(
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
)
func swiftBuildQuietLogLevel(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration
) async throws {
try await withKnownIssue {
// GIVEN we have a simple test package
try await fixture(name: "Miscellaneous/SwiftBuild") { fixturePath in
//WHEN we build with the --quiet option
let (stdout, stderr) = try await executeSwiftBuild(
fixturePath,
configuration: configuration,
extraArgs: ["--quiet"],
buildSystem: buildSystem
)
// THEN we should not see any output in stderr
#expect(stderr.isEmpty)
// AND no content in stdout
#expect(stdout.isEmpty)
}
} when: {
buildSystem == .swiftbuild && (
ProcessInfo.hostOperatingSystem == .windows || (
ProcessInfo.hostOperatingSystem == .linux && configuration == .release
)
)
}
}

@Test(
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
)
func swiftBuildQuietLogLevelWithError(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration
) async throws {
// GIVEN we have a simple test package
try await fixture(name: "Miscellaneous/SwiftBuild") { fixturePath in
let mainFilePath = fixturePath.appending("main.swift")
try localFileSystem.removeFileTree(mainFilePath)
try localFileSystem.writeFileContents(
mainFilePath,
string: """
print("done"
"""
)

//WHEN we build with the --quiet option
let error = await #expect(throws: SwiftPMError.self) {
try await executeSwiftBuild(
fixturePath,
configuration: .debug,
extraArgs: ["--quiet"],
buildSystem: buildSystem
)
}

guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = try #require(error) else {
Issue.record("Incorrect error was raised.")
return
}

if buildSystem == .swiftbuild {
// THEN we should see output in stderr
#expect(stderr.isEmpty == false)
// AND no content in stdout
#expect(stdout.isEmpty)
} else {
// THEN we should see content in stdout
#expect(stdout.isEmpty == false)
// AND no output in stderr
#expect(stderr.isEmpty)
}
}
}
}

extension Triple {
Expand Down
70 changes: 70 additions & 0 deletions Tests/CommandsTests/RunCommandTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,74 @@ struct RunCommandTests {
}
}

@Test(
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
)
func swiftRunQuietLogLevel(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration
) async throws {
try await withKnownIssue(isIntermittent: true) {
// GIVEN we have a simple test package
try await fixture(name: "Miscellaneous/SwiftRun") { fixturePath in
//WHEN we run with the --quiet option
let (stdout, stderr) = try await executeSwiftRun(
fixturePath,
nil,
configuration: configuration,
extraArgs: ["--quiet"],
buildSystem: buildSystem
)
// THEN we should not see any output in stderr
#expect(stderr.isEmpty)
// AND no content in stdout
#expect(stdout == "done\n")
}
} when: {
buildSystem == .swiftbuild && ProcessInfo.hostOperatingSystem == .linux
}
}

@Test(
.bug("https://github.com/swiftlang/swift-package-manager/issues/8844"),
arguments: SupportedBuildSystemOnPlatform, BuildConfiguration.allCases
)
func swiftRunQuietLogLevelWithError(
buildSystem: BuildSystemProvider.Kind,
configuration: BuildConfiguration
) async throws {
// GIVEN we have a simple test package
try await fixture(name: "Miscellaneous/SwiftRun") { fixturePath in
let mainFilePath = fixturePath.appending("main.swift")
try localFileSystem.removeFileTree(mainFilePath)
try localFileSystem.writeFileContents(
mainFilePath,
string: """
print("done"
"""
)

//WHEN we run with the --quiet option
let error = await #expect(throws: SwiftPMError.self) {
try await executeSwiftRun(
fixturePath,
nil,
configuration: .debug,
extraArgs: ["--quiet"],
buildSystem: buildSystem
)
}

guard case SwiftPMError.executionFailure(_, let stdout, let stderr) = try #require(error) else {
Issue.record("Incorrect error was raised.")
return
}

// THEN we should see an output in stderr
#expect(stderr.isEmpty == false)
// AND no content in stdout
#expect(stdout.isEmpty)
}
}
}