~/bend-docscommunity

src/sha/dump.bend source

src/sha/dump.bend on the hub · documented module

# sha/dump: a directory read off the disk and handed to sha/nar, which builds# its NAR and names it. The listing is one `find`, run through snap's foreign# effect, and every regular file is then read. This half lives apart from# sha/nar because bend 2.0.32 fails a proof whose imports reach foreign code,# so a law may import sha/nar but never this.import Baseimport 0xabe575924687afad4cee1a2c1194d639/main.bend as Rimport ../io/file.bend as Fimport ./nar.bend as Nar# a command's output as it printed it, or the walk stopped with why it faileddef said(ok: Bool, +why: String, +text: String) -> IO(String):  match ok:    case False{}:      IO.die(String, 1, "ez: nar hash: " ++ why ++ text)    case True{}:      IO.pure(String, text)# what a program printed, with the status line in front of it taken off and# nothing else toucheddef printed.at(ends: Bool, tail: String, rest: Unit -> String) -> String:  match ends:    case True{}:      tail    case False{}:      rest(Unit{})# the output after its first newlinedef printed(out: String) -> String:  match out:    case SNil{}:      ""    case SCon{c, +t}:      printed.at(Char.is_eq(c, '\n'), t, _u => printed(t))# a path of the tree, as the file effect is to open itdef under.top(+top: String, +at: String) -> String:  Bool.pick(String, String.is_empty(at), top, top ++ "/" ++ at)def file.got(got: Maybe<&2, String>, +path: String) -> IO(String):  match got:    case None{}:      IO.die(String, 1, "ez: nar hash: " ++ path ++ ": unreadable")    case Some{s}:      IO.pure(String, s)# a regular file's text, by its path from the topdef file.of(+path: String) -> IO(String):  do IO<String>:    m : Maybe<&2, String> <- F.read(path)    file.got(m, path)# a path of the listing with what the NAR needs of it: a file's text read, a# symlink's target as the listing printed itdef ent.other(  known: Bool,  +kind: String,  +name: String,  +at: String,  +target: String,  +path: String) -> IO(Nar.Ent):  match known:    case True{}:      IO.pure(Nar.Ent, Nar.Ent{kind, False{}, name, at, target})    case False{}:      IO.die(Nar.Ent, 1, "ez: nar hash: " ++ path ++ ": not a file, directory, or symlink")# a regular file's text read, or anything else as the listing gave itdef ent.read(  file: Bool,  +kind: String,  +mode: String,  +name: String,  +at: String,  +target: String,  +path: String) -> IO(Nar.Ent):  match file:    case True{}:      do IO<Nar.Ent>:        body : String <- file.of(path)        return Nar.Ent{kind, Nar.owner.exec(mode), name, at, body}    case False{}:      ent.other(Bool.or(String.eq(kind, "d"), String.eq(kind, "l")), kind, name, at,        target, path)# one path of the listing, readdef ent.of(+top: String, row: Nar.Row) -> IO(Nar.Ent):  Nar.Row{+kind, +mode, +name, +at, +target} = row  ent.read(String.eq(kind, "f"), kind, mode, name, at, target, under.top(top, at))# every path of the listing, readdef ents(+top: String, rs: List<&2, Nar.Row>) -> IO(List<&2, Nar.Ent>):  match rs:    case []:      IO.pure(List<&2, Nar.Ent>, [])    case +h <> t:      do IO<List<&2, Nar.Ent>>:        e : Nar.Ent <- ent.of(top, h)        rest : List<&2, Nar.Ent> <- ents(top, t)        return e <> rest# the tree's node, or the walk stopped when the listing made nonedef built(got: Maybe<&2, String>, +path: String) -> IO(String):  match got:    case None{}:      IO.die(String, 1, "ez: nar hash: " ++ path ++ ": the listing does not make a tree")    case Some{node}:      IO.pure(String, node)# the NAR serial of one pathdef dump(+path: String) -> IO(String):  do IO<String>:    +out : String <- R.exec(Nar.listing.argv(path))    text : String <- said(R.ok(out), path ++ ": ", printed(out))    es : List<&2, Nar.Ent> <- ents(path, Nar.rows(Nar.cut(text)))    built(Nar.tree(es), path)# the SRI narHash of a path, the same string `nix hash path --sri` printsdef path(+work: String) -> IO(String):  do IO<String>:    node : String <- dump(work)    return Nar.sri(Nar.archive(node))