~/bend-docscommunity

src/lock/up.bend checks

raw source on the hub · import 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.bend as Up

lock/up: what ez lock --upgrade decides, as a pure function of what the remote said. It is the upgrade half of the planner (lock/plan.bend): it reads the ledger and the answers to its own questions, and returns either the questions it still has, a refusal, or the ledger the lock is made from and everything the upgrade writes around it. The interpreter (lock/run.bend) answers each question by IO, and the planner turns the result into effects.

A git dependency with a tag is re-resolved to that tag; one with only a commit fast-forwards to the default branch tip when the pin is an ancestor of it. A hub dependency is left, because the hash is the pin. --package selects one dependency or tool, and no other entry is asked about. A tool pin with no commit or no NAR hash is filled here and nowhere else. A moved dependency marked vendor = true has its new tree committed under .ez/lib and its old one removed, the gitignore allowlist is derived again from the ledger the upgrade leaves (I.sync), and an import that names a moved hash is rewritten. Nothing is written when the upgrade refuses: that is the planner's, since a refusal is a plan with no effects.

A same commit is checked out and weighed, and U.judge is given whether that checkout agrees with the pin, so a pinned commit whose tree no longer hashes to the pin is Drift and refused.

12 imports
import Base
import ./lock.bend as L
import ../ledger/manifest.bend as M
import ../ledger/render.bend as Rend
import ../ledger/upgrade.bend as U
import ../ledger/ignore.bend as I
import ../git/git.bend as Git
import ../pkg/pkg.bend as K
import ../pkg/path.bend as Path
import ../hub/hub.bend as Web
import ../share/sha.bend as Sha
import ../share/say.bend as Say

Types

type Ask source · line 45 · raw

Data

a question the upgrade asks, answered by one IO action. ez add (add/plan.bend) asks four of them too: Tags, Head and Refs to resolve a ref, and Clone for the checkout it walks. The upgrade asks each with the source its ledger records, and looks the answer up by that; git is asked the same question with that source anchored at the project (anchor), which the planner computes (lock/plan.bend, P.Query). ez add and ez fetch ask with the source anchored already.

type Found source · line 110 · raw

Data

one source file of the project, with its text

type Answer source · line 115 · raw

Data

the answer to one question. Git's output is kept as it was printed, with whether the command succeeded, so reading it is the planner's decision.

type Reply source · line 127 · raw

Data

one question, answered

type Laid source · line 132 · raw

Data

a tree checked out at a rev a dependency moved to: the package the lock reads for its new hash, so it is not cloned a second time

type Edit source · line 136 · raw

Data

a file the upgrade writes: ez.toml, .gitignore, or a source

type Next source · line 153 · raw

Data

what the upgrade decided. model is the ledger model the upgrade renders into ez.toml, and ez.toml as it is when the upgrade refuses, still asks, or moves nothing; the upgrade's decisions are stated over it. read is the ledger the lock is made from: the one the upgrade writes, read back, or ez.toml as it is when nothing moved. stop is why the upgrade refuses, "" when it does not; a World with questions still open refuses too, and names them in asks. The rest is what the upgrade writes around the lock: the trees it checked out, the hashes committed under .ez/lib, the lines a person is told, ez.toml and .gitignore when they change, the project's sources, which it writes where a moved hash is rewritten (edit.sources), the committed trees it removes, and the hashes import lines stop naming, each with the hash that replaces it, which the lock reads the committed sources through. The sources are rewritten once, by the plan, and not on every round of questions.

type Heard source · line 247 · raw

Data

an answer looked up, or none yet

type Said source · line 274 · raw

Data

what git printed, once it is known: the text, or why there is none, or the question still open

type Co source · line 329 · raw

Data

a checkout, once it is known

type Asc source · line 356 · raw

Data

ancestry, once it is known

type Wd source · line 383 · raw

Data

a NAR hash, once it is known

type Hubbed source · line 411 · raw

