Files
Saleem Abdulrasool 339d250464 Port to Windows (#5030)
At least ensure it compiles just fine on Windows.

* build: add CryptoSwift dependency for Windows
* SwiftLintBuiltInRules: treat Windows similar to Linux wrt `NSDataDetector`
* SwiftLintCore: initial pass for Windows support

Add some Windows specific handling for the paths in SwiftLintCore.  The
one piece that this change does not cover is the handling of `glob` as
that is not an ISO C standard function and as such there is no `glob` on
Windows.  This will be worked through separately.

* swiftlint: add a Windows port

This enables building the swiftlint command on Windows.  There is no
system ioctl for terminal access, instead, we can use the Win32 Console
API surface to query the console size.  In the case of a failure, assume
the width to be 80-columns (as the standard VGA console is 80x25).

* WIP/SwiftLintCore: port the `glob` function to Windows

Windows does not support `glob` as a standard C library function as that
is not part of the C standard.  Attempt to emulate that through the use
of `FindFirstFileW` and `FindNextFile` to iterate the matching files
given a pattern.  This should allow us to start enumerating the files as
if we had `glob` available.
2025-11-21 09:59:28 +01:00

63 lines
2.0 KiB
Swift

import Dispatch
import Foundation
// 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) || os(Windows)
// 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)
}