src/share/pin.bend

ezx@1.11.0.0 · 55 lines · 4 definitions

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.
5import Base
6import ezx@1.11.0.0/src/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.
12def 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.
27def 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.
40def 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
49def 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))