Files
computer-playbook/utils/install/README.md
kevinveenbirkenbachandClaude Opus 5.5 30268cf552 fix(install): replace an end-of-life distro Node.js with the current LTS
Debian trixie ships nodejs 20.19, whose release line reached its end of
life on 2026-04-30. `@mermaid-js/mermaid-cli` 12 and its puppeteer
declare `node >=22.13.0`, so `make install-lint` failed in every fresh
Debian stack container with `All providers failed for
chrome-headless-shell` (#1088).

`ensure_node_present()` still installs the distro package first, then
reads the release line of `node` on PATH and looks it up in the
nodejs/Release schedule. A line past its `end` date is replaced by the
newest LTS from nodejs.org/dist/index.json: SHASUMS256.txt is verified
with gpgv against the active Node.js release keys from
nodejs/release-keys, the tarball against its SHA-256 entry, and the
release is unpacked into /usr/local, after which `node` on PATH must be
that release. Nothing pins a major: the next LTS line is picked up the
same way. Ubuntu 26.04's Node.js 22, supported until 2027-04-30, stays.

`ensure_npm_present()` calls it first, so a container that already holds
the end-of-life node is upgraded too rather than skipped because npm
exists. The call runs once per process.

Closes #1088

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 16:02:52 +02:00

40 lines
2.5 KiB
Markdown

# utils/install
This directory hosts the Python implementation behind `make install-lint`.
For the general rules that govern READMEs in code directories see [documentation.md](../../docs/contributing/documentation.md).
## Purpose
The package installs the lint toolchain (actionlint, shfmt, ruff, ansible-lint, mbake, markdownlint-cli2, eslint, shellcheck, ansible-playbook, ansible-galaxy) using the right channel per tool (system package manager, pip, npm, or GitHub release).
Modules at this level are channel-agnostic primitives; per-tool policy lives one level down in [lint/](lint/).
## Structure
| File | Role |
|---|---|
| `primitives.py` | Logging, sudo wrapping, PATH mutation, and stdlib-based URL download. |
| `pip.py` | Venv-aware pip installer with `--break-system-packages` and `--user` fallback. |
| `npm.py` | Global / local npm install with per-user `--prefix` fallback. |
| `node.py` | Node.js runtime that is still supported upstream: the distro package, or the newest LTS from nodejs.org (signature- and checksum-verified) when the distro line has reached its end of life. |
| `github_release.py` | Latest-tag resolver and asset downloader for GitHub releases. |
| `system_pkg.py` | Per-manager dispatch for `pacman` / `apt-get` / `dnf` / `yum` / `brew`. |
| `lint/` | One module per tool, each exposing `ensure()`. See [lint README](lint/README.md). |
The CLI entry point lives at [__main__.py](lint/__main__.py), invoked from [lint.sh](../../scripts/install/lint.sh) as `python3 -m utils.install.lint`.
The matching dispatcher [wrapper.sh](../../scripts/install/wrapper.sh) routes `make install-lint` host vs container based on `INFINITO_LINT_RUNNER`.
## File Naming
- Module names MUST stay lowercase snake_case.
- Channel-agnostic helpers MUST live directly under `utils/install/`.
- Per-tool policy (one tool per file) MUST live under `lint/` (see [lint README](lint/README.md)).
- Test files live in [tests/unit/python/utils/install/](../../tests/unit/python/utils/install/) and mirror the module name with a `test_` prefix.
## Import Rules
- `primitives.py` MUST NOT import from any other module in this package.
- `pip.py`, `npm.py`, `github_release.py`, and `system_pkg.py` MAY import from `primitives.py`.
- `npm.py` MAY import from `system_pkg.py` and `node.py` to bootstrap npm itself; no other cross-imports between these four are allowed.
- `node.py` MAY import from `primitives.py` and `system_pkg.py`.
- Per-tool modules under `lint/` MUST NOT import each other (see [lint README](lint/README.md)).