1 # remove/run: the interpreter for `ez remove`. It reads the directory it runs 2 # in, ez.toml, `.gitignore` and the `.bend` files git lists into a World, then 3 # loops: it asks the planner (remove/relock.bend) what the lock after the 4 # remove still needs, answers each question with the lock's interpreter 5 # (`Run.answer.all`), and adds the answers to the World, until nothing is 6 # left to ask. Then it runs the plan with the lock's effect runner 7 # (`Run.exec.plan`), which exits 1 with the reason when the plan refuses. It 8 # decides nothing; that it reads and executes faithfully is EZ-TRUST-2. 9 import Base 10 import 0x8e26a6f8c31689519e618374376ee3dd/main.bend as R 11 import ../io/file.bend as F 12 import ../lock/run.bend as Run 13 import ../lock/world.bend as W 14 import ./plan.bend as RP 15 import ./relock.bend as RR 16 import ../ws/relock.bend as Rel 17 import ../ws/run.bend as WsRun 18 19 # the World with more of the lock's answers in it 20 def more(world: RR.World, rs: List<&2, W.Reply>) -> RR.World: 21 RR.World{r, here, listing, locks} = world 22 RR.World{r, here, listing, List.append(&2, W.Reply, locks, rs)} 23 24 # the planner's step: its questions answered and the loop gone round again, 25 # or its plan run 26 def loop.step(st: RR.Next, +lib: String, world: RR.World, go: RR.World -> IO(Unit)) -> IO(Unit): 27 match st: 28 case RR.AskLock{asks}: 29 do IO: 30 rs : List<&2, W.Reply> <- Run.answer.all(lib, asks) 31 go(more(world, rs)) 32 case RR.Planned{pl}: 33 Run.exec.plan(lib, pl) 34 35 # the loop, under fuel. Every round adds an answer, since the lock never asks 36 # what the World answers already, so the fuel (`Run.rounds`) is only a guard. 37 def loop(fuel: Nat, +lib: String, +ws: Rel.Ws, +world: RR.World) -> IO(Unit): 38 match fuel: 39 case 0n: 40 IO.die(Unit, 1, "ez: ez remove kept asking questions") 41 case 1n+f: 42 loop.step(Rel.remove.next(ws, world), lib, world, w => loop(f, lib, ws, w)) 43 44 # `ez remove ` 45 def run(+name: String) -> IO(Unit): 46 do IO: 47 lib : String <- Run.bend.lib() 48 +pwd : String <- R.exec(["pwd"]) 49 led : Maybe<&2, String> <- F.read(RP.toml()) 50 ig : Maybe<&2, String> <- F.read(RP.ignore.file()) 51 ls : W.Listing <- Run.read.listing() 52 ws : Rel.Ws <- WsRun.relock.ws() 53 loop(Run.rounds(), lib, ws, RR.World{RP.World{name, led, F.text_of(ig)}, 54 String.trim(R.text(pwd)), ls, []})