src/doctor/run.bend
ezx@1.11.0.0 · 145 lines · 13 definitions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import Base
17import snap@1.4.0.0/main.bend as R
18import ezx@1.11.0.0/src/run/bend.bend as Bend
19import ezx@1.11.0.0/src/io/file.bend as F
20import ezx@1.11.0.0/src/share/args.bend as Args
21import ezx@1.11.0.0/src/lock/run.bend as Run
22import ezx@1.11.0.0/src/lock/world.bend as W
23import ezx@1.11.0.0/src/lock/lock.bend as L
24import ezx@1.11.0.0/src/doctor/world.bend as DW
25import ezx@1.11.0.0/src/doctor/plan.bend as DP
26import ezx@1.11.0.0/src/ws/run.bend as WsRun
27import ezx@1.11.0.0/src/ws/doctor.bend as WsDoc
28
29
30
31def probe.ask(is_bend: Bool, name: String) -> IO(String):
32 match is_bend:
33 case True{}:
34 Bend.version()
35 case False{}:
36 R.exec([name, "--version"])
37
38
39
40
41def tree.read(+dir: String, +manifest: String) -> IO(DW.Answer):
42 do IO<DW.Answer>:
43 ss : List<&2, String> <- Run.disk.all(dir, L.manifest.files(String.lines(manifest)))
44 return DW.Laid{manifest, ss}
45
46
47def tree.seen(got: Maybe<&2, String>, +dir: String) -> IO(DW.Answer):
48 match got:
49 case Some{text}:
50 tree.read(dir, text)
51 case None{}:
52 IO.pure(DW.Answer, DW.Away{})
53
54
55def tree(+dir: String) -> IO(DW.Answer):
56 do IO<DW.Answer>:
57 m : Maybe<&2, String> <- F.read(dir ++ "/manifest")
58 tree.seen(m, dir)
59
60
61def answer(+lib: String, ask: DW.Ask) -> IO(DW.Answer):
62 match ask:
63 case DW.Probe{+name}:
64 do IO<DW.Answer>:
65 +out : String <- probe.ask(String.eq(name, "bend"), name)
66 return DW.Printed{R.ok(out), R.text(out)}
67 case DW.Lib{dir}:
68 do IO<DW.Answer>:
69 +out : String <- R.exec(["ls", dir])
70 return DW.Printed{R.ok(out), R.text(out)}
71 case DW.Sources{}:
72 do IO<DW.Answer>:
73 l : W.Listing <- Run.read.listing()
74 return DW.Listed{l}
75 case DW.Tree{a}:
76 tree(lib ++ "/" ++ W.ask.hash(a))
77 case DW.Name{nv}:
78 do IO<DW.Answer>:
79 m : Maybe<&2, String> <- F.read(lib ++ "/names/" ++ nv)
80 return DW.Held{m}
81
82
83def answer.all(+lib: String, asks: List<&2, DW.Ask>) -> IO(List<&2, DW.Reply>):
84 match asks:
85 case []:
86 IO.pure(List<&2, DW.Reply>, [])
87 case +h <> t:
88 do IO<List<&2, DW.Reply>>:
89 a : DW.Answer <- answer(lib, h)
90 rest : List<&2, DW.Reply> <- answer.all(lib, t)
91 return DW.Reply{h, a} <> rest
92
93
94def more(world: DW.World, rs: List<&2, DW.Reply>) -> DW.World:
95 DW.World{cc, lib, ledger, lock, replies} = world
96 DW.World{cc, lib, ledger, lock, List.append(&2, DW.Reply, replies, rs)}
97
98
99
100def loop.step(st: DP.Step, +lib: String, world: DW.World, go: DW.World -> IO(Unit)) -> IO(Unit):
101 match st:
102 case DP.Asking{asks}:
103 do IO<Unit>:
104 rs : List<&2, DW.Reply> <- answer.all(lib, asks)
105 go(more(world, rs))
106 case DP.Run{pl}:
107 Run.exec.plan("", pl)
108
109
110
111
112
113def rounds() -> Nat:
114 U32.to_nat(100000)
115
116
117
118
119def loop(fuel: Nat, +lib: String, +back: WsDoc.Back, +world: DW.World) -> IO(Unit):
120 match fuel:
121 case 0n:
122 IO.die(Unit, 1, "ez: ez doctor kept asking questions")
123 case 1n+f:
124 loop.step(WsDoc.step(back, world), lib, world, w => loop(f, lib, back, w))
125
126
127def var(name: String) -> IO(String):
128 do IO<String>:
129 r : Result<&1, &1, U32 & String, String> <- IO.get_env(name)
130 return Args.text_of(r)
131
132
133def run.doctored(dd: WsDoc.Doctored, +cc: String, +lib: String, lk: Maybe<&2, String>) -> IO(Unit):
134 WsDoc.Doctored{led, back} = dd
135 loop(rounds(), DP.lib.at(lib), back, DW.World{cc, lib, led, lk, []})
136
137
138def run() -> IO(Unit):
139 do IO<Unit>:
140 cc : String <- var("CC")
141 +lib : String <- var("BEND_LIB")
142 own : Maybe<&2, String> <- F.read(DW.toml())
143 dd : WsDoc.Doctored <- WsRun.doctor.ledger(own)
144 lk : Maybe<&2, String> <- F.read(DW.lockfile())
145 run.doctored(dd, cc, lib, lk)