Data

the hub's word on a hash, once it is known. It stops the upgrade only when a manifest arrived under the hash and did not hash to it.

type Srcs source · line 446 · raw

Data

the project's sources, once they are known

type Tip source · line 478 · raw

Data

the commit a pin is asked to move to, the tag it came through ("" for none), and the default branch it tips ("" for a tag); or the question still open, or why there is no answer

type Fate source · line 584 · raw

Data

what one dependency became: its entry in the ledger the upgrade leaves, the committed tree to remove ("" for none), its new hash, the hash an import must stop naming ("" for none), whether it moved, what a person is told, and the tree checked out at its new rev. Or the questions still open, or why the upgrade refuses.

type Deps source · line 783 · raw

Data

every dependency after the upgrade: the ledger's entries in its order, the committed trees that moved (swaps), the hashes import lines stop naming (edits), whether any pin moved, what a person is told, the trees checked out, the questions still open, and the first refusal, "" for none

type Pinned source · line 826 · raw

Data

one tool after it was asked about, or the questions still open, or why the upgrade refuses

type Named source · line 888 · raw

Data

the ref a pin with no commit is pinned from, once it is known

type Tools source · line 1070 · raw

Data

every tool after the upgrade, as Deps is for dependencies

Definitions

def ask.url source · line 58 · raw

@ask:Ask -> String

the source a question names, "" for one that names none

def anchor source · line 86 · raw

@+here:String -> @ask:Ask -> Ask

a question as git is to be asked it: the source it names anchored at the directory here (Path.anchor), so a relative path, which the ledger keeps relative to the project, is read from the project wherever git runs. A URL and an absolute path are as they are, and a question that names no source is as it is.

def next.model source · line 158 · raw

@nx:Next -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read

def next.read source · line 162 · raw

@nx:Next -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read

def next.stop source · line 166 · raw

@nx:Next -> String

def next.asks source · line 170 · raw

@nx:Next -> List<&2, Ask>

def next.trees source · line 174 · raw

@nx:Next -> List<&2, Laid>

def next.vends source · line 178 · raw

@nx:Next -> List<&2, String>

def next.says source · line 182 · raw

@nx:Next -> List<&2, String>

def next.edits source · line 186 · raw

@nx:Next -> List<&2, Edit>

def next.found source · line 190 · raw

@nx:Next -> List<&2, Found>

def next.drops source · line 194 · raw

@nx:Next -> List<&2, String>

def next.swaps source · line 198 · raw

@nx:Next -> List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap>

def plain source · line 203 · raw

@+read:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read -> Next

a plain lock: ez.toml as it is, and nothing around it

def halt.why source · line 210 · raw

@+why:String -> String

a refusal's reason, never empty. An empty reason is no refusal at all, so an upgrade that stopped with one would otherwise go on to lock the ledger as it was, and a pin that halted with one would drop out of the ledger the upgrade writes. The interpreter never answers with an empty reason.

def stopped source · line 215 · raw

@+read:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read -> @+why:String -> @asks:List<&2, Ask> -> Next

an upgrade that refuses, or still asks: the lock is not made, and nothing is written

def key source · line 223 · raw

@ask:Ask -> String

a question as a key. A ledger value never holds a newline, so the fields are kept apart by one.

def look.step source · line 253 · raw

@hit:Bool -> @answer:Answer -> @rest:(@_:Unit -> Heard) -> Heard

this answer when it is the question's, otherwise the rest's. The rest arrives as a thunk, so the first hit ends the scan.

def look source · line 261 · raw

@rs:List<&2, Reply> -> @+want:String -> Heard

the first answer given to a question

def heard source · line 269 · raw

@rs:List<&2, Reply> -> @ask:Ask -> Heard

the answer to a question, or none yet

def printed.ok source · line 279 · raw

@ok:Bool -> @+what:String -> @text:String -> Said

def printed.of source · line 286 · raw

