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 {
190
190
try self . write ( to: URL ( fileURLWithPath: path. string) , atomically: atomically, encoding: enc)
191
191
}
192
192
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
+
193
209
public init ( contentsOf path: FilePath , encoding enc: String . Encoding = . utf8) throws {
194
210
try self . init ( contentsOf: URL ( fileURLWithPath: path. string) , encoding: enc)
195
211
}
Original file line number Diff line number Diff line change 1
1
import Foundation
2
+ @testable import Swiftly
3
+ @testable import SwiftlyCore
2
4
import SystemPackage
3
5
import Testing
4
6
@@ -100,6 +102,20 @@ import Testing
100
102
try FileManager . default. removeItem ( atPath: tempFile. string)
101
103
}
102
104
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
+
103
119
@Test ( " Test multiple progress updates create multiple lines " )
104
120
func testMultipleUpdatesCreateMultipleLines( ) async throws {
105
121
let tempFile = fs. mktemp ( ext: " .json " )
You can’t perform that action at this time.
0 commit comments