src/ws/pin.bend
ezx@1.10.0.0 · 57 lines · 0 definitions
1# ws/pin: the ref `ez add` in a workspace member takes (EZ-WS-4). A git source
2# has one pin across a workspace, so a member adding a source another member
3# already records takes that pin: with no ref, the tag it records, or its
4# commit when it records none; with the tag or commit it records, that; with
5# any other ref, nothing, since moving the source is an upgrade of every
6# member that records it. A source no member records, and a hub package, take
7# the ref as it was given.
8import Base
9import ezx@1.10.0.0/src/ledger/manifest.bend as M
10import ezx@1.10.0.0/src/pkg/path.bend as P
11import ezx@1.10.0.0/src/ez/target.bend as Tgt
12import ezx@1.10.0.0/src/add/world.bend as A
13import ezx@1.10.0.0/src/ws/joint.bend as J
14
15# the ref an add goes on with, or why it stops
16type Ref is Data:
17 Given{ref: String}
18 Held{why: String}
19
20# the ref the workspace pins a source at: its tag, or its commit when it has
21# no tag
22def held(+rev: String, +tag: String) -> String:
23 Bool.pick(String, String.is_empty(tag), rev, tag)
24
25# a ref given against the pin the workspace records for the source
26def ref.pinned(+url: String, +rev: String, +tag: String, +ref: String) -> Ref:
27 Bool.pick(Ref, String.is_empty(ref), Given{held(rev, tag)},
28 Bool.pick(Ref, Bool.or(String.eq(ref, tag), String.eq(ref, rev)), Given{ref},
29 Held{"ez: the workspace pins " ++ url ++ " at " ++ held(rev, tag) ++
30 "; move it for every member with ez lock --upgrade --package"}))
31
32# a ref given against what the workspace records for the source, if anything
33def ref.at(src: M.Source, +url: String, +ref: String) -> Ref:
34 match src:
35 case M.Hub{_nv}:
36 Given{ref}
37 case M.Git{_u, +rev, +tag, _o, _n, _v}:
38 ref.pinned(url, rev, tag, ref)
39 case M.Member{_p, _n}:
40 Given{ref}
41
42# a place's ref: a git source's against the workspace's pins, as the root
43# reads the source from the member's directory, and anything else as given
44def ref.place(place: Tgt.Place, +pins: List<&2, M.Dep>, +dir: String, +home: String, +ref: String) -> Ref:
45 match place:
46 case Tgt.Bad{_why}:
47 Given{ref}
48 case _:
49 +url = P.anchor(dir, A.url.of(place, home))
50 ref.at(J.pin.of(pins, url), url, ref)
51
52# the ref `ez add <target> [ref]` in a member goes on with: `pins` is every
53# dependency of the workspace's joint ledger and `dir` the member's directory
54# from the root. A hub package, added by its `<name>@<version>`, has no ref.
55def ref(+pins: List<&2, M.Dep>, +dir: String, +home: String, +target: String, +ref: String) -> Ref:
56 Bool.pick(Ref, Tgt.aim.named(Tgt.aim(target)), Given{ref},
57 ref.place(Tgt.classify(target), pins, dir, home, ref))