src/sha/nar.bend checks
raw source on the hub · import 0x74799d3f846634a3d7461d4336d7c9d4/src/sha/nar.bend as Nar
sha/nar: the SRI nix hash path --sri would give for a directory, computed
without nix. A NAR is the tree as length-prefixed strings; its sha256, in
SRI form, is what fetchgit records as narHash.
The tree is read in one listing, then every regular file's text, and the
NAR is built from what was read by a pure, fuelled state machine: each step
places one path or closes one directory, the way lock/resolve and pkg/walk
carry on, since two Bend defs may not call each other. What the NAR holds
of a path is what nix's dumper takes: the owner's exec bit of the mode,
every name and link target as it is, and a file's bytes. The reading is
sha/dump's, since it runs find through foreign code a law may not import.
3 imports
import Base import ../pkg/pkg.bend as K import ../share/sha.bend as Sha
Types
type Row source · line 293 · raw
Data
one path of the listing: its type as %y gives it (d, f, l), its
mode (%M), its name (%f), its path from the top (%P) and a symlink's
target (%l)
Row@kind:String -> @mode:String -> @name:String -> @at:String -> @target:String -> Row
type Ent source · line 316 · raw
Data
one path of the tree with what the NAR holds of it: a file's text, or a
symlink's target, as body
Ent@kind:String -> @exec:Bool -> @name:String -> @at:String -> @body:String -> Ent
type Frame source · line 321 · raw
Data
a directory still open: its path from the top, its name, and the entries found in it so far
Frame@at:String -> @name:String -> @kids:List<&2, 0x74799d3f846634a3d7461d4336d7c9d4/src/pkg/pkg.Item> -> Frame
type State source · line 326 · raw
Data
where the build stands: the paths still to place, the directory they are being placed in, and the directories around it
State@es:List<&2, Ent> -> @top:Frame -> @up:List<&2, Frame> -> State
type Move source · line 330 · raw
Data
a step of the build: another state, or the finished node of the top
Next@st:State -> Move
Built@node:String -> Move
Definitions
def byte source · line 23 · raw
@+code:U32 -> Char
one byte as a character. NAR is a byte stream held in a Bend string.
def nat.byte source · line 26 · raw
@+value:Nat -> Char
def le64.go source · line 29 · raw
@width:Nat -> @+value:Nat -> String
def le64 source · line 37 · raw
@+value:Nat -> String
a length as NAR writes it: eight bytes, little-endian
def zeros source · line 41 · raw
@count:Nat -> String
that many NUL bytes, the padding after a string
def pad.of source · line 48 · raw
@+len:Nat -> Nat
def str source · line 52 · raw
@+text:String -> String
one NAR string: its length, its bytes, then zeros up to a multiple of eight
def exec.fields source · line 56 · raw
@ex:Bool -> String
def regular source · line 64 · raw
@ex:Bool -> @+contents:String -> String
a regular file's node, marked executable when it is
def symlink source · line 69 · raw
@+target:String -> String
a symlink's node
def entry source · line 74 · raw
@+ent:0x74799d3f846634a3d7461d4336d7c9d4/src/pkg/pkg.Item -> String
one directory entry: its name and its node
def entries source · line 80 · raw
@es:List<&2, 0x74799d3f846634a3d7461d4336d7c9d4/src/pkg/pkg.Item> -> String
a directory's entries, in the order given
def directory source · line 88 · raw
@es:List<&2, 0x74799d3f846634a3d7461d4336d7c9d4/src/pkg/pkg.Item> -> String
a directory's node, its entries in the order given
def dir source · line 96 · raw
@es:List<&2, 0x74799d3f846634a3d7461d4336d7c9d4/src/pkg/pkg.Item> -> String
a directory's node as NAR writes it: its entries sorted by name, whatever
order they were listed in. String.is_le is codepoint order, which is nix's
byte order for the UTF-8 of valid names. Every directory the walk serializes
goes through here, so the order find printed its names in never reaches
the NAR.
def archive source · line 100 · raw
@+node:String -> String
a whole NAR: the magic, then the root node
def b64.digit.plus source · line 103 · raw
@plus:Bool -> Char
def b64.digit.lt62 source · line 110 · raw
@small:Bool -> @+index:U32 -> Char
def b64.digit.lt52 source · line 117 · raw
@small:Bool -> @+index:U32 -> Char
def b64.digit.lt26 source · line 124 · raw
@small:Bool -> @+index:U32 -> Char
def b64.digit source · line 131 · raw
@+index:U32 -> Char
def b64.triple source · line 134 · raw
@+first:U32 -> @+second:U32 -> @+third:U32 -> String
def b64.one source · line 141 · raw
@+first:U32 -> String
def b64.two source · line 146 · raw
@+first:U32 -> @+second:U32 -> String
def b64 source · line 154 · raw
@text:String -> String
standard base64, padded with =
def hex.val.upper source · line 165 · raw
@is_upper:Bool -> @+code:U32 -> U32
def hex.val.lower source · line 172 · raw
@is_lower:Bool -> @+code:U32 -> U32
def hex.val.digit source · line 179 · raw
@is_digit:Bool -> @+code:U32 -> U32
def hex.val source · line 186 · raw
@+ch:Char -> U32
def hex.bytes source · line 190 · raw
@text:String -> String
def sri.hex source · line 199 · raw
@+hex:String -> String
def sri source · line 203 · raw
@+bytes:String -> String
the SRI of some bytes: sha256- and the base64 of their digest
def empty source · line 207 · raw
String
the node of an empty directory
def nul source · line 223 · raw
Char
the NUL that ends every field of the listing
def push source · line 228 · raw
@+ch:Char -> @fs:List<&2, String> -> List<&2, String>
a char put in front of the first field, which a text that does not end with a NUL leaves open
def cut.at source · line 237 · raw
@ends:Bool -> @+ch:Char -> @fs:List<&2, String> -> List<&2, String>
one char of the listing read: a NUL ends a field, any other char is the next of the field it is in
def cut source · line 245 · raw
@text:String -> List<&2, String>
the fields of a listing, each ended by a NUL, exactly as they were printed
def clean source · line 253 · raw
@text:String -> Bool
whether a text holds no NUL, as no name and no link target can
def joined source · line 262 · raw
@fs:List<&2, String> -> String
fields as the listing prints them, each ended by a NUL
def clean.all source · line 270 · raw
@fs:List<&2, String> -> Bool
whether every field holds no NUL
def owner.exec source · line 283 · raw
@mode:String -> Bool
whether a file's owner may execute it, from the mode find prints as
%M, -rwxr-xr-x: the fourth character is x, or s when the setuid
bit is set as well. This is the mode bit nix's NAR dumper reads
(S_IXUSR), not an access check, so a file the owner may not execute is
not executable whoever weighs it.
def rows source · line 298 · raw
@fs:List<&2, String> -> List<&2, Row>
the listing's fields, five to a path. A path the listing cut short is not read.
def listing.argv source · line 308 · raw
@+top:String -> List<&2, String>
what find is asked to print of every path under top, the top first,
each field ended by a NUL. find lists a directory before what is in it
and all of it before the next entry, which is the order build reads.
def leaf.of source · line 334 · raw
@link:Bool -> @ex:Bool -> @+body:String -> String
def leaf source · line 342 · raw
@entry:Ent -> String
a file's or a symlink's node
def under source · line 347 · raw
@+at:String -> @+name:String -> String
the path of an entry named name inside the directory at at
def close source · line 352 · raw
@top:Frame -> @up:List<&2, Frame> -> @es:List<&2, Ent> -> Move
the directory on top finished: its node is an entry of the one around it, or the whole tree when there is none
def ent.kind source · line 361 · raw
@entry:Ent -> String
an entry's type, name and path, and an open directory's path
def ent.name source · line 366 · raw
@entry:Ent -> String
an entry's name
def ent.at source · line 371 · raw
@entry:Ent -> String
an entry's path from the top
def frame.at source · line 376 · raw
@frame:Frame -> String
an open directory's path from the top
def place source · line 382 · raw
@is_dir:Bool -> @+name:String -> @+at:String -> @+node:String -> @more:List<&2, Ent> -> @top:Frame -> @up:List<&2, Frame> -> Move
a path inside the directory on top: a directory is opened, anything else is an entry of it, with its leaf's node
def step.ent source · line 400 · raw
@inside:Bool -> @+entry:Ent -> @more:List<&2, Ent> -> @top:Frame -> @up:List<&2, Frame> -> Move
the next path: placed when it is inside the directory on top, which closes otherwise
def step source · line 414 · raw
@st:State -> Move
one step of the build
def build.go source · line 423 · raw
@fuel:Nat -> @mv:Move -> Maybe<&2, String>
the build, under fuel
def build source · line 437 · raw
@+es:List<&2, Ent> -> Maybe<&2, String>
the node of a directory, from its paths in the order find lists them. Each
step places a path or closes a directory, and each directory is closed
once, so twice the paths and two more is fuel enough.
def tree.top source · line 443 · raw
@is_dir:Bool -> @top:Ent -> @more:List<&2, Ent> -> Maybe<&2, String>
the node of the whole tree, from its listing with the top first: a directory is built, a file or a symlink is a leaf
def tree source · line 451 · raw
@es:List<&2, Ent> -> Maybe<&2, String>
the node of the whole tree, or none for an empty listing