File tree Expand file tree Collapse file tree 3 files changed +90
-0
lines changed
Expand file tree Collapse file tree 3 files changed +90
-0
lines changed Original file line number Diff line number Diff line change 1+ import Foundation
2+ import SwiftlyCore
3+ import SystemPackage
4+ import TSCUtility
5+
6+ enum ProgressInfo : Codable {
7+ case step( timestamp: Date , percent: Int , text: String )
8+ case complete( success: Bool )
9+ }
10+
11+ struct JsonFileProgressReporter : ProgressAnimationProtocol {
12+ let filePath : FilePath
13+ private let encoder : JSONEncoder
14+
15+ init ( filePath: FilePath , encoder: JSONEncoder = JSONEncoder ( ) ) {
16+ self . filePath = filePath
17+ self . encoder = encoder
18+ }
19+
20+ private func writeProgress( _ progress: ProgressInfo ) {
21+ let jsonData = try ? self . encoder. encode ( progress)
22+ guard let jsonData = jsonData, let jsonString = String ( data: jsonData, encoding: . utf8)
23+ else {
24+ print ( " Failed to encode progress entry to JSON " )
25+ return
26+ }
27+
28+ let jsonLine = jsonString + " \n "
29+
30+ do {
31+ try jsonLine. append ( to: self . filePath)
32+ } catch {
33+ print ( " Failed to write progress entry to \( self . filePath) : \( error) " )
34+ }
35+ }
36+
37+ func update( step: Int , total: Int , text: String ) {
38+ assert ( step <= total)
39+ self . writeProgress (
40+ ProgressInfo . step (
41+ timestamp: Date ( ) ,
42+ percent: Int ( Double ( step) / Double( total) * 100 ) ,
43+ text: text
44+ ) )
45+ }
46+
47+ func complete( success: Bool ) {
48+ self . writeProgress ( ProgressInfo . complete ( success: success) )
49+ }
50+
51+ func clear( ) {
52+ do {
53+ try FileManager . default. removeItem ( atPath: self . filePath. string)
54+ } catch {
55+ print ( " Failed to clear progress file at \( self . filePath) : \( error) " )
56+ }
57+ }
58+ }
Original file line number Diff line number Diff line change @@ -190,6 +190,22 @@ extension String {
190190 try self . write ( to: URL ( fileURLWithPath: path. string) , atomically: atomically, encoding: enc)
191191 }
192192
193+ public func append( to path: FilePath , encoding enc: String . Encoding = . utf8) throws {
194+ if !FileManager. default. fileExists ( atPath: path. string) {
195+ try self . write ( to: path, atomically: true , encoding: enc)
196+ return
197+ }
198+
199+ let fileHandle = try FileHandle ( forWritingTo: URL ( fileURLWithPath: path. string) )
200+ defer { fileHandle. closeFile ( ) }
201+ fileHandle. seekToEndOfFile ( )
202+ if let data = self . data ( using: enc) {
203+ fileHandle. write ( data)
204+ } else {
205+ throw SwiftlyError ( message: " Failed to convert string to data with encoding \( enc) " )
206+ }
207+ }
208+
193209 public init ( contentsOf path: FilePath , encoding enc: String . Encoding = . utf8) throws {
194210 try self . init ( contentsOf: URL ( fileURLWithPath: path. string) , encoding: enc)
195211 }
Original file line number Diff line number Diff line change 11import Foundation
2+ @testable import Swiftly
3+ @testable import SwiftlyCore
24import SystemPackage
35import Testing
46
@@ -100,6 +102,20 @@ import Testing
100102 try FileManager . default. removeItem ( atPath: tempFile. string)
101103 }
102104
105+ @Test ( " Test clear method removes file " )
106+ func testClearRemovesFile( ) throws {
107+ let tempFile = fs. mktemp ( ext: " .json " )
108+ let reporter = JsonFileProgressReporter ( filePath: tempFile)
109+
110+ reporter. update ( step: 1 , total: 2 , text: " Test " )
111+
112+ #expect( FileManager . default. fileExists ( atPath: tempFile. string) )
113+
114+ reporter. clear ( )
115+
116+ #expect( !FileManager. default. fileExists ( atPath: tempFile. string) )
117+ }
118+
103119 @Test ( " Test multiple progress updates create multiple lines " )
104120 func testMultipleUpdatesCreateMultipleLines( ) async throws {
105121 let tempFile = fs. mktemp ( ext: " .json " )
You can’t perform that action at this time.
0 commit comments