@answer:Answer -> @+what:String -> Said

def printed.heard source · line 296 · raw

@got:Heard -> @ask:Ask -> @+what:String -> Said

what git printed for what

def printed source · line 304 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> @+what:String -> Said

the same, looked up among the answers

def text.of source · line 308 · raw

@answer:Answer -> Said

a file's text, "" when it is missing

def text.said.heard source · line 317 · raw

@got:Heard -> @ask:Ask -> Said

def text.said source · line 325 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Said

the same, looked up among the answers

def checkout.of source · line 334 · raw

@answer:Answer -> Co

def checkout.heard source · line 344 · raw

@got:Heard -> @ask:Ask -> Co

the checkout a question was answered with

def checkout source · line 352 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Co

the same, looked up among the answers

def onward.of source · line 361 · raw

@answer:Answer -> Asc

def onward.heard source · line 371 · raw

@got:Heard -> @ask:Ask -> Asc

the ancestry a question was answered with

def onward source · line 379 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Asc

the same, looked up among the answers

def weighed.of source · line 388 · raw

@answer:Answer -> Wd

def weighed.heard source · line 398 · raw

@got:Heard -> @ask:Ask -> Wd

the NAR hash a question was answered with

def weighed source · line 406 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Wd

the same, looked up among the answers

def hub.got source · line 417 · raw

@got:0x886223f5c47e4983fe57d887c034bc7f/src/hub/hub.Got -> Hubbed

def hub.of source · line 424 · raw

@answer:Answer -> Hubbed

def hubbed.heard source · line 434 · raw

@got:Heard -> @ask:Ask -> Hubbed

the hub's word a question was answered with

def hubbed source · line 442 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Hubbed

the same, looked up among the answers

def sources.of source · line 451 · raw

@answer:Answer -> Srcs

def sources.heard source · line 461 · raw

@got:Heard -> @ask:Ask -> Srcs

the sources a question was answered with

def sources source · line 469 · raw

@rs:List<&2, Reply> -> @+ask:Ask -> Srcs

the same, looked up among the answers

def follow.rev source · line 485 · raw

@+rev:String -> @+url:String -> @+ref:String -> Tip

the commit the rows name for a ref. A ref the remote does not have is a mistake worth naming.

def follow.said source · line 489 · raw

@said:Said -> @+url:String -> @+ref:String -> Tip

def follow.ask source · line 498 · raw

@pinned:Bool -> @+rs:List<&2, Reply> -> @+url:String -> @+ref:String -> Tip

def follow source · line 507 · raw

@+rs:List<&2, Reply> -> @+url:String -> @+ref:String -> Tip

the commit a ref names, as Git.resolve reads it: a 40-hex ref is a commit already, and asks the remote nothing

def forward.rev source · line 511 · raw

@+rev:String -> @branch:String -> @+url:String -> Tip

a remote with no HEAD is not one an upgrade can move

def forward.said source · line 515 · raw

@said:Said -> @+url:String -> Tip

def forward source · line 526 · raw

@+rs:List<&2, Reply> -> @+url:String -> Tip

the commit the default branch tips, and its name

def tip.of source · line 530 · raw

@+branch:String -> @+tip:String -> String

the word Off quotes: a branch name when there is one, otherwise the commit

def off.why source · line 535 · raw

@+name:String -> @+tag:String -> @+pin:String -> @+tip:String -> String

a tag that moved off the pin's history, or a branch tip that does not descend from a rev-only pin

def branch.of source · line 541 · raw

@+label:String -> String

the branch a rev-only pin followed, said when there is one

def say.move source · line 545 · raw

@+name:String -> @+old:String -> @+new:String -> @+branch:String -> String

a line saying a pin moved

def hash.of source · line 549 · raw

@+manifest:String -> String

the 0x name a manifest is the digest of

def hash.kept.or source · line 553 · raw

@same:Bool -> @+bare:String -> @+full:String -> String

