Skip to content

Commit 409f7c8

Browse files
authored
add duration to build complete message (#3832)
motivation: give users more information changes: record build duration and include it in CLI output
1 parent 9e9fab2 commit 409f7c8

File tree

5 files changed

+42
-36
lines changed

5 files changed

+42
-36
lines changed

Sources/Basics/DispatchTimeInterval+Extensions.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,25 @@ extension DispatchTimeInterval {
5656
return nil
5757
}
5858
}
59+
60+
public var descriptionInSeconds: String {
61+
switch self {
62+
case .seconds(let value):
63+
return "\(value)s"
64+
case .milliseconds(let value):
65+
return String(format: "%.2f", Double(value)/Double(1000)) + "s"
66+
case .microseconds(let value):
67+
return String(format: "%.2f", Double(value)/Double(1_000_000)) + "s"
68+
case .nanoseconds(let value):
69+
return String(format: "%.2f", Double(value)/Double(1_000_000_000)) + "s"
70+
case .never:
71+
return "n/a"
72+
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
73+
@unknown default:
74+
return "n/a"
75+
#endif
76+
}
77+
}
5978
}
6079

6180
// remove when available to all platforms
@@ -67,3 +86,4 @@ extension DispatchTime {
6786
}
6887
}
6988
#endif
89+

Sources/Build/BuildOperation.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import SPMBuildCore
1616
import SPMLLBuild
1717
import TSCBasic
1818
import TSCUtility
19+
import Foundation
1920

2021
public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildSystem, BuildErrorAdviceProvider {
2122

@@ -130,19 +131,24 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
130131

131132
/// Perform a build using the given build description and subset.
132133
public func build(subset: BuildSubset) throws {
134+
let buildStartTime = DispatchTime.now()
135+
133136
// Create the build system.
134137
let buildDescription = try self.getBuildDescription()
135138
let buildSystem = try self.createBuildSystem(buildDescription: buildDescription)
136139
self.buildSystem = buildSystem
137140

138-
buildSystemDelegate?.buildStart(configuration: self.buildParameters.configuration)
141+
// delegate is only available after createBuildSystem is called
142+
self.buildSystemDelegate?.buildStart(configuration: self.buildParameters.configuration)
139143

140144
// Perform the build.
141145
let llbuildTarget = try computeLLBuildTargetName(for: subset)
142146
let success = buildSystem.build(target: llbuildTarget)
143147

144-
buildSystemDelegate?.buildComplete(success: success)
145-
delegate?.buildSystem(self, didFinishWithResult: success)
148+
let duration = buildStartTime.distance(to: .now())
149+
150+
self.buildSystemDelegate?.buildComplete(success: success, duration: duration)
151+
self.delegate?.buildSystem(self, didFinishWithResult: success)
146152
guard success else { throw Diagnostics.fatalError }
147153

148154
// Create backwards-compatibility symlink to old build path.

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
*/
1010

1111
import Basics
12-
import TSCBasic
13-
import TSCUtility
14-
import SPMLLBuild
15-
import PackageModel
1612
import Dispatch
1713
import Foundation
1814
import LLBuildManifest
15+
import PackageModel
1916
import SPMBuildCore
17+
import SPMLLBuild
18+
import TSCBasic
19+
import TSCUtility
2020

2121
#if canImport(llbuildSwift)
2222
typealias LLBuildBuildSystemDelegate = llbuildSwift.BuildSystemDelegate
@@ -635,12 +635,12 @@ final class BuildOperationBuildSystemDelegateHandler: LLBuildBuildSystemDelegate
635635
}
636636
}
637637

638-
func buildComplete(success: Bool) {
638+
func buildComplete(success: Bool, duration: DispatchTimeInterval) {
639639
queue.sync {
640640
self.progressAnimation.complete(success: success)
641641
if success {
642642
self.progressAnimation.clear()
643-
self.outputStream <<< "Build complete!\n"
643+
self.outputStream <<< "Build complete! (\(duration.descriptionInSeconds))\n"
644644
self.outputStream.flush()
645645
}
646646
}

Sources/Commands/SwiftTool.swift

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,28 +1046,6 @@ extension Basics.Diagnostic {
10461046
}
10471047
}
10481048

1049-
extension DispatchTimeInterval {
1050-
var descriptionInSeconds: String {
1051-
switch self {
1052-
case .seconds(let value):
1053-
return "\(value)s"
1054-
case .milliseconds(let value):
1055-
return String(format: "%.2f", Double(value)/Double(1000)) + "s"
1056-
case .microseconds(let value):
1057-
return String(format: "%.2f", Double(value)/Double(1_000_000)) + "s"
1058-
case .nanoseconds(let value):
1059-
return String(format: "%.2f", Double(value)/Double(1_000_000_000)) + "s"
1060-
case .never:
1061-
return "n/a"
1062-
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
1063-
@unknown default:
1064-
return "n/a"
1065-
#endif
1066-
}
1067-
}
1068-
}
1069-
1070-
10711049
// MARK: - Diagnostics
10721050

10731051
private struct SwiftToolObservability: ObservabilityHandlerProvider, DiagnosticsHandler {

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,17 @@ final class BuildToolTests: CommandsTestCase {
272272
fixture(name: "DependencyResolution/Internal/Simple") { path in
273273
do {
274274
let result = try execute([], packagePath: path)
275-
// Number of steps must be greater than 0. e.g., [8/8] Build complete!
276-
XCTAssertMatch(result.stdout, .regex("\\[[1-9][0-9]*\\/[1-9][0-9]*\\] Linking Foo"))
277-
XCTAssertMatch(result.stdout, .suffix("\nBuild complete!\n"))
275+
XCTAssertMatch(result.stdout, .regex("\\[[1-9][0-9]*\\/[1-9][0-9]*\\] Compiling"))
276+
let lines = result.stdout.split(separator: "\n")
277+
XCTAssertMatch(String(lines.last!), .regex("Build complete! \\([0-9]*\\.[0-9]*s\\)"))
278278
}
279279

280280
do {
281-
let result = try execute([], packagePath: path)
282281
// test second time, to make sure message is presented even when nothing to build (cached)
283-
XCTAssertMatch(result.stdout, .equal("[1/1] Planning build\nBuilding for debugging...\nBuild complete!\n"))
282+
let result = try execute([], packagePath: path)
283+
XCTAssertNoMatch(result.stdout, .regex("\\[[1-9][0-9]*\\/[1-9][0-9]*\\] Compiling"))
284+
let lines = result.stdout.split(separator: "\n")
285+
XCTAssertMatch(String(lines.last!), .regex("Build complete! \\([0-9]*\\.[0-9]*s\\)"))
284286
}
285287
}
286288
}

0 commit comments

Comments
 (0)