src/lock/run.bend fails
raw source on the hub · import 0x886223f5c47e4983fe57d887c034bc7f/src/lock/run.bend as Run
lock/run: the interpreter for ez lock. It reads the ledger and the
committed sources into a World, then loops: it asks the planner
(lock/plan.bend) what is still open, answers each question by IO, and adds
the answers to the World, until nothing is left to ask. Then it runs the
planner's plan. It decides nothing: which packages to read, whether their
bytes are the ones the ledger names, where an upgrade moves a pin, and what
is written are the planner's. That it reads and executes faithfully is
EZ-TRUST-2. It answers a name's question by asking the hub once, and the
lock's by reading ez.lock.toml. Under --upgrade it also answers the
upgrade's questions (lock/up.bend): what git prints for refs, the default
branch and tags, ancestry, checkouts at a rev, the hub's manifest for a
moved hash, .gitignore, and the project's sources. A new checkout's package is walked
from its entry here, by K.pkg_of, which is interpreter code under
EZ-TRUST-2 until ez add is converted.
15 imports
import Base import 0xabe575924687afad4cee1a2c1194d639/main.bend as R import ../io/file.bend as F import ../hub/hub.bend as Web import ../hub/get.bend as Net import ../git/git.bend as Git import ../git/exec.bend as GX import ../pkg/pkg.bend as K import ../pkg/path.bend as P import ../share/say.bend as Say import ../share/spin.bend as Spin import ./lock.bend as L import ./world.bend as W import ./up.bend as Up import ./plan.bend as Plan
Definitions
def env.text source · line 35 · raw
@res:Result<&1, &1, Pair(U32, String), String> -> String
an environment variable's text; unset, ""
def lib.or source · line 43 · raw
@+dir:String -> String
where packages live, which is with the project rather than in ~/.bend/lib
def bend.lib source · line 47 · raw
IO(String)
the BEND_LIB this project pins
def nonempty source · line 53 · raw
@ss:List<&2, String> -> List<&2, String>
the non-empty lines
def read.ledger source · line 62 · raw
IO(Maybe<&2, String>)
the ledger's text, or None when there is no ez.toml
def read.all source · line 66 · raw
@ps:List<&2, String> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Source>)
every listed path, read
def listed source · line 77 · raw
@ok:Bool -> @+text:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Listing)
what git listed, or why it could not
def read.listing source · line 90 · raw
IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Listing)
every .bend file git tracks under the current directory, with its text.
Untracked files are not a clone's, so they are not the lock's.
def gots source · line 100 · raw
@+how:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.How -> @+manifest:String -> @gs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/hub/hub.Got> -> @acc:List<&2, String> -> 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer
every text a fetch answered, or the first miss
def hub.all source · line 112 · raw
@+hub:String -> @+hash:String -> @fs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/pkg/pkg.Item> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/hub/hub.Got>)
every file of a hub package, fetched and checked against its sum
def hub.got source · line 123 · raw
@got:0x886223f5c47e4983fe57d887c034bc7f/src/hub/hub.Got -> @+hub:String -> @+hash:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a hub package's files, once its manifest arrived
def answer.hub source · line 133 · raw
@+hub:String -> @+hash:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a hub package: its manifest, then every file it names
def disk.all source · line 143 · raw
@+dir:String -> @fs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/pkg/pkg.Item> -> IO(List<&2, String>)
every file a tree's manifest names, read from beside it. A file that is not there reads as "", which does not hash to its sum.
def answer.lib source · line 154 · raw
@+dir:String -> @+manifest:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a tree under BEND_LIB, as it is
def clone.miss source · line 161 · raw
@+work:String -> @+why:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a checkout that could not be made or read is removed, and the question is answered with why
def clone.ran source · line 168 · raw
@ok:Bool -> @+work:String -> @+why:String -> @go:(@_:Unit -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)) -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a command of a clone that worked goes on with the clone; one that failed ends it
def clone.run source · line 176 · raw
@+work:String -> @what:String -> @args:List<&2, String> -> @go:(@_:Unit -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)) -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
one git command of a clone, and the rest of the clone when it worked
def clone.walk source · line 182 · raw
@+work:String -> @+entry:String -> @+nar:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
the checkout's package, walked from its entry the way ez add walked it
def clone.entry source · line 191 · raw
@ok:Bool -> @+work:String -> @+entry:String -> @+url:String -> @+rev:String -> @+nar:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
the entry has to be in the checkout for there to be a package to walk
def clone.weigh source · line 199 · raw
@+work:String -> @+url:String -> @+rev:String -> @+entry:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
the checkout, weighed and walked
def answer.clone source · line 212 · raw
@+lib:String -> @+hash:String -> @+url:String -> @+rev:String -> @+entry:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a git package whose tree is not under BEND_LIB: a shallow clone at the rev
the ledger pins, the way ez add and ez fetch clone, from the source the
question names, which the planner anchored at the project root. Nothing is
laid here; the plan lays the tree once it has checked it.
def git.seen source · line 226 · raw
@got:Maybe<&2, String> -> @+lib:String -> @+hash:String -> @+url:String -> @+rev:String -> @+entry:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a tree already under BEND_LIB is read; a missing one is cloned
def answer.git source · line 241 · raw
@+lib:String -> @+hash:String -> @+url:String -> @+rev:String -> @+entry:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a git package
def answer.pkg source · line 247 · raw
@+lib:String -> @+hash:String -> @src:0x886223f5c47e4983fe57d887c034bc7f/src/lock/lock.Src -> @+hub:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a package, from where its source says
def said source · line 256 · raw
@got:0x886223f5c47e4983fe57d887c034bc7f/src/hub/hub.Got -> 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer
what the hub says a name names, as it said it; the planner reads the hash out of it
def answer.name source · line 264 · raw
@+hub:String -> @+nv:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
a name, asked of the hub once: GET <hub>/name/<nv>
def answer.lock source · line 272 · raw
IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
the lock being rewritten, "" when there is none
def answer source · line 278 · raw
@+lib:String -> @ask:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Ask -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Answer)
one question, answered
def answer.all source · line 288 · raw
@+lib:String -> @asks:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Ask> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Reply>)
every question, answered
def git.said source · line 302 · raw
@+what:String -> @args:List<&2, String> -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
what git printed, and whether it succeeded, kept as it was
def answer.refs source · line 315 · raw
@+url:String -> @+ref:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the refs a ref could name: a tag, its peeled form, and a branch, all at once, because which of them exists is the question
def answer.head source · line 320 · raw
@+url:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
HEAD on the remote, with the branch it is a symref to
def answer.tags source · line 324 · raw
@+url:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
every tag on the remote
def answer.above source · line 328 · raw
@+lib:String -> @+url:String -> @+pin:String -> @+tip:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
whether tip descends from pin, asked of a blobless bare clone
def tree.walk source · line 335 · raw
@+work:String -> @+at:String -> @+nar:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the checkout's package, walked from its entry the way ez add walks it, with
the directory its paths are written from, against the repo
def tree.entry source · line 345 · raw
@ok:Bool -> @+work:String -> @+at:String -> @+url:String -> @+rev:String -> @+nar:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the entry has to be in the checkout for there to be a package to walk
def answer.tree source · line 358 · raw
@+lib:String -> @+url:String -> @+rev:String -> @+entry:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a checkout at a rev: cloned, its .git removed, weighed, and walked. An
entry that was not recorded is read from the checkout. Nothing is laid and
nothing is noted: a tree the upgrade moves to is laid by the plan, once the
upgrade and the lock both succeed.
def answer.weigh source · line 373 · raw
@+url:String -> @+rev:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a commit's NAR hash, for a tool
def answer.hubhas source · line 379 · raw
@+hub:String -> @+hash:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the hub's manifest for a hash a dependency moved to
def answer.ignore source · line 385 · raw
IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the ignore file, "" when it is missing
def found.put source · line 391 · raw
@got:Maybe<&2, String> -> @+at:String -> @rest:0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer -> 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer
one source in front of the rest, or the first that could not be read
def found.all source · line 403 · raw
@ps:List<&2, String> -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
every listed source, read
def found.listed source · line 413 · raw
@ok:Bool -> @+text:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
def answer.sources source · line 422 · raw
IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
every Bend source of the project. Vendored trees and the gate's shadow live under .ez, and a checkout's .git is not source, so neither is rewritten.
def whole.miss source · line 430 · raw
@+work:String -> @+why:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a checkout ez add walks, which could not be made or read: removed, and
the question answered with why
def whole.ran source · line 437 · raw
@ok:Bool -> @+work:String -> @+why:String -> @go:(@_:Unit -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)) -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a command of the checkout that worked goes on with it; one that failed ends it
def whole.run source · line 445 · raw
@+work:String -> @what:String -> @args:List<&2, String> -> @go:(@_:Unit -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)) -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
one git command of the checkout, and the rest of it when it worked
def whole.put source · line 451 · raw
@got:Maybe<&2, String> -> @+at:String -> @rest:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/pkg/pkg.Source> -> List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/pkg/pkg.Source>
a file read, in front of the rest
def whole.read source · line 461 · raw
@+work:String -> @ps:List<&2, String> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/pkg/pkg.Source>)
every listed file of the checkout, read, with its path from the checkout's top. One that cannot be read as text, such as a link to a directory, is left out, as the walk would find it missing.
def whole.listed source · line 477 · raw
@ok:Bool -> @+work:String -> @+nar:String -> @+text:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
the checkout, its .git removed, weighed, and every file of it read; then
removed. Nothing is laid: ez add lays the tree from its plan.
the files of a checkout, read, once find has listed them. A listing that
failed is refused rather than read: find writes what it could not reach
to stderr, which snap answers beside the paths (SNAP-ANS-4), and such a
line is no path of the package.
def whole.weigh source · line 489 · raw
@+work:String -> @+rev:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
def whole.dir source · line 499 · raw
@ok:Bool -> @+work:String -> @+url:String -> @+rev:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a scratch directory made, or why it could not be
def answer.whole source · line 517 · raw
@+url:String -> @+rev:String -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
a checkout at a rev for ez add: a shallow clone into a scratch directory
outside the project and BEND_LIB, weighed, and every file's text read, so
the planner walks the package itself. The scratch directory is removed
whether or not the clone worked, so a refused add leaves no trace.
def answer.up source · line 523 · raw
@+lib:String -> @ask:0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Ask -> IO(0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Answer)
one of the upgrade's questions, answered
def answer.ups source · line 547 · raw
@+lib:String -> @asks:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Ask> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Reply>)
every one of them, answered
def answer.queries source · line 560 · raw
@+lib:String -> @qs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Query> -> IO(List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Reply>)
every query of the lock's upgrade: git is asked the question as the planner anchored it, and the answer is recorded under the question the upgrade looks it up by
def more source · line 571 · raw
@world:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.World -> @rs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Reply> -> @us:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/up.Reply> -> 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.World
the World with more answers in it
def wrote source · line 580 · raw
@ok:Bool -> @+at:String -> IO(Unit)
a write that did not happen stops the command
def write source · line 588 · raw
@+at:String -> @text:String -> IO(Unit)
one file written, with the directory it goes in made first
def lay.all source · line 595 · raw
@+dir:String -> @fs:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.Source> -> IO(Unit)
every file of a tree, in order
def place source · line 605 · raw
@+lib:String -> @pl:0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Place -> String
where a place is
def exec source · line 613 · raw
@+lib:String -> @effect:0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Effect -> IO(Unit)
one effect
def exec.all source · line 632 · raw
@+lib:String -> @es:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Effect> -> IO(Unit)
every effect, in order
def end.at source · line 643 · raw
@zero:Bool -> @+code:U32 -> @+why:String -> IO(Unit)
a status that is 0 ends nothing, so the program runs out and exits 0; any other exits with that status and the reason
def end source · line 652 · raw
@+outcome:0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Outcome -> IO(Unit)
how the command ends: with the status the planner gave its outcome
(Plan.status, EZ-OUT-1), and the reason when it refused
def exec.plan source · line 657 · raw
@+lib:String -> @pl:0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Plan -> IO(Unit)
a plan, executed
def loop.step source · line 668 · raw
@st:0x886223f5c47e4983fe57d887c034bc7f/src/lock/plan.Step -> @+lib:String -> @world:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.World -> @go:(@_:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.World -> IO(Unit)) -> IO(Unit)
the planner's step: its questions answered and the loop gone round again, or its plan run
def loop source · line 681 · raw
@fuel:Nat -> @+lib:String -> @+world:0x886223f5c47e4983fe57d887c034bc7f/src/lock/world.World -> IO(Unit)
the loop, under fuel. Every round adds at least one answer, since the planner never asks what the World answers already.
def run source · line 691 · raw
@up:Bool -> @+only:String -> IO(Unit)
ez lock and ez lock --upgrade [--package only]: the directory it runs
in, the ledger and the listing read, every question answered, and the plan
run