~/bend-docscommunity

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)

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

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

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

type Move source · line 330 · raw

Data

a step of the build: another state, or the finished node of the top

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 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