utils/install/lintΒΆ

Per-tool installer policy for the lint toolchain. For the package’s overall role see README.md. For general README conventions see documentation.md.

PurposeΒΆ

Each module in this directory owns exactly one lint tool and exposes a single ensure() function. The CLI in main.py groups these ensure calls and applies the stamp-based skip for the default β€œall” invocation.

File NamingΒΆ

  • A module name MUST match the lowercase snake_case of the tool it installs:

    • actionlint -> actionlint.py

    • markdownlint-cli2 -> markdownlint_cli2.py

    • ansible-lint -> ansible/lint.py

  • Aggregate installers (one helper covers a tightly coupled command pair) take the topic name without a key suffix. Example: ansible/commands.py installs both ansible-playbook and ansible-galaxy via the same system-package candidates.

Module ShapeΒΆ

Every per-tool module MUST expose the same surface so the dispatcher can call it uniformly:

"""<one-line docstring: what gets installed and via which channel>."""

from __future__ import annotations


def ensure() -> None:
    """Install <tool> if not present. Raises RuntimeError on failure."""
  • ensure() MUST be idempotent: return immediately when the tool is already on PATH (or importable, for Python modules).

  • ensure() MUST raise RuntimeError with a descriptive message on failure.

  • A module MAY read tool-specific environment overrides (e.g. ACTIONLINT_VERSION, RUFF_PIP_SPEC) at call time.

Import RulesΒΆ

  • A per-tool module MUST NOT import another per-tool module. Shared logic flows through utils.install.primitives, utils.install.pip, utils.install.npm, utils.install.github_release, and utils.install.system_pkg only.

  • A per-tool module MAY import from utils.cache (for PROJECT_ROOT) and from stdlib.

Group DispatchΒΆ

main.py maps each CLI group to a fixed set of ensure() calls:

Group

Modules called (in order)

action

actionlint

ansible

ansible_commands, ansible_collections, ansible_lint

python

shfmt, ruff

shellcheck

shellcheck

markdown

markdownlint_cli2

makefile

mbake

javascript

eslint

all (default)

every group above, in the order listed

The all mode honors a per-interpreter stamp at build/install-lint-<hash>.stamp (the suffix is the first 8 chars of sha256(sys.executable), so host and container track independently even though build/ is bind-mounted). Stamp dependencies are lint.sh and pyproject.toml. Group-targeted invocations always run and never touch the stamp.