1 # shake/args: the process's arguments, each word reusable, and the values of a 2 # spec's env vars, internal (main.bend exports them). `IO.args` answers a `&1` 3 # list that starts with the program as invoked (bend 2.0.32 and later); the 4 # rest of a program reads the line more than once, so `words` drops that head 5 # and copies the rest. 6 import Base 7 import ./cli.bend as C 8 9 # a &1 list copied to &2 10 def copy(xs: List<&1, String>) -> List<&2, String>: 11 match xs: 12 case Nil{}: 13 Nil{} 14 case Con{+h, t}: 15 h <> copy(t) 16 17 # the arguments of an IO.args line: every word after the program name, copied 18 def words(xs: List<&1, String>) -> List<&2, String>: 19 match xs: 20 case Nil{}: 21 Nil{} 22 case Con{_h, t}: 23 copy(t) 24 25 # the process's arguments, without the program name 26 def argv() -> IO(List<&2, String>): # noqa: L001 IO: reads argv (SHAKE-TRUST-4) 27 IO.bind(List<&1, String>, List<&2, String>, IO.args(), 28 xs => IO.pure(List<&2, String>, words(xs))) 29 30 # a name and its value in front of the pairs, when `IO.get_env` found one 31 def kept( 32 +name: String, 33 got: Result<&1, &1, U32 & String, String>, 34 rest: List<&2, C.Var> 35 ) -> List<&2, C.Var>: 36 match got: 37 case Done{vv}: 38 (name, vv) <> rest 39 case Fail{_e}: 40 rest 41 42 # the names that are set, each with its value, in order 43 def vars(names: List<&2, String>) -> IO(List<&2, C.Var>): # noqa: L001 IO: reads env vars (SHAKE-TRUST-5) 44 match names: 45 case Nil{}: 46 IO.pure(List<&2, C.Var>, []) 47 case Con{+hh, tt}: 48 IO.bind(Result<&1, &1, U32 & String, String>, List<&2, C.Var>, IO.get_env(hh), 49 got => IO.bind(List<&2, C.Var>, List<&2, C.Var>, vars(tt), 50 rest => IO.pure(List<&2, C.Var>, kept(hh, got, rest)))) 51 52 # the env vars a spec names that are set, each with its value 53 def env_vars(spec: C.Cli) -> IO(List<&2, C.Var>): # noqa: L001 IO: reads env vars (SHAKE-TRUST-5) 54 vars(C.env.names(spec))