Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit397007d

Browse files
committed
chore: add mutagen session state conversions
1 parentae1e3b0 commit397007d

File tree

4 files changed

+332
-21
lines changed

4 files changed

+332
-21
lines changed

‎Coder-Desktop/Coder-Desktop/Views/FileSync/FileSyncConfig.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,12 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
2020
}.width(min:200, ideal:240)
2121
TableColumn("Workspace", value: \.agentHost)
2222
.width(min:100, ideal:120)
23-
TableColumn("Remote Path", value: \.betaPath)
23+
TableColumn("Remote Path"){Text($0.betaPath).help($0.betaPath)}
2424
.width(min:100, ideal:120)
25-
TableColumn("Status"){ $0.status.body}
25+
TableColumn("Status"){ $0.status.column.help($0.statusAndErrors)}
2626
.width(min:80, ideal:100)
27-
TableColumn("Size"){ itemin
28-
Text(item.size)
29-
}
30-
.width(min:60, ideal:80)
27+
TableColumn("Size"){Text($0.maxSize.humanSizeBytes).help($0.sizeDescription)}
28+
.width(min:60, ideal:80)
3129
}
3230
.frame(minWidth:400, minHeight:200)
3331
.padding(.bottom,25)

‎Coder-Desktop/VPNLib/FileSync/FileSyncSession.swift

Lines changed: 269 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,141 @@ import SwiftUI
33
publicstructFileSyncSession:Identifiable{
44
publicletid:String
55
publicletalphaPath:String
6+
publicletname:String
7+
68
publicletagentHost:String
79
publicletbetaPath:String
810
publicletstatus:FileSyncStatus
9-
publicletsize:String
11+
12+
publicletmaxSize:FileSyncSessionEndpointSize
13+
publicletlocalSize:FileSyncSessionEndpointSize
14+
publicletremoteSize:FileSyncSessionEndpointSize
15+
16+
publicleterrors:[FileSyncError]
17+
18+
init(state:Synchronization_State){
19+
id= state.session.identifier
20+
name= state.session.name
21+
22+
// If the protocol isn't what we expect for alpha or beta, show unknown
23+
alphaPath=if state.session.alpha.protocol==Url_Protocol.local, !state.session.alpha.path.isEmpty{
24+
state.session.alpha.path
25+
}else{
26+
"Unknown"
27+
}
28+
if state.session.beta.protocol==Url_Protocol.ssh, !state.session.beta.host.isEmpty{
29+
lethost= state.session.beta.host
30+
// TOOD: We need to either:
31+
// - make this compatible with custom suffixes
32+
// - always strip the tld
33+
// - always keep the tld
34+
agentHost= host.hasSuffix(".coder")?String(host.dropLast(6)): host
35+
}else{
36+
agentHost="Unknown"
37+
}
38+
betaPath=if !state.session.beta.path.isEmpty{
39+
state.session.beta.path
40+
}else{
41+
"Unknown"
42+
}
43+
44+
varstatus:FileSyncStatus=if state.session.paused{
45+
.paused
46+
}else{
47+
convertSessionStatus(status: state.status)
48+
}
49+
if case.error= status{}else{
50+
if state.conflicts.count>0{
51+
status=.conflicts
52+
}
53+
}
54+
self.status= status
55+
56+
localSize=.init(
57+
sizeBytes: state.alphaState.totalFileSize,
58+
fileCount: state.alphaState.files,
59+
dirCount: state.alphaState.directories,
60+
symLinkCount: state.alphaState.symbolicLinks
61+
)
62+
remoteSize=.init(
63+
sizeBytes: state.betaState.totalFileSize,
64+
fileCount: state.betaState.files,
65+
dirCount: state.betaState.directories,
66+
symLinkCount: state.betaState.symbolicLinks
67+
)
68+
maxSize= localSize.maxOf(other: remoteSize)
69+
70+
errors=accumulateErrors(from: state)
71+
}
72+
73+
publicvarstatusAndErrors:String{
74+
varout="\(status.type)\n\n\(status.description)"
75+
errors.forEach{ out+="\n\t\($0)"}
76+
return out
77+
}
78+
79+
publicvarsizeDescription:String{
80+
varout=""
81+
if localSize!= remoteSize{
82+
out+="Maximum:\n\(maxSize.description(linePrefix:""))\n\n"
83+
}
84+
out+="Local:\n\(localSize.description(linePrefix:""))\n\n"
85+
out+="Remote:\n\(remoteSize.description(linePrefix:""))"
86+
return out
87+
}
88+
}
89+
90+
publicstructFileSyncSessionEndpointSize:Equatable{
91+
publicletsizeBytes:UInt64
92+
publicletfileCount:UInt64
93+
publicletdirCount:UInt64
94+
publicletsymLinkCount:UInt64
95+
96+
publicinit(sizeBytes:UInt64, fileCount:UInt64, dirCount:UInt64, symLinkCount:UInt64){
97+
self.sizeBytes= sizeBytes
98+
self.fileCount= fileCount
99+
self.dirCount= dirCount
100+
self.symLinkCount= symLinkCount
101+
}
102+
103+
func maxOf(other:FileSyncSessionEndpointSize)->FileSyncSessionEndpointSize{
104+
FileSyncSessionEndpointSize(
105+
sizeBytes:max(sizeBytes, other.sizeBytes),
106+
fileCount:max(fileCount, other.fileCount),
107+
dirCount:max(dirCount, other.dirCount),
108+
symLinkCount:max(symLinkCount, other.symLinkCount)
109+
)
110+
}
111+
112+
publicvarhumanSizeBytes:String{
113+
humanReadableBytes(sizeBytes)
114+
}
115+
116+
publicfunc description(linePrefix:String="")->String{
117+
varresult=""
118+
result+= linePrefix+ humanReadableBytes(sizeBytes)+"\n"
119+
letnumberFormatter=NumberFormatter()
120+
numberFormatter.numberStyle=.decimal
121+
iflet formattedFileCount= numberFormatter.string(from:NSNumber(value: fileCount)){
122+
result+="\(linePrefix)\(formattedFileCount) file\(fileCount==1?"":"s")\n"
123+
}
124+
iflet formattedDirCount= numberFormatter.string(from:NSNumber(value: dirCount)){
125+
result+="\(linePrefix)\(formattedDirCount) director\(dirCount==1?"y":"ies")"
126+
}
127+
if symLinkCount>0,let formattedSymLinkCount= numberFormatter.string(from:NSNumber(value: symLinkCount)){
128+
result+="\n\(linePrefix)\(formattedSymLinkCount) symlink\(symLinkCount==1?"":"s")"
129+
}
130+
return result
131+
}
10132
}
11133

