~/bend-docscommunity

src/ledger/ignore.bend checks

raw source on the hub · import 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/ignore.bend as Ignore

ledger/ignore: the gitignore allowlist, derived from the ledger. A dependency marked vendor = true has its tree committed under .ez/lib/<hash>, and git only keeps it when .gitignore says so with a !.ez/lib/<hash> line. That line has to follow the ledger exactly: a hash the ledger stopped naming leaves a dead tree committed, and one it names but the file does not is a tree a clone never gets. So the allowlist is not edited, it is derived: sync takes the ledger's dependencies and the file, and gives back the file whose allowlist lines are exactly the vendored hashes, with every line that is not ez's left as it was. ez add, ez remove and ez lock --upgrade all write what it returns.

Which lines are ez's. A line that starts !.ez/lib/ is ez's allowlist, as written, and whatever follows the prefix is the hash it names. Anything else is read loosely: surrounding blanks trimmed, one leading / and one trailing / dropped, so !/.ez/lib/<h>/ and !.ez/lib/<h> are allowlist lines too. ez owns everything under .ez/lib, so any exception under it is ez's to keep or drop; a line spelled differently from allow is dropped and the hash, when the ledger still vendors it, written back in the canonical spelling. Three more lines are what makes the allowlist work at all: .ez/*, !.ez/lib and .ez/lib/*. Git cannot re-include a file under a directory it excluded, so a bare .ez/ (or .ez, /.ez/) makes every allowlist line inert. That line is replaced, where it stands, by whichever of the three the file does not already have.

Where the allowlist goes. The vendored hashes are written as one block, each once, in the order the ledger first names them, where the file's first allowlist line was. A file with none gets the block at its end, which is where the upgrade has always appended one, preceded by whichever of the three rules the file lacks.

2 imports
import Base
import ./manifest.bend as M

Types

type Rule source · line 34 · raw

Data

what one line of an ignore file is to ez

type Line source · line 43 · raw

Data

a line, with what it is to ez beside it

Definitions

def allow source · line 47 · raw

@+hash:String -> String

the gitignore line that keeps one committed tree

def lead source · line 52 · raw

@+pat:String -> String

one leading /, which anchors a pattern to the file's own directory and so changes nothing for a .gitignore at the root

def trail source · line 57 · raw

@+pat:String -> String

one trailing /, which only narrows a pattern to directories, and every path ez names here is one

def bare source · line 62 · raw

@+pat:String -> String

a pattern with both of those dropped

def loose.under source · line 66 · raw

@under:Bool -> @+rest:String -> Rule

an exception under .ez/lib/ names the hash after the prefix

def loose.neg source · line 74 · raw

@+pat:String -> Rule

an exception: the re-included library directory, or one tree under it

def loose.pos source · line 80 · raw

@+pat:String -> Rule

an exclusion: the whole of .ez, what is inside it, or what is inside its library directory

def loose.go source · line 86 · raw

@neg:Bool -> @+pat:String -> Rule

a trimmed line, read by whether it is an exception

def loose source · line 94 · raw

@+line:String -> Rule

a line that is not written the way allow writes one

def canon source · line 99 · raw

@empty:Bool -> @+rest:String -> Rule

!.ez/lib/ with nothing after it is the directory, with a trailing slash

def kind.go source · line 107 · raw

@exact:Bool -> @+line:String -> Rule

a line written the way allow writes one names the hash after the prefix

def kind source · line 115 · raw

@+line:String -> Rule

what a line of an ignore file is to ez

def tag source · line 119 · raw

@ls:List<&2, String> -> List<&2, Line>

every line, with what it is

def hashes.put source · line 127 · raw

@what:Rule -> @rest:List<&2, String> -> List<&2, String>

the hash an allowlist line names, in front of the rest

def hashes source · line 144 · raw

@ls:List<&2, String> -> List<&2, String>

every hash the allowlist lines of a file name, in order. This is what the allowlist says, and what the laws hold against the ledger.

def others.put source · line 152 · raw

@what:Rule -> @+line:String -> @rest:List<&2, String> -> List<&2, String>

a line that is not ez's, in front of the rest

def others source · line 168 · raw

@ls:List<&2, String> -> List<&2, String>

every line that is not ez's, in order: the lines sync must not touch

def vendors.put source · line 176 · raw

@vend:Bool -> @+hash:String -> @rest:List<&2, String> -> List<&2, String>

a dependency's hash, in front of the rest, when its tree is committed

def vendors source · line 185 · raw

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

the hash of every dependency marked vendor = true, in the order the ledger wrote them. Two dependencies may name one hash.

