daemon/shadowcli.bend
cswap-bend-cli@0.1.0.0 · 116 lines · 20 definitions
1import Base
2import cswap-bend-cli@0.1.0.0/fs.bend as Fs
3import cswap-bend-cli@0.1.0.0/act.bend as Act
4import cswap-bend-cli@0.1.0.0/store/base.bend as SBase
5import cswap-bend-cli@0.1.0.0/swlive.bend as L
6import cswap-bend-cli@0.1.0.0/daemon/config.bend as Cfg
7import cswap-bend-cli@0.1.0.0/daemon/shadow.bend as Sh
8
9
10
11
12
13
14type Split is Data:
15 Split{shadow: Bool, log: Maybe<&2, String>, rest: List<&2, String>}
16
17def ActM(-A: Type) -> Type:
18 Act.of(A)
19
20def ActM.pure(-A: Type, x: A) -> Act.of(A):
21 Act.pure(A, x)
22
23def ActM.bind(-A: Type, -B: Type, m: Act.of(A), f: A -> Act.of(B)) -> Act.of(B):
24 Act.bind(A, B, m, f)
25
26def sp_shadow(+s: Split) -> Bool:
27 match s:
28 case Split{sh, l, r}:
29 sh
30
31def sp_log(+s: Split) -> Maybe<&2, String>:
32 match s:
33 case Split{sh, l, r}:
34 l
35
36def sp_rest(+s: Split) -> List<&2, String>:
37 match s:
38 case Split{sh, l, r}:
39 r
40
41def keep(+a: String, +s: Split) -> Split:
42 match s:
43 case Split{sh, l, r}:
44 Split{sh, l, a <> r}
45
46def mark(+s: Split) -> Split:
47 match s:
48 case Split{sh, l, r}:
49 Split{True{}, l, r}
50
51def set_log(+v: String, +s: Split) -> Split:
52 match s:
53 case Split{sh, l, r}:
54 Split{sh, Some{v}, r}
55
56def pick(+pend: Bool, +is_sh: Bool, +is_log: Bool, +a: String, +r: Split) -> Split:
57 match pend is_sh is_log:
58 case True{} _ _:
59 set_log(a, r)
60 case False{} True{} _:
61 mark(r)
62 case False{} False{} True{}:
63 r
64 case False{} False{} False{}:
65 keep(a, r)
66
67def next_pend(+pend: Bool, +is_log: Bool) -> Bool:
68 match pend:
69 case True{}:
70 False{}
71 case False{}:
72 is_log
73
74
75def split(+xs: List<&2, String>, +pend: Bool) -> Split:
76 match xs:
77 case Nil{}:
78 Split{False{}, None{}, []}
79 case Con{a, t}:
80 pick(pend, String.eq(a, "--shadow"), String.eq(a, "--shadow-log"), a, split(t, next_pend(pend, String.eq(a, "--shadow-log"))))
81
82def settings_text(r: Fs.Res(String)) -> String:
83 match r:
84 case Fail{e}:
85 ""
86 case Done{t}:
87 t
88
89def read_settings(+ctx: SBase.Ctx) -> Act.of(String):
90 Act.lift(String, IO.bind(Fs.Res(String), String, Fs.read_file(SBase.root_of(ctx) ++ "/settings.json"), r => IO.pure(String, settings_text(r))))
91
92def flag_once(+f: Cfg.Flags) -> Bool:
93 match f:
94 case Cfg.Flags{o, j, d, th, iv, cd, st, md, ia}:
95 o
96
97def started(+ctx: SBase.Ctx, +opts: L.Opts, +log: String, +f: Cfg.Flags, +text: String) -> Act.of(U32):
98 Sh.run(Sh.Sh{ctx, Cfg.merge(Cfg.from_text(text), f), opts, log}, flag_once(f))
99
100def with_flags(+ctx: SBase.Ctx, +opts: L.Opts, +log: String, r: Result<&2, &2, String, Cfg.Flags>) -> Act.of(U32):
101 match r:
102 case Fail{msg}:
103 Act.fail(U32, 2, "cswap auto: error: " ++ msg)
104 case Done{f}:
105 Act.bind(String, U32, read_settings(ctx), t => started(ctx, opts, log, f, t))
106
107def with_log(+ctx: SBase.Ctx, +opts: L.Opts, +m: Maybe<&2, String>, +rest: List<&2, String>) -> Act.of(U32):
108 match m:
109 case None{}:
110 Act.fail(U32, 2, "cswap auto: error: --shadow needs --shadow-log PATH")
111 case Some{log}:
112 with_flags(ctx, opts, log, Cfg.parse_flags(rest))
113
114
115def run(+ctx: SBase.Ctx, +opts: L.Opts, +sp: Split) -> Act.of(U32):
116 with_log(ctx, opts, sp_log(sp), sp_rest(sp))