the bare checkout's hash when it is the pin's, and the walk's otherwise

def hash.kept.pick source · line 560 · raw

@same:Bool -> @+pin:String -> @+full:String -> @+manifest:String -> String

def hash.kept source · line 572 · raw

@+pin:String -> @+manifest:String -> String

the hash a pinned commit's checkout has, by the rule the pin was taken by: the walk's, or, for a pin written before bend 2.0.27 took the LICENSE files along, the same checkout's without them. A pin that is neither is a drift, and names the walk's hash.

def stay source · line 591 · raw

@dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @says:List<&2, String> -> Fate

a dependency left as it was

def swap.hash source · line 595 · raw

@same:Bool -> @+old:String -> String

the old hash, or "" when it did not change

def swap.of source · line 603 · raw

@vend:Bool -> @+old:String -> @+new:String -> String

a committed tree whose hash changed is a tree to remove

def line.if source · line 611 · raw

@say:Bool -> @+text:String -> List<&2, String>

a line, only when there is something to say

def dep.moved source · line 617 · raw

@+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+hash:String -> @+rev:String -> @+root:String -> @+nar:String -> @manifest:String -> @srcs:List<&2, String> -> @+branch:String -> Fate

a moved pin, once the hub has not objected to its new hash: the ledger's entry retargeted, the committed tree it replaces, the hash imports stop naming, and what a person is told

def dep.hub source · line 640 · raw

@hubbed:Hubbed -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+hash:String -> @+rev:String -> @+root:String -> @+nar:String -> @manifest:String -> @srcs:List<&2, String> -> @+branch:String -> Fate

the hub's word on the new hash

def dep.advance source · line 663 · raw

@co:Co -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+rev:String -> @+branch:String -> Fate

the checkout at the rev the pin advances to, then the hub asked about the hash it has. The hub a moved hash is checked against is the ledger's.

def dep.verdict source · line 676 · raw

@verdict:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Verdict -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+tip:String -> @+branch:String -> @+seen:String -> Fate

the verdict. seen is the hash the pinned commit's checkout has, which a drift names; "" when the commit moved and the pin was not checked out.

def dep.kept source · line 701 · raw

@co:Co -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+tip:String -> @+tag:String -> Fate

the pinned commit's checkout, judged with whether it agrees with the pin: the same hash, NAR hash and root. One that does not is a drift.

def dep.onward source · line 716 · raw

@asc:Asc -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+tip:String -> @+tag:String -> @+branch:String -> Fate

a different commit, once ancestry is known. The commit moved, so no checkout at the pin was weighed and none agrees with it.

def dep.same source · line 736 · raw

@same:Bool -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> @+tip:String -> @+tag:String -> @+branch:String -> Fate

the same commit is checked out to be weighed; a different one is asked whether it descends from the pin

def dep.tip source · line 754 · raw

@tip:Tip -> @+rs:List<&2, Reply> -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> Fate

the commit the remote names, against the pin

def dep.hold source · line 766 · raw

@sel:Bool -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> Fate

a hub pin named with --package is reported and left. An unselected dependency is left quietly.

def dep.one source · line 770 · raw

@aim:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Aim -> @+rs:List<&2, Reply> -> @+only:String -> @+hub:String -> @+dep:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep -> Fate

one dependency, by what it is asked

def swaps.put source · line 789 · raw

@empty:Bool -> @+old:String -> @+new:String -> @rest:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap> -> List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap>

a moved hash, kept only when there is one

def deps.join source · line 798 · raw

@fate:Fate -> @rest:Deps -> Deps

one dependency in front of the rest. A refusal ahead of the rest wins, so the first in ledger order is the one given.

def deps.walk source · line 813 · raw

@+rs:List<&2, Reply> -> @+only:String -> @+hub:String -> @ds:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep> -> Deps

every dependency, in the order the ledger wrote them

def set.go source · line 834 · raw