12134
publicenumFileSyncStatus{
13135
case unknown
14-
case error(String)
136+
case error(FileSyncErrorStatus)
15137
case ok
16138
case paused
17-
caseneedsAttention(String)
18-
case working(String)
139+
caseconflicts
140+
case working(FileSyncWorkingStatus)
19141

20142
publicvarcolor:Color{
21143
switchself{
@@ -27,31 +149,163 @@ public enum FileSyncStatus {
27149
.red
28150
case.error:
29151
.red
30-
case.needsAttention:
152+
case.conflicts:
31153
.orange
32154
case.working:
33-
.white
155+
.purple
34156
}
35157
}
36158

37-
publicvardescription:String{
159+
publicvartype:String{
38160
switchself{
39161
case.unknown:
40162
"Unknown"
41-
caselet.error(msg):
42-
msg
163+
caselet.error(status):
164+
status.name
43165
case.ok:
44166
"Watching"
45167
case.paused:
46168
"Paused"
47-
caselet.needsAttention(msg):
48-
msg
49-
caselet.working(msg):
50-
msg
169+
case.conflicts:
170+
"Conflicts"
171+
caselet.working(status):
172+
status.name
173+
}
174+
}
175+
176+
publicvardescription:String{
177+
switchself{
178+
case.unknown:
179+
"Unknown status message."
180+
caselet.error(status):
181+
status.description
182+
case.ok:
183+
"The session is watching for filesystem changes."
184+
case.paused:
185+
"The session is paused."
186+
case.conflicts:
187+
"The session has conflicts that need to be resolved."
188+
caselet.working(status):
189+
status.description
51190
}
52191
}
53192

54-
publicvarbody:someView{
55-
Text(description).foregroundColor(color)
193+
publicvarcolumn:someView{
194+
Text(type).foregroundColor(color)
195+
}
196+
}
197+
198+
publicenumFileSyncWorkingStatus{
199+
case connectingAlpha
200+
case connectingBeta
201+
case scanning
202+
case reconciling
203+
case stagingAlpha
204+
case stagingBeta
205+
case transitioning
206+
case saving
207+
208+
varname:String{
209+
switchself{
210+
case.connectingAlpha:
211+
"Connecting (alpha)"
212+
case.connectingBeta:
213+
"Connecting (beta)"
214+
case.scanning:
215+
"Scanning"
216+
case.reconciling:
217+
"Reconciling"
218+
case.stagingAlpha:
219+
"Staging (alpha)"
220+
case.stagingBeta:
221+
"Staging (beta)"
222+
case.transitioning:
223+
"Transitioning"
224+
case.saving:
225+
"Saving"
226+
}
227+
}
228+
229+
vardescription:String{
230+
switchself{
231+
case.connectingAlpha:
232+
"The session is attempting to connect to the alpha endpoint."
233+
case.connectingBeta:
234+
"The session is attempting to connect to the beta endpoint."
235+
case.scanning:
236+
"The session is scanning the filesystem on each endpoint."
237+
case.reconciling:
238+
"The session is performing reconciliation."
239+
case.stagingAlpha:
240+
"The session is staging files on the alpha endpoint"
241+
case.stagingBeta:
242+
"The session is staging files on the beta endpoint"
243+
case.transitioning:
244+
"The session is performing transition operations on each endpoint."
245+
case.saving:
246+
"The session is recording synchronization history to disk."
247+
}
248+
}
249+
}
250+
251+
publicenumFileSyncErrorStatus{
252+
case disconnected
253+
case haltedOnRootEmptied
254+
case haltedOnRootDeletion
255+
case haltedOnRootTypeChange
256+
case waitingForRescan
257+
258+
varname:String{
259+
switchself{
260+
case.disconnected:
261+
"Disconnected"
262+
case.haltedOnRootEmptied:
263+
"Halted on root emptied"
264+
case.haltedOnRootDeletion:
265+
"Halted on root deletion"
266+
case.haltedOnRootTypeChange:
267+
"Halted on root type change"
268+
case.waitingForRescan:
269+
"Waiting for rescan"
270+
}
271+
}
272+
273+
vardescription:String{
274+
switchself{
275+
case.disconnected:
276+
"The session is unpaused but not currently connected or connecting to either endpoint."
277+
case.haltedOnRootEmptied:
278+
"The session is halted due to the root emptying safety check."
279+
case.haltedOnRootDeletion:
280+
"The session is halted due to the root deletion safety check."
281+
case.haltedOnRootTypeChange:
282+
"The session is halted due to the root type change safety check."
283+
case.waitingForRescan:
284+
"The session is waiting to retry scanning after an error during the previous scan."
285+
}
286+
}
287+
}
288+
289+
publicenumFileSyncEndpoint{
290+
case local
291+
case remote
292+
}
293+
294+
publicenumFileSyncProblemType{
295+
case scan
296+
case transition
297+
}
298+
299+
publicenumFileSyncError{
300+
case generic(String)
301+
case problem(FileSyncEndpoint,FileSyncProblemType, path:String, error:String)
302+
303+
vardescription:String{
304+
switchself{
305+
caselet.generic(error):
306+
error
307+
caselet.problem(endpoint, type, path, error):
308+
"\(endpoint)\(type) error at\(path):\(error)"
309+
}
56310
}
57311
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// swiftlint:disable:next cyclomatic_complexity
2+
func convertSessionStatus(status:Synchronization_Status)->FileSyncStatus{
3+
switch status{
4+
case.disconnected:
5+
.error(.disconnected)
6+
case.haltedOnRootEmptied:
7+
.error(.haltedOnRootEmptied)
8+
case.haltedOnRootDeletion:
9+
.error(.haltedOnRootDeletion)
10+
case.haltedOnRootTypeChange:
11+
.error(.haltedOnRootTypeChange)
12+
case.waitingForRescan:
13+
.error(.waitingForRescan)
14+
case.connectingAlpha:
15+
.working(.connectingAlpha)
16+
case.connectingBeta:
17+
.working(.connectingBeta)
18+
case.scanning:
19+
.working(.scanning)
20+
case.reconciling:
21+
.working(.reconciling)
22+
case.stagingAlpha:
23+
.working(.stagingAlpha)
24+
case.stagingBeta:
25+
.working(.stagingBeta)
26+
case.transitioning:
27+
.working(.transitioning)
28+
case.saving:
29+
.working(.saving)
30+
case.watching:
31+
.ok
32+
case.UNRECOGNIZED:
33+
.unknown
34+
}
35+
}
36+
37+
func accumulateErrors(from state:Synchronization_State)->[FileSyncError]{
38+
varerrors:[FileSyncError]=[]
39+
if !state.lastError.isEmpty{
40+
errors.append(.generic(state.lastError))
41+
}
42+
forproblemin state.alphaState.scanProblems{
43+
errors.append(.problem(.local,.scan, path: problem.path, error: problem.error))
44+
}
45+
forproblemin state.alphaState.transitionProblems{
46+
errors.append(.problem(.local,.transition, path: problem.path, error: problem.error))
47+
}
48+
forproblemin state.betaState.scanProblems{
49+
errors.append(.problem(.remote,.scan, path: problem.path, error: problem.error))
50+
}
51+
forproblemin state.betaState.transitionProblems{
52+
errors.append(.problem(.remote,.transition, path: problem.path, error: problem.error))
53+
}
54+
return errors
55+
}
56+
57+
func humanReadableBytes(_ bytes:UInt64)->String{
58+
ByteCountFormatter().string(fromByteCount:Int64(bytes))
59+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp