Repository files
Presence, size and line counts of the well known files a repository is expected to carry, plus any extra path the guardrail asks for.
| Facts key | files |
| Version | v1 |
| Script | files.py |
| Timeout | 30 seconds |
Inputs
| Input | Description | Default | Environment |
|---|---|---|---|
paths | Comma separated paths to describe, relative to the directory the CLI runs in. | README.md,README.rst,LICENSE,LICENSE.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,SECURITY.md,.gitignore | GUARDRAIL_INPUT_PATHS |
path | One further path to describe, so a guardrail configured with its own path is collected too. | `` | GUARDRAIL_INPUT_PATH |
When a guardrail declares an input with the same name, it passes its value through. That means you set these values in the guardrail's configuration in buildnote.json.
A guardrail asks for these facts by name and reads them back by the same name:
{
"collect": ["files"]
}files = guardrail.facts("files")Facts
These are the fields of the document files collects. In a path, [] means each entry of the list before it, and [path] means a key of the object before it.
| Fact | Meaning |
|---|---|
files | Every requested path, keyed exactly as it was asked for. A path nobody asked for is absent, so look up the one the guardrail configured instead of iterating. Unlike every other collector's paths, the key is deliberately not resolved from the directory the CLI runs in: files["AGENTS.md"] means the same thing whichever directory a policy checks, and files[path].location says where it was actually looked for. |
files[path].present | Whether the path is a file. |
files[path].location | Where the path was looked for, from the directory the CLI runs in, so a policy covering several directories can tell one module's AGENTS.md from another's. |
files[path].symlink | Whether the path is a symbolic link, present only when it is one. A link to an existing file is present as well; a link pointing at nothing is not present. |
files[path].symlinkTarget | What the link points at, exactly as it was written, present only when the path is a link. A relative target is resolved from the directory the link sits in, not from the directory the CLI runs in. |
files[path].bytes | Size in bytes. Absent when the file is not present or could not be read. |
files[path].lines | Line count. Absent when the file is not present or could not be read. |
files[path].nonBlankLines | Lines carrying something other than whitespace. Absent when the file is not present or could not be read. |
files[path].unreadable | Why the file could not be read, present only when it could not be. |
If a collector can't finish, it prints what it gathered so far along with an incomplete key that says why. Facts after the point where it stopped are missing, so a check that depends on them should read incomplete first.
Example facts
Here are the facts the files collector gathers from an example project:
{
"files": {
"README.md": {
"present": true,
"location": "README.md",
"bytes": 22,
"lines": 3,
"nonBlankLines": 2
},
"README.rst": {
"present": false,
"location": "README.rst"
},
"LICENSE": {
"present": true,
"location": "LICENSE",
"bytes": 12,
"lines": 1,
"nonBlankLines": 1
},
"LICENSE.md": {
"present": false,
"location": "LICENSE.md"
},
"CONTRIBUTING.md": {
"present": false,
"location": "CONTRIBUTING.md"
},
"CODE_OF_CONDUCT.md": {
"present": false,
"location": "CODE_OF_CONDUCT.md"
},
"SECURITY.md": {
"present": false,
"location": "SECURITY.md"
},
".gitignore": {
"present": true,
"location": ".gitignore",
"bytes": 7,
"lines": 1,
"nonBlankLines": 1
}
}
}