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. 8 import Base 9 import ../ledger/manifest.bend as M 10 import ../pkg/path.bend as P 11 import ../ez/target.bend as Tgt 12 import ../add/world.bend as A 13 import ./joint.bend as J 14 15 # the ref an add goes on with, or why it stops 16 type 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 22 def 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 26 def 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 33 def 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 44 def 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 [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 `@`, has no ref. 55 def 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))