def named source · line 193 · raw

@hs:List<&2, String> -> @+hash:String -> Bool

whether a list of hashes already names a hash

def once.put source · line 202 · raw

@skip:Bool -> @+hash:String -> @rest:List<&2, String> -> List<&2, String>

a hash in front of the rest, unless it is passed over

def once.seen source · line 210 · raw

@skip:Bool -> @+hash:String -> @+seen:List<&2, String> -> List<&2, String>

the hashes seen so far, with this one when it was kept

def once.go source · line 220 · raw

@hs:List<&2, String> -> @+seen:List<&2, String> -> List<&2, String>

each hash once, where it first appears, passing over any seen already holds. An empty hash names no tree; M.parse refuses a dependency with none, so that only guards a model built by hand.

def vended source · line 231 · raw

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

the hashes the allowlist must name: every dependency marked vendor = true, each hash once, in the order the ledger first names it. Two dependencies that share a tree share its one line.

def allow.each source · line 235 · raw

@hs:List<&2, String> -> List<&2, String>

one allowlist line per hash

def allows source · line 243 · raw

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

the allowlist lines of a ledger, in its order

def same source · line 247 · raw

@left:Rule -> @right:Rule -> Bool

whether two kinds are the same rule. Two allowlist lines are never asked.

def has.step source · line 261 · raw

@hit:Bool -> @rest:(@_:Unit -> Bool) -> Bool

the rest of the scan only when this line was not it

def has source · line 269 · raw

@ls:List<&2, Line> -> @+want:Rule -> Bool

whether a file already has a line of this kind

def rule.put source · line 277 · raw

@there:Bool -> @+line:String -> @rest:List<&2, String> -> List<&2, String>

a rule, in front of the rest, when the file does not have it

def rules.go source · line 285 · raw

@star:Bool -> @lib:Bool -> @pkgs:Bool -> List<&2, String>

the three rules the allowlist needs, less the ones already there

def rules source · line 289 · raw

@+ls:List<&2, Line> -> List<&2, String>

the rules a file lacks

def need source · line 295 · raw

@skip:Bool -> @+rs:List<&2, String> -> List<&2, String>

the rules go in front of the block only when nothing else puts them in: a .ez/ line is replaced by them where it stands, and a ledger that vendors nothing needs none

def block source · line 303 · raw

@+ds:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep> -> @+ls:List<&2, Line> -> List<&2, String>

the allowlist block: the missing rules, then one line per vendored hash

def placed source · line 309 · raw

@done:Bool -> @+blk:List<&2, String> -> List<&2, String>

the block, where it goes: at the first allowlist line, or at the end

def walk source · line 316 · raw

@ls:List<&2, Line> -> @+fix:List<&2, String> -> @+blk:List<&2, String> -> @done:Bool -> List<&2, String>

every line, walked once. fix replaces a .ez/ line. blk replaces the first allowlist line, every later one is dropped, and done says the block is already down; a file with no allowlist line gets it at the end. Every other line is kept as it was.

def lines.go source · line 336 · raw

@+ds:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep> -> @+ls:List<&2, Line> -> List<&2, String>

the walk over a file's lines, each already read for what it is

def lines source · line 341 · raw

@ds:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep> -> @ls:List<&2, String> -> List<&2, String>

the lines of an ignore file with the allowlist the ledger's dependencies call for: exactly the vendored hashes, and nothing else changed

def unend.go source · line 352 · raw

@rest:List<&2, String> -> @+last:String -> List<&2, String>

the last piece of a file cut at its newlines, dropped when it is empty: it is what follows the newline the file ends with, and not a line a person wrote

def unend source · line 360 · raw

@ps:List<&2, String> -> List<&2, String>

the lines of a file cut at its newlines, less that last empty piece

def file.lines source · line 369 · raw

@text:String -> List<&2, String>

the lines of a file. An empty file has none, a file of one newline has one empty line, and a last line with no newline after it is a line all the same.

def file.text source · line 374 · raw

@ls:List<&2, String> -> String

lines written out as a file, each ending with a newline, which file.lines reads back as those lines

def text.out source · line 383 · raw

@same:Bool -> @+text:String -> @+out:String -> String

a file whose lines did not change comes back byte for byte, whatever it ended with. One whose lines did is its new lines, each ending with a newline.

def sync source · line 393 · raw

@ds:List<&2, 0x886223f5c47e4983fe57d887c034bc7f/src/ledger/manifest.Dep> -> @+text:String -> String

the ignore file with the allowlist the ledger calls for. ez add, ez remove and ez lock --upgrade write this when it differs from what they read.