1 Commits
Author SHA1 Message Date
sneak ae926cf2b6 Install node, yarn and python from the distribution (closes #146)
check / check (push) Successful in 22s
Follows sneak's ruling at
#146 (comment). Runtimes
and the installer tools bundled with python come from the distribution,
with no version and no hash. Third-party packages stay pinned by hash.

script/bootstrap drops nvm and corepack. It installs node, yarn and the
node packages only when yarn.lock is in the tree, and stops there when
yarn's major version is not 1. This repository's Dockerfile starts from
Alpine 3.24. The Python example starts from debian:trixie-slim, keeps
pipenv at $HOME/.pipenv on a host and in an image, and sets
PIP_ONLY_BINARY=:all:, so pip downloads no build tools without a hash
check.

Model: opus-5-5
2026-11-04 08:21:17 +00:00
3 changed files with 24 additions and 18 deletions

No files matched your search

+5 -3
View File
@@ -167,7 +167,9 @@ with your task.
- [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore` - [ ] JS: `package.json`, `yarn.lock`, `.prettierrc`, `.prettierignore`
(fetch from (fetch from
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and `https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierrc` and
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`) `https://git.eeqj.de/sneak/prompts/raw/branch/main/.prettierignore`).
Make the first `yarn.lock` with yarn 1, from a distribution that
packages it, such as Alpine (`apk add nodejs yarn`).
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
- [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above) - [ ] Docs/writing: `.prettierrc`, `.prettierignore` (same URLs as above)
@@ -211,8 +213,8 @@ with your task.
image whose distribution packages yarn 1, such as Alpine. image whose distribution packages yarn 1, such as Alpine.
- [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by - [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by
whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With
neither name on `PATH`, they print one line saying to run neither name on `PATH`, `script/fmt` and `script/fmt-check` print one line
`script/bootstrap`, and exit 1. saying to run `script/bootstrap`, and exit 1.
- [ ] `script/bootstrap` installs no linter of its own — delete the block, its - [ ] `script/bootstrap` installs no linter of its own — delete the block, its
version variables and its call site. A JS repo's `yarn install` stays; it version variables and its call site. A JS repo's `yarn install` stays; it
brings a linter along with every other dependency, and no verdict is taken brings a linter along with every other dependency, and no verdict is taken
+5 -3
View File
@@ -179,7 +179,9 @@ Template files can be fetched from:
`https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and, `https://git.eeqj.de/sneak/prompts/raw/branch/main/.golangci.yml` and,
in the same commit, set the lint phase digest to the one named in the in the same commit, set the lint phase digest to the one named in the
`.golangci.yml` paragraph of `REPO_POLICIES.md`) `.golangci.yml` paragraph of `REPO_POLICIES.md`)
- [ ] JS: `yarn init`, `yarn add --dev prettier` - [ ] JS: `yarn init`, `yarn add --dev prettier`. `script/bootstrap`
installs no yarn until `yarn.lock` exists, so use yarn 1 from a
distribution that packages it, such as Alpine (`apk add nodejs yarn`).
- [ ] Python: `pyproject.toml` - [ ] Python: `pyproject.toml`
## Configure script/ Entrypoints and Makefile ## Configure script/ Entrypoints and Makefile
@@ -236,8 +238,8 @@ are thin shims calling them. Model scripts:
`script/fmt-check` runs the formatter on the host. `script/fmt-check` runs the formatter on the host.
- [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by - [ ] `script/bootstrap`, `script/fmt` and `script/fmt-check` run yarn by
whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With whichever name is present: `yarn`, or `yarnpkg` on Debian and Ubuntu. With
neither name on `PATH`, they print one line saying to run neither name on `PATH`, `script/fmt` and `script/fmt-check` print one line
`script/bootstrap`, and exit 1. saying to run `script/bootstrap`, and exit 1.
- [ ] No `docker build` in `script/` leaves a dangling image behind: - [ ] No `docker build` in `script/` leaves a dangling image behind:
`script/lint` and `script/test` write no image, and `script/docker` and `script/lint` and `script/test` write no image, and `script/docker` and
`script/cibuild` tag theirs `script/cibuild` tag theirs
+14 -12
View File
@@ -123,26 +123,28 @@ style conventions are in separate documents:
`script/bootstrap` installs node, yarn and the node packages only when `script/bootstrap` installs node, yarn and the node packages only when
`yarn.lock` is in the tree. With no `yarn.lock`, it installs no node and no `yarn.lock` is in the tree. With no `yarn.lock`, it installs no node and no
yarn, and it does not check yarn's version. yarn, and it does not check yarn's version. Make a repository's first
`yarn.lock` with yarn 1, from a distribution that packages it, such as
Alpine (`apk add nodejs yarn`).
Debian and Ubuntu name the yarn command `yarnpkg`. `script/bootstrap`, Debian and Ubuntu name the yarn command `yarnpkg`. `script/bootstrap`,
`script/fmt` and `script/fmt-check` each carry the same small function that `script/fmt` and `script/fmt-check` each carry the same small function that
runs whichever name is present. With neither name on `PATH`, the function runs whichever name is present. With neither name on `PATH`, `script/fmt`
prints one line saying to run `script/bootstrap`, and exits 1. and `script/fmt-check` print one line saying to run `script/bootstrap`, and
exit 1.
With `yarn.lock` in the tree, `script/bootstrap` stops with a one-line With `yarn.lock` in the tree, `script/bootstrap` stops with a one-line
message when yarn's major version is not 1, before it installs any node message when yarn's major version is not 1, before it installs any node
packages. Debian 13 and Ubuntu 26.04 package yarn 4. With packages. Debian 13 and Ubuntu 26.04 package yarn 4. With
`--frozen-lockfile`, yarn 4 refuses a yarn 1 `yarn.lock`. Without that flag, `--frozen-lockfile`, yarn 4 refuses a yarn 1 `yarn.lock`. Without that flag,
it rewrites the file in its own format, with its own hashes in place of it rewrites the file in its own format, with yarn 4 hashes in place of the
these. A host whose distribution packages yarn 4 moves to one that packages yarn 1 ones. A host whose distribution packages yarn 4 moves to one that
yarn 1, such as Alpine or Ubuntu 24.04. packages yarn 1, such as Alpine or Ubuntu 24.04.
A `Dockerfile` stage copies `yarn.lock` before it runs `script/bootstrap` A `Dockerfile` stage copies `yarn.lock` before it runs `script/bootstrap`
only if that stage needs yarn. A stage that needs yarn starts from an image only if that stage needs yarn. A stage that needs yarn starts from an image
whose distribution packages yarn 1, such as Alpine. The Python and Go stages whose distribution packages yarn 1, such as Alpine. The Python and Go stages
below need no yarn, so they copy no `yarn.lock` before that step and never below need no yarn and copy no `yarn.lock`, so they never reach the stop.
reach the stop.
`script/cibuild` runs the CI build, and the Gitea workflow calls it. The `script/cibuild` runs the CI build, and the Gitea workflow calls it. The
script changes to the repo root, runs `script/bootstrap`, runs script changes to the repo root, runs `script/bootstrap`, runs
@@ -569,10 +571,10 @@ style conventions are in separate documents:
"$HOME/.pipenv/bin/pipenv" install --dev --deploy "$HOME/.pipenv/bin/pipenv" install --dev --deploy
``` ```
Make `script/requirements.txt` once with Make `script/requirements.txt` once, with
`echo pipenv | pip-compile --generate-hashes --allow-unsafe -o script/requirements.txt -`, `echo pipenv | pip-compile --generate-hashes --allow-unsafe -o script/requirements.txt -`.
from Alpine's `py3-pip-tools` package, because Debian and Ubuntu do not `pip-compile` comes from Alpine's `py3-pip-tools` package; Debian and Ubuntu
package it. Make the first `Pipfile.lock` with do not package `pip-tools`. Make the first `Pipfile.lock` with
`$HOME/.pipenv/bin/pipenv lock`, after the `pip install` line has installed `$HOME/.pipenv/bin/pipenv lock`, after the `pip install` line has installed
pipenv. pipenv.