@+name:String -> @+entry:String -> @+bin:String -> @source:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Source -> @+rev:String -> @+tag:String -> @+nar:String -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool

the pin with a commit and a NAR hash written in. An empty tag leaves the one the ledger already had. The vendor bit is off: a tool is not committed under .ez/lib.

def set source · line 852 · raw

@tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+rev:String -> @+tag:String -> @+nar:String -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool

a tool's pin with a commit, a tag and a NAR hash written in

def tool.pin source · line 859 · raw

@short:Bool -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+rev:String -> @+tag:String -> @+nar:String -> @says:List<&2, String> -> Pinned

a commit and its NAR hash written into the pin. A pin with either one empty is short, and an upgrade that wrote one would fill it again on the next run, so a weighing that names no commit or no NAR hash pins nothing.

def tool.weighed source · line 867 · raw

@wd:Wd -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+rev:String -> @+tag:String -> @says:List<&2, String> -> Pinned

a commit weighed, then written into the pin

def tool.resolved source · line 878 · raw

@tip:Tip -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+ref:String -> Pinned

the commit a ref named, weighed. The pin records the ref as its tag, even one that names a commit, so the next upgrade asks about the same ref.

def heads.branch source · line 894 · raw

@+name:String -> @+url:String -> Named

a remote whose HEAD names no branch leaves nothing to pin

def heads.said source · line 900 · raw

@said:Said -> @+url:String -> Named

def tags.best source · line 910 · raw

@none:Bool -> @+best:String -> @+rs:List<&2, Reply> -> @+url:String -> Named

the greatest semver-ish tag, else the default branch

def tags.said source · line 917 · raw

@said:Said -> @+rs:List<&2, Reply> -> @+url:String -> Named

def tool.default source · line 929 · raw

@+rs:List<&2, Reply> -> @+url:String -> Named

the ref ez add pins when none was asked for: the greatest semver-ish release tag, else the greatest pre-release, else the default branch

def tool.ref source · line 933 · raw

@no_tag:Bool -> @+rs:List<&2, Reply> -> @+url:String -> @+tag:String -> Named

the ref to resolve: the tag the ledger named, or the default ref

def tool.named source · line 940 · raw

@named:Named -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+url:String -> Pinned

def tool.verdict source · line 952 · raw

@verdict:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Verdict -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+tip:String -> @+branch:String -> Pinned

the verdict on a full pin. A pin that moves keeps its own tag, as a dependency does: the tip was named by that tag, or by the default branch for a pin with none.

def tool.kept.nar source · line 971 · raw

@fill:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+tip:String -> @+tag:String -> @+nar:String -> Pinned

the pinned commit weighed: its NAR hash written in when the pin has none, else judged with whether it is the one the pin records

def tool.kept source · line 980 · raw

@wd:Wd -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+tip:String -> @+tag:String -> Pinned

the pinned commit weighed again

def tool.onward source · line 989 · raw

@asc:Asc -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+tip:String -> @+tag:String -> @+branch:String -> Pinned

def tool.same source · line 998 · raw

@same:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> @+tip:String -> @+tag:String -> @+branch:String -> Pinned

def tool.tip source · line 1007 · raw

@tip:Tip -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

def tool.aim source · line 1018 · raw

@aim:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Aim -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

a full pin, re-asked: its tag re-resolved, or the default branch followed

def tool.fill source · line 1032 · raw

@no_rev:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

a pin with no commit is resolved from its tag, or the default ref, then weighed. One with a commit and no NAR hash is upgraded as a full pin is, and its NAR hash is written in wherever it lands: filled at its own commit only, it would move on the next upgrade, which follows its tag or the default branch.

def tool.short source · line 1044 · raw

@short:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

a selected pin with no commit or no NAR hash is filled; a full one is asked whether it moved

def tool.git source · line 1052 · raw

@git:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

a selected tool names a repo, or it cannot be pinned

def tool.sel source · line 1062 · raw

