repomatic.file_inventory module

What files this repository contains, honoring .gitignore.

One question, asked in one place: every “which files are the Python sources / the workflows / the images” lookup routes through FileInventory, whose glob_files() resolves symlinks, drops broken ones and filters out anything .gitignore excludes. The results are the lists CI jobs gate on, so a job that formats Markdown and one that lints it see the same files.

Split out of repomatic.metadata.core.Metadata, which reaches CI context, git history and pyproject.toml: none of that is needed to answer “what is on disk here”, and Metadata keeps the family reachable under its own names for every existing caller.

Todo

Drop the py-walk dependency and parse .gitignore with wcmatch, already imported here for globbing, once it reads gitignore files natively: facelessuser/wcmatch#226.

repomatic.file_inventory.GITIGNORE_PATH = PosixPath('.gitignore')

Path of the .gitignore file whose rules filter every inventory lookup.

Fixed at the repository root, unlike the configurable [tool.repomatic.gitignore] location that sync-gitignore writes: the glob filter has to match what git itself honors, and git only reads this path.

class repomatic.file_inventory.FileInventory[source]

Bases: object

The repository’s files, grouped by what a job needs to act on them.

Each group is a cached property, so a command asking for the Markdown files twice walks the tree once. Instantiate per working directory: the lookups resolve against the current directory at call time.

property gitignore_exists: bool[source]
property gitignore_parser: Parser | None[source]

Returns a parser for the .gitignore file, if it exists.

gitignore_match(file_path)[source]
Return type:

bool

glob_files(*patterns)[source]

Return all file path matching the patterns.

Patterns are glob patterns supporting ** for recursive search, and ! for negation, resolved against the current working directory: they select from one shared walk of it (see _all_files), so an absolute pattern matches nothing.

All directories are traversed, whether they are hidden (i.e. starting with a dot .) or not, including symlinks.

Skips:

  • files which does not exists

  • directories

  • broken symlinks

  • files matching patterns specified by .gitignore file

Returns both hidden and non-hidden files.

All files are normalized to their absolute path, so that duplicates produced by symlinks are ignored.

File path are returned as relative to the current working directory if possible, or as absolute path otherwise.

The resulting list of file paths is sorted.

Return type:

list[Path]

property python_files: list[Path][source]

Returns a list of python files.

property json_files: list[Path][source]

Returns a list of JSON files.

Note

JSON5 files are excluded because Biome doesn’t support them.

property yaml_files: list[Path][source]

Returns a list of YAML files.

property pyproject_files: list[Path][source]

Returns a list of pyproject.toml files.

property workflow_files: list[Path][source]

Returns a list of GitHub workflow files.

property doc_files: list[Path][source]

Returns a list of doc files.

property markdown_files: list[Path][source]

Returns a list of Markdown files.

property image_files: list[Path][source]

Returns a list of image files.

Covers the formats handled by repomatic format-images: JPEG, PNG, WebP, and AVIF. See repomatic.images for the optimization tools.

shebang_names_zsh(path)[source]

Whether path opens with a shebang line naming zsh.

The .sh extension is ambiguous: it says POSIX shell while the shebang picks the actual interpreter. Reading that first line is what keeps shfmt_files and zsh_files disjoint, so a bash script is never handed to the Zsh linter and a zsh script is never handed to shfmt. Verdicts are memoized per inventory (see _zsh_shebangs).

Parameters:

path (Path) – File to probe.

Return type:

bool | None

Returns:

True when the shebang names zsh, False when it does not, and None when the file cannot be read. Both callers drop an unreadable file rather than guess at its dialect.

property shfmt_files: list[Path][source]

Returns a list of shell files that shfmt can reliably format.

shfmt supports the following dialects (-ln flag):

  • bash: GNU Bourne Again Shell.

  • posix: POSIX Shell (/bin/sh).

  • mksh: MirBSD Korn Shell.

  • bats: Bash Automated Testing System.

Zsh is excluded. shfmt added experimental Zsh support in v3.13.0 but it fails on common constructs: for var (list) short-form loops and for ... { } brace-delimited loops.

Files are excluded by extension (.zsh, .zshrc, etc.) and by shebang (any .sh file whose first line references zsh).

Todo

Stop excluding Zsh once shfmt formats those constructs: mvdan/sh#1203.

property zsh_files: list[Path][source]

Returns a list of Zsh files.

The .zsh extension and the zsh dotfiles are unambiguous. A .sh file joins the list only when its shebang names zsh: matching the extension alone would claim every bash script in the repository, and the Zsh lint job would then run zsh --no-exec over scripts shfmt is formatting as bash. See shebang_names_zsh().