Skip to content

Commit b557890

Browse files
committed
Adopt CLI Progress Indicator
1 parent 082f617 commit b557890

File tree

4 files changed

+54
-40
lines changed

4 files changed

+54
-40
lines changed

Sources/hostmgr/commands/benchmark/NetworkBenchmark.swift

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,32 +27,16 @@ struct NetworkBenchmark: AsyncParsableCommand {
2727
region: Configuration.shared.vmImagesRegion
2828
)
2929

30+
let progressBar = Console.startFileDownload(file.imageObject)
31+
3032
try await manager.download(
3133
object: file.imageObject,
3234
to: FileManager.default.temporaryFilePath(),
33-
progressCallback: self.updateProgress
35+
progressCallback: progressBar.update
3436
)
3537
}
3638

3739
private func imageSizeSort(_ lhs: RemoteVMImage, _ rhs: RemoteVMImage) -> Bool {
3840
lhs.imageObject.size < rhs.imageObject.size
3941
}
40-
41-
private func updateProgress(_ progress: FileTransferProgress) {
42-
Self.limiter.perform {
43-
let downloadedSize = ByteCountFormatter.string(fromByteCount: Int64(progress.current), countStyle: .file)
44-
let totalSize = ByteCountFormatter.string(fromByteCount: Int64(progress.total), countStyle: .file)
45-
46-
let secondsElapsed = Date().timeIntervalSince(startDate)
47-
let perSecond = Double(progress.current) / Double(secondsElapsed)
48-
49-
// Don't continue unless the rate can be represented by `Int64`
50-
guard perSecond.isNormal else {
51-
return
52-
}
53-
54-
let rate = ByteCountFormatter.string(fromByteCount: Int64(perSecond), countStyle: .file)
55-
logger.info("Downloaded \(downloadedSize) of \(totalSize) [Rate: \(rate) per second]")
56-
}
57-
}
5842
}

Sources/hostmgr/commands/sync/SyncVMImagesCommand.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ struct SyncVMImagesCommand: AsyncParsableCommand, FollowsCommandPolicies {
6060

6161
let limiter = Limiter(policy: .throttle, operationsPerSecond: 1)
6262

63+
let progressBar = Console.startImageDownload(image)
6364
try await RemoteVMRepository().download(image: image, to: destination) { progress in
65+
progressBar.update(progress)
66+
6467
limiter.perform {
6568
try? recordHeartbeat()
66-
logger.info("\(progress.decimalPercent)% complete")
6769
}
6870
}
6971

Sources/hostmgr/commands/vm/image/remote/VMRemoteImageDownload.swift

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,10 @@ struct VMRemoteImageDownload: AsyncParsableCommand {
4848
let sleepManager = SystemSleepManager(reason: "Downloading \(remoteImage.fileName)")
4949
sleepManager.disable()
5050

51-
let progressBar = Tqdm(
52-
description: "Downloading \(remoteImage.fileName)",
53-
total: Int(remoteImage.imageObject.size),
54-
unit: " bytes",
55-
unitScale: true
56-
)
51+
let progressBar = Console.startImageDownload(remoteImage)
5752

5853
try await remote.download(image: remoteImage, to: destination) {
59-
progressBar.update(n: $0.percent)
54+
progressBar.update($0)
6055
}
61-
62-
progressBar.close()
6356
}
6457
}

Sources/libhostmgr/S3Manager.swift

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,30 +146,65 @@ public struct S3Object {
146146
}
147147

148148
public struct FileTransferProgress {
149-
public let current: Int
150-
public let total: Int
149+
public typealias Percentage = Decimal
151150

152-
public let estimatedTimeRemaining: TimeInterval?
151+
let current: Int
152+
let total: Int
153153

154-
public init(current: Int, total: Int, estimatedTimeRemaining: TimeInterval?) {
154+
public init(current: Int, total: Int) {
155155
self.current = current
156156
self.total = total
157-
self.estimatedTimeRemaining = estimatedTimeRemaining
158157
}
159158

160-
public var percent: Int {
161-
Int(decimalPercent)
159+
public var percent: Percentage {
160+
Decimal(Double(self.current) / Double(self.total) * 100.0)
162161
}
163162

164-
public var decimalPercent: Double {
165-
Double(current) / Double(total) * 100
163+
public var downloadedData: String {
164+
ByteCountFormatter.string(fromByteCount: Int64(current), countStyle: .file)
165+
}
166+
167+
public var totalData: String {
168+
ByteCountFormatter.string(fromByteCount: Int64(total), countStyle: .file)
169+
}
170+
171+
public func dataRate(timeIntervalSinceStart interval: TimeInterval) -> String {
172+
let bytesPerSecond = Double(current) / interval
173+
174+
// Don't continue unless the rate can be represented by `Int64`
175+
guard bytesPerSecond.isNormal else {
176+
return ByteCountFormatter.string(fromByteCount: 0, countStyle: .file)
177+
}
178+
179+
return ByteCountFormatter.string(fromByteCount: Int64(bytesPerSecond), countStyle: .file)
180+
}
181+
182+
public func estimatedTimeRemaining(timeIntervalSinceStart interval: TimeInterval) -> TimeInterval {
183+
let bytesPerSecond = Double(current) / interval
184+
185+
// Don't continue unless the rate makes some kind of sense
186+
guard bytesPerSecond.isNormal else {
187+
return .infinity
188+
}
189+
190+
let totalNumberOfSeconds = Double(total) / bytesPerSecond
191+
192+
return totalNumberOfSeconds - interval
193+
}
194+
195+
public var formattedPercentage: String {
196+
let formatter = NumberFormatter()
197+
formatter.alwaysShowsDecimalSeparator = true
198+
formatter.roundingMode = .down
199+
formatter.minimumFractionDigits = 2
200+
formatter.maximumFractionDigits = 2
201+
return formatter.string(from: percent as NSDecimalNumber)!
166202
}
167203

168204
static func progressData(from progress: Progress) -> FileTransferProgress {
169205
return FileTransferProgress(
170206
current: Int(progress.completedUnitCount),
171-
total: Int(progress.totalUnitCount),
172-
estimatedTimeRemaining: progress.estimatedTimeRemaining
207+
total: Int(progress.totalUnitCount)
173208
)
174209
}
175210
}

0 commit comments

Comments
 (0)