64 lines
2.0 KiB
Swift
64 lines
2.0 KiB
Swift
import Dispatch
|
|
import Foundation
|
|
import SwiftLintFramework
|
|
|
|
// Inspired by https://github.com/jkandzi/Progress.swift
|
|
actor ProgressBar {
|
|
private var index = 1
|
|
private var lastPrintedTime: TimeInterval = 0.0
|
|
private let startTime = uptime()
|
|
private let count: Int
|
|
|
|
init(count: Int) {
|
|
self.count = count
|
|
}
|
|
|
|
func initialize() {
|
|
// When progress is printed, the previous line is reset, so print an empty line before anything else
|
|
queuedPrintError("")
|
|
}
|
|
|
|
func printNext() {
|
|
guard index <= count else { return }
|
|
|
|
let currentTime = uptime()
|
|
if currentTime - lastPrintedTime > 0.1 || index == count {
|
|
let lineReset = "\u{1B}[1A\u{1B}[K"
|
|
let bar = makeBar()
|
|
let timeEstimate = makeTimeEstimate(currentTime: currentTime)
|
|
let lineContents = "\(index) of \(count) \(bar) \(timeEstimate)"
|
|
queuedPrintError("\(lineReset)\(lineContents)")
|
|
lastPrintedTime = currentTime
|
|
}
|
|
|
|
index += 1
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func makeBar() -> String {
|
|
let barLength = 30
|
|
let completedBarElements = Int(Double(barLength) * (Double(index) / Double(count)))
|
|
let barArray = Array(repeating: "=", count: completedBarElements) +
|
|
Array(repeating: " ", count: barLength - completedBarElements)
|
|
return "[\(barArray.joined())]"
|
|
}
|
|
|
|
private func makeTimeEstimate(currentTime: TimeInterval) -> String {
|
|
let totalTime = currentTime - startTime
|
|
let itemsPerSecond = Double(index) / totalTime
|
|
let estimatedTimeRemaining = Double(count - index) / itemsPerSecond
|
|
let estimatedTimeRemainingString = "\(Int(estimatedTimeRemaining))s"
|
|
return "ETA: \(estimatedTimeRemainingString) (\(Int(itemsPerSecond)) files/s)"
|
|
}
|
|
}
|
|
|
|
#if os(Linux)
|
|
// swiftlint:disable:next identifier_name
|
|
private let NSEC_PER_SEC = 1_000_000_000
|
|
#endif
|
|
|
|
private func uptime() -> TimeInterval {
|
|
Double(DispatchTime.now().uptimeNanoseconds) / Double(NSEC_PER_SEC)
|
|
}
|