src/ws/relock.bend
ezx@1.11.0.0 · 428 lines · 46 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import Base
17import ezx@1.11.0.0/src/lock/plan.bend as LP
18import ezx@1.11.0.0/src/lock/world.bend as LW
19import ezx@1.11.0.0/src/lock/lock.bend as L
20import ezx@1.11.0.0/src/ledger/manifest.bend as M
21import ezx@1.11.0.0/src/ledger/render.bend as Rend
22import ezx@1.11.0.0/src/pkg/path.bend as P
23import ezx@1.11.0.0/src/relock/relock.bend as R
24import ezx@1.11.0.0/src/add/world.bend as A
25import ezx@1.11.0.0/src/add/plan.bend as AP
26import ezx@1.11.0.0/src/add/relock.bend as AR
27import ezx@1.11.0.0/src/remove/plan.bend as RP
28import ezx@1.11.0.0/src/remove/relock.bend as RR
29import ezx@1.11.0.0/src/ws/workspace.bend as W
30import ezx@1.11.0.0/src/ws/joint.bend as J
31import ezx@1.11.0.0/src/ws/up.bend as U
32
33
34
35
36
37type Rooted is Data:
38 Rooted{
39 at: String,
40 rel: List<&2, String>,
41 text: String,
42 found: List<&2, J.Found>,
43 listing: LW.Listing,
44 lock: String
45 }
46
47
48type Ws is Data:
49 Own{}
50 Inside{root: Rooted}
51
52
53def rooted.at(root: Rooted) -> String:
54 Rooted{at, _rel, _text, _found, _listing, _lock} = root
55 at
56
57
58
59
60
61
62
63def at.place(+at: String, place: LP.Place) -> LP.Place:
64 match place:
65 case LP.Committed{}:
66 LP.Under{at}
67 case LP.Cache{}:
68 LP.Cache{}
69 case LP.Under{dir}:
70 LP.Under{P.join(at, dir)}
71
72
73
74
75def at.effect(+at: String, effect: LP.Effect) -> LP.Effect:
76 match effect:
77 case LP.Write{path, text}:
78 LP.Write{P.join(at, path), text}
79 case LP.Lay{place, hash, files}:
80 LP.Lay{at.place(at, place), hash, files}
81 case LP.Drop{hash}:
82 LP.Lay{LP.Under{at}, hash, []}
83 case LP.Say{text}:
84 LP.Say{text}
85 case LP.Name{nv, hash}:
86 LP.Name{nv, hash}
87
88
89def at.effects(+at: String, es: List<&2, LP.Effect>) -> List<&2, LP.Effect>:
90 match es:
91 case []:
92 []
93 case hd <> tl:
94 at.effect(at, hd) <> at.effects(at, tl)
95
96
97def at.plan(+at: String, pl: LP.Plan) -> LP.Plan:
98 LP.Plan{es, outcome} = pl
99 LP.Plan{at.effects(at, es), outcome}
100
101
102
103
104
105
106def keep.parsed(rd: M.Read, +spec: W.Spec, root: W.Root, +text: String) -> String:
107 match rd:
108 case M.Good{mm}:
109 U.root.text(mm, spec, root)
110 case M.Bad{_why}:
111 text
112
113
114
115def keep.read(rd: W.Read, +old: String, +text: String) -> String:
116 match rd:
117 case W.Root{+spec}:
118 keep.parsed(M.parse(text), spec, W.root.of(old), text)
119 case W.Lone{}:
120 text
121 case W.Bad{_why}:
122 text
123
124
125def keep(+old: String, +text: String) -> String:
126 keep.read(W.spec.of(old), old, text)
127
128
129def keep.write(hit: Bool, +old: String, +path: String, +text: String) -> LP.Effect:
130 match hit:
131 case True{}:
132 LP.Write{path, keep(old, text)}
133 case False{}:
134 LP.Write{path, text}
135
136
137def keep.effect(+old: String, effect: LP.Effect) -> LP.Effect:
138 match effect:
139 case LP.Write{+path, text}:
140 keep.write(String.eq(path, R.toml()), old, path, text)
141 case LP.Lay{place, hash, files}:
142 LP.Lay{place, hash, files}
143 case LP.Drop{hash}:
144 LP.Drop{hash}
145 case LP.Say{text}:
146 LP.Say{text}
147 case LP.Name{nv, hash}:
148 LP.Name{nv, hash}
149
150
151def keep.effects(+old: String, es: List<&2, LP.Effect>) -> List<&2, LP.Effect>:
152 match es:
153 case []:
154 []
155 case hd <> tl:
156 keep.effect(old, hd) <> keep.effects(old, tl)
157
158
159
160
161def edit.at(rel: List<&2, String>, +old: String, pl: LP.Plan) -> LP.Plan:
162 match rel:
163 case []:
164 LP.Plan{es, outcome} = pl
165 LP.Plan{keep.effects(old, es), outcome}
166 case _hd <> _tl:
167 pl
168
169
170def edit(root: Rooted, pl: LP.Plan) -> LP.Plan:
171 Rooted{_at, rel, text, _found, _listing, _lock} = root
172 edit.at(rel, text, pl)
173
174
175
176
177
178type Ledgers is Data:
179 Ledgers{text: String, found: List<&2, J.Found>}
180
181
182def put.pick(hit: Bool, +path: String, was: String, +text: String, rest: List<&2, J.Found>) -> List<&2, J.Found>:
183 match hit:
184 case True{}:
185 J.Found{path, text} <> rest
186 case False{}:
187 J.Found{path, was} <> rest
188
189
190def put.found(fs: List<&2, J.Found>, +path: String, +text: String) -> List<&2, J.Found>:
191 match fs:
192 case []:
193 []
194 case J.Found{+fp, ft} <> tl:
195 rest = put.found(tl, path, text)
196 put.pick(String.eq(fp, path), fp, ft, text, rest)
197
198
199
200def ledgers.at(rel: List<&2, String>, +new: String, +text: String, +fs: List<&2, J.Found>) -> Ledgers:
201 match rel:
202 case []:
203 Ledgers{new, fs}
204 case hd <> tl:
205 Ledgers{text, put.found(fs, P.join(W.segs.text(hd <> tl), R.toml()), new)}
206
207
208
209def new.of(led: Maybe<&2, String>) -> String:
210 match led:
211 case None{}:
212 ""
213 case Some{text}:
214 text
215
216
217
218def ledgers(root: Rooted, pl: LP.Plan, was: Maybe<&2, String>) -> Ledgers:
219 Rooted{_at, rel, +text, fs, _listing, _lock} = root
220 ledgers.at(rel, new.of(R.ledger(pl, was)), text, fs)
221
222
223
224
225
226
227type Lock is Data:
228 Lock{back: U.Back, world: LW.World}
229 Stop{why: String}
230
231
232def world(+at: String, led: Maybe<&2, String>, listing: LW.Listing, rs: List<&2, LW.Reply>) -> LW.World:
233 LW.World{LW.Args{False{}, "", at}, led, listing, rs, []}
234
235
236
237def lock.joint(
238 jj: J.Joint,
239 +at: String,
240 +text: String,
241 +spec: W.Spec,
242 +fs: List<&2, J.Found>,
243 +listing: LW.Listing,
244 +lock: String,
245 rs: List<&2, LW.Reply>
246) -> Lock:
247 match jj:
248 case J.Lone{}:
249 Lock{U.Alone{}, world(at, Some{text}, listing, rs)}
250 case J.Clash{why}:
251 Stop{why}
252 case J.Joint{+mm}:
253 Lock{U.Back{text, spec, fs, lock},
254 world(at, Some{Rend.show(mm)}, listing,
255 List.append(&2, LW.Reply, J.seeds(J.Joint{mm}, J.files(listing)), rs))}
256
257
258def lock.read(
259 rd: W.Read,
260 +at: String,
261 +text: String,
262 +fs: List<&2, J.Found>,
263 +listing: LW.Listing,
264 +lock: String,
265 rs: List<&2, LW.Reply>
266) -> Lock:
267 match rd:
268 case W.Lone{}:
269 Lock{U.Alone{}, world(at, Some{text}, listing, rs)}
270 case W.Bad{why}:
271 Stop{why}
272 case W.Root{+spec}:
273 lock.joint(J.joint(text, fs, J.files(listing)), at, text, spec, fs, listing, lock, rs)
274
275
276def lock.of(lg: Ledgers, root: Rooted, rs: List<&2, LW.Reply>) -> Lock:
277 Ledgers{+text, +fs} = lg
278 Rooted{+at, _rel, _text, _found, +listing, +lock} = root
279 lock.read(W.spec.of(text), at, text, fs, listing, lock, rs)
280
281
282def stop(+why: String) -> LP.Plan:
283 LP.Plan{[], LP.Refused{why}}
284
285
286def lock.plan(lk: Lock) -> LP.Plan:
287 match lk:
288 case Lock{back, +world}:
289 U.plan(back, world)
290 case Stop{why}:
291 stop(why)
292
293
294def lock.step(lk: Lock) -> LP.Step:
295 match lk:
296 case Lock{+back, +world}:
297 U.step(back, world)
298 case Stop{why}:
299 LP.Run{stop(why)}
300
301
302def lock.packs(lk: Lock) -> List<&2, L.Pack>:
303 match lk:
304 case Lock{_back, +world}:
305 LP.packs(world)
306 case Stop{_why}:
307 []
308
309
310
311
312
313def add.edit(+root: Rooted, +aw: A.World) -> LP.Plan:
314 edit(root, AP.command(aw))
315
316
317
318def add.lock(+root: Rooted, world: AR.World) -> Lock:
319 AR.World{+aw, _listing, locks} = world
320 lock.of(ledgers(root, add.edit(root, aw), A.ledger(aw)), root,
321 List.append(&2, LW.Reply, AR.seeds(aw), locks))
322
323
324def add.notes(+lk: Lock, +aw: A.World) -> List<&2, LP.Effect>:
325 AR.notes.of(AR.held(lock.packs(lk), AR.added(aw)), AR.added(aw))
326
327
328
329def add.plan(+root: Rooted, world: AR.World) -> LP.Plan:
330 AR.World{+aw, +listing, +locks} = world
331 +lk = add.lock(root, AR.World{aw, listing, locks})
332 R.join(add.edit(root, aw), at.plan(rooted.at(root), lock.plan(lk)), add.notes(lk, aw), AR.tail(aw))
333
334
335def add.next.lock(st: LP.Step, +root: Rooted, +world: AR.World) -> AR.Next:
336 match st:
337 case LP.Asking{as, ups, ns}:
338 AR.AskLock{R.asks(LP.Asking{as, ups, ns})}
339 case LP.Run{_pl}:
340 AR.Planned{add.plan(root, world)}
341
342
343def add.next.made(refused: Bool, +root: Rooted, +world: AR.World) -> AR.Next:
344 match refused:
345 case True{}:
346 AR.Planned{add.plan(root, world)}
347 case False{}:
348 add.next.lock(lock.step(add.lock(root, world)), root, world)
349
350
351def add.next.add(nx: AP.Next, +root: Rooted, +world: AR.World) -> AR.Next:
352 match nx:
353 case AP.AskGit{asks}:
354 AR.AskGit{asks}
355 case AP.AskHub{asks}:
356 AR.AskHub{asks}
357 case AP.Planned{pl}:
358 add.next.made(R.refuses(pl), root, world)
359
360
361
362def add.next(ws: Ws, +world: AR.World) -> AR.Next:
363 match ws:
364 case Own{}:
365 AR.next(world)
366 case Inside{+root}:
367 add.next.add(AP.next(AR.add(world)), root, world)
368
369
370def add.planned(ws: Ws, world: AR.World) -> LP.Plan:
371 match ws:
372 case Own{}:
373 AR.plan(world)
374 case Inside{+root}:
375 add.plan(root, world)
376
377
378
379
380
381def remove.edit(+root: Rooted, +rw: RP.World) -> LP.Plan:
382 edit(root, RP.plan(rw))
383
384
385def remove.lock(+root: Rooted, world: RR.World) -> Lock:
386 RR.World{+rw, _here, _listing, locks} = world
387 lock.of(ledgers(root, remove.edit(root, rw), RR.ledger.was(rw)), root, locks)
388
389
390
391def remove.plan(+root: Rooted, world: RR.World) -> LP.Plan:
392 RR.World{+rw, +here, +listing, +locks} = world
393 +lk = remove.lock(root, RR.World{rw, here, listing, locks})
394 R.join(remove.edit(root, rw), at.plan(rooted.at(root), lock.plan(lk)), [], RR.tail())
395
396
397def remove.next.lock(st: LP.Step, +root: Rooted, +world: RR.World) -> RR.Next:
398 match st:
399 case LP.Asking{as, ups, ns}:
400 RR.AskLock{R.asks(LP.Asking{as, ups, ns})}
401 case LP.Run{_pl}:
402 RR.Planned{remove.plan(root, world)}
403
404
405def remove.next.made(refused: Bool, +root: Rooted, +world: RR.World) -> RR.Next:
406 match refused:
407 case True{}:
408 RR.Planned{remove.plan(root, world)}
409 case False{}:
410 remove.next.lock(lock.step(remove.lock(root, world)), root, world)
411
412
413
414
415def remove.next(ws: Ws, +world: RR.World) -> RR.Next:
416 match ws:
417 case Own{}:
418 RR.next(world)
419 case Inside{+root}:
420 remove.next.made(R.refuses(RP.plan(RR.remove(world))), root, world)
421
422
423def remove.planned(ws: Ws, world: RR.World) -> LP.Plan:
424 match ws:
425 case Own{}:
426 RR.plan(world)
427 case Inside{+root}:
428 remove.plan(root, world)