1 # share/pin: a plain `ez lock` refuses a `[tools.*]` pin it would have to fill. 2 # It copies every pin as the ledger has it and never asks a remote, so a pin 3 # with no commit or no NAR hash stops it, naming the upgrade that fills the 4 # pin. Filling and moving a pin is `ez lock --upgrade`'s, in lock/up.bend. 5 import Base 6 import ../ledger/manifest.bend as M 7 8 # why a plain lock cannot copy a git pin as it stands, or "" when it can. The 9 # lock copies `rev` and `narHash` out of the ledger and never asks a remote 10 # for them, so a pin missing either is refused rather than filled, and the 11 # upgrade that fills it is named. 12 def gap.git(no_rev: Bool, no_nar: Bool, +name: String) -> String: 13 match no_rev: 14 case True{}: 15 "ez: tools." ++ name ++ " has no rev; run `ez lock --upgrade --package " ++ 16 name ++ "` to pin it" 17 case False{}: 18 match no_nar: 19 case True{}: 20 "ez: tools." ++ name ++ " has no narHash; run `ez lock --upgrade --package " ++ 21 name ++ "` to pin it" 22 case False{}: 23 "" 24 25 # why a plain lock cannot copy a pin as it stands, or "" when it can. A pin 26 # with no repo has nothing to pin, under a plain lock or an upgrade. 27 def gap(pin: M.Tool) -> String: 28 M.Tool{n, _e, _b, s} = pin 29 match s: 30 case M.Hub{_named}: 31 "ez: tools." ++ n ++ " has no git" 32 case M.Git{_url, rev, _tag, _root, nar, _vend}: 33 gap.git(String.is_empty(rev), String.is_empty(nar), n) 34 case M.Member{_path, _named}: 35 "ez: tools." ++ n ++ " has no git" 36 37 # this pin's gap when it has one, otherwise the rest's. The rest arrives as a 38 # thunk and only the arm that wants it applies it, so the first gap stops the 39 # scan. 40 def gaps.step(none: Bool, here: String, rest: Unit -> String) -> String: 41 match none: 42 case True{}: 43 rest(Unit{}) 44 case False{}: 45 here 46 47 # the first pin, in ledger order, a plain lock cannot copy, or "" when it can 48 # copy every one 49 def gaps(ts: List<&2, M.Tool>) -> String: 50 match ts: 51 case []: 52 "" 53 case h <> t: 54 +here = gap(h) 55 gaps.step(String.is_empty(here), here, _u => gaps(t))