@sel:Bool -> @+rs:List<&2, Reply> -> @+tool:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool -> Pinned

a selected tool is asked; the others are left

def tools.join source · line 1074 · raw

@pinned:Pinned -> @rest:Tools -> Tools

def tools.walk source · line 1087 · raw

@+rs:List<&2, Reply> -> @+only:String -> @ts:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Tool> -> Tools

every tool, in the order the ledger wrote them

def edit.toml source · line 1100 · raw

@moved:Bool -> @+text:String -> @rest:List<&2, Edit> -> List<&2, Edit>

ez.toml, only when a pin moved, so an upgrade that changed nothing does not reformat the file

def edit.if source · line 1108 · raw

@same:Bool -> @+at:String -> @+text:String -> @rest:List<&2, Edit> -> List<&2, Edit>

a file, only when its text changes

def edit.sources source · line 1117 · raw

@fs:List<&2, Found> -> @+es:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap> -> List<&2, Edit>

every source with each moved hash rewritten in its imports, written only when that changes it

def drops.of source · line 1126 · raw

@ss:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap> -> List<&2, String>

every committed tree that moved, removed

def read.next source · line 1135 · raw

@moved:Bool -> @+text:String -> @old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read

the ledger the lock is made from: the one the upgrade writes, read back, or ez.toml as it was when nothing moved

def model.next source · line 1143 · raw

@moved:Bool -> @next:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read

the ledger model the upgrade renders, or ez.toml's when nothing moved

def fit.why source · line 1154 · raw

@moved:Bool -> @next:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> String

why an upgrade that moved a pin stops, "" when it does not: the ledger it would write cannot be written so that it reads back as the model it renders (EZ-LED-4), so it is refused, with no effect, rather than written as something else

def done source · line 1162 · raw

@+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @dd:Deps -> @tt:Tools -> @+ignore:String -> @fs:List<&2, Found> -> Next

every answer in: the ledger, the allowlist and the imports, and the trees

def open.srcs source · line 1183 · raw

@srcs:Srcs -> List<&2, Ask>

the question still open, when one is

def got.srcs source · line 1191 · raw

@srcs:Srcs -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @dd:Deps -> @tt:Tools -> @+ignore:String -> Next

the sources, once the ignore file is known

def got.ignore source · line 1201 · raw

@said:Said -> @+srcs:Srcs -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @dd:Deps -> @tt:Tools -> Next

the ignore file, then the sources

def ask.srcs source · line 1212 · raw

@none:Bool -> @+rs:List<&2, Reply> -> Srcs

the sources are read only when an import has a hash to stop naming

def deps.edits source · line 1219 · raw

@dd:Deps -> List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/upgrade.Swap>

def settled source · line 1224 · raw

@+rs:List<&2, Reply> -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @+dd:Deps -> @tt:Tools -> Next

every pin answered: what is written around the lock

def pins.asks source · line 1229 · raw

@asks:List<&2, Ask> -> @+rs:List<&2, Reply> -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @dd:Deps -> @tt:Tools -> Next

the pins' questions still open: the lock waits for them

def pins.bad source · line 1237 · raw

@clean:Bool -> @+bad:String -> @asks:List<&2, Ask> -> @+rs:List<&2, Reply> -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> @dd:Deps -> @tt:Tools -> Next

a refusal wins over every question still open

def pins source · line 1253 · raw

@dd:Deps -> @tt:Tools -> @+rs:List<&2, Reply> -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> Next

the dependencies' and the tools' answers together

def known source · line 1262 · raw

@ok:Bool -> @+only:String -> @+rs:List<&2, Reply> -> @+old:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Manifest -> Next

--package has to name a dependency or a pinned CLI

def next source · line 1272 · raw

@+only:String -> @read:0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Read -> @+rs:List<&2, Reply> -> Next

ez lock --upgrade [--package only] over the ledger and the answers so far. A ledger that does not parse is the plain lock's refusal.