From 917fe4bc1da4b9ec5816e4db0e9b21ff8e409083 Mon Sep 17 00:00:00 2001 From: clawbot Date: Tue, 10 Nov 2026 20:19:00 +0000 Subject: [PATCH] Rename script/install to script/fetch-policy By convention, and in scripts-to-rule-them-all, script/install installs the program itself. This script fetches the shared policy files into a repo. The make target, the test names and the messages take the new name. Behaviour is unchanged. Model: opus-5-5 --- Makefile | 6 +- README.md | 14 ++-- TODO.md | 8 +- prompts/EXISTING_REPO_CHECKLIST.md | 6 +- prompts/NEW_REPO_CHECKLIST.md | 7 +- prompts/REPO_POLICIES.md | 32 ++++---- script/{install => fetch-policy} | 16 ++-- script/update-policy | 14 ++-- test/update-policy.sh | 121 +++++++++++++++-------------- 9 files changed, 113 insertions(+), 111 deletions(-) rename script/{install => fetch-policy} (96%) diff --git a/Makefile b/Makefile index c22ff51..0ffeb6f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: bootstrap setup test lint fmt fmt-check check docker hooks install update-policy +.PHONY: bootstrap setup test lint fmt fmt-check check docker hooks fetch-policy update-policy # Makefile targets are thin shims; the implementations live in script/ # per the scripts-to-rule-them-all pattern (see the Entrypoints section @@ -31,8 +31,8 @@ docker: hooks: @script/install-precommit -install: - @script/install +fetch-policy: + @script/fetch-policy update-policy: @script/update-policy diff --git a/README.md b/README.md index b4cffa7..9664209 100644 --- a/README.md +++ b/README.md @@ -141,13 +141,13 @@ alpine. We provide: `script/check` - `script/install-precommit` — installs the git pre-commit hook (our own extension); `make hooks` shims to it -- `script/install` — fetch the vendored policy files from this repo over HTTP - and write them into a repo (our own extension). It writes into the repo given - as its argument, or its own repo with no argument. It stops when its target is - this repo. -- `script/update-policy` — fetch the current `script/install`, run it on its own - repo and commit the result without pushing (our own extension). It is for the - repos that vendor the policy files. It stops when run here. +- `script/fetch-policy` — fetch the vendored policy files from this repo over + HTTP and write them into a repo (our own extension). It writes into the repo + given as its argument, or its own repo with no argument. It stops when its + target is this repo. +- `script/update-policy` — fetch the current `script/fetch-policy`, run it on + its own repo and commit the result without pushing (our own extension). It is + for the repos that vendor the policy files. It stops when run here. `make hooks` installs the pre-commit hook that runs `script/precommit`. diff --git a/TODO.md b/TODO.md index 31800dc..3f6cc77 100644 --- a/TODO.md +++ b/TODO.md @@ -21,11 +21,11 @@ fmt-check, and commit. # Completed Steps -- 2026-11-09: `script/install` writes the vendored policy files into a repo over - HTTP, and installs itself and `script/update-policy` there +- 2026-11-09: `script/fetch-policy` writes the vendored policy files into a repo + over HTTP, itself and `script/update-policy` among them (https://git.eeqj.de/sneak/prompts/issues/165). `make update-policy` now - fetches the current `script/install`, runs it and commits without pushing. The - template repositories get both scripts in their own issues. + fetches the current `script/fetch-policy`, runs it and commits without + pushing. The template repositories get both scripts in their own issues. - 2026-11-09: `script/update-policy` and `make update-policy` update a repo's vendored policy files with one command (https://git.eeqj.de/sneak/prompts/issues/162). They fetch the files from diff --git a/prompts/EXISTING_REPO_CHECKLIST.md b/prompts/EXISTING_REPO_CHECKLIST.md index fbc2214..a9c4d9e 100644 --- a/prompts/EXISTING_REPO_CHECKLIST.md +++ b/prompts/EXISTING_REPO_CHECKLIST.md @@ -211,8 +211,8 @@ with your task. `https://git.eeqj.de/sneak/prompts/raw/branch/main/script/` - [ ] `script/precommit` exists and the pre-commit hook (installed by `script/install-precommit`, shimmed by `make hooks`) runs it -- [ ] `script/install` and `script/update-policy` exist, identical to the model - scripts, and `make update-policy` shims to `script/update-policy`. +- [ ] `script/fetch-policy` and `script/update-policy` exist, identical to the + model scripts, and `make update-policy` shims to `script/update-policy`. `make update-policy` commits without pushing, so a person reviews and pushes the commit. A `.gitignore` or `.dockerignore` without the comment that ends the canonical file needs no preparation. The script moves each @@ -225,7 +225,7 @@ with your task. stops the same way on a line in `.golangci.yml` that the canonical file has never held, apart from comments and the repo's entries in the `deny` list of the `test-support` rule. It also stops on a repo's own - `script/install` or `script/update-policy`. + `script/fetch-policy` or `script/update-policy`. - [ ] README has an **Entrypoints** section documenting the `script/` entrypoints and linking the standard - [ ] `script/lint` and `script/test` each run diff --git a/prompts/NEW_REPO_CHECKLIST.md b/prompts/NEW_REPO_CHECKLIST.md index c5cd5a3..e9d5fcb 100644 --- a/prompts/NEW_REPO_CHECKLIST.md +++ b/prompts/NEW_REPO_CHECKLIST.md @@ -266,10 +266,11 @@ are thin shims calling them. Model scripts: - [ ] `script/install-precommit` — installs the pre-commit hook that runs `script/precommit` - [ ] `make hooks` — shims to `script/install-precommit` -- [ ] `script/install` — fetches the vendored policy files from the `prompts` - repo over HTTP and writes them into the repo; identical across repos +- [ ] `script/fetch-policy` — fetches the vendored policy files from the + `prompts` repo over HTTP and writes them into the repo; identical across + repos - [ ] `script/update-policy` / `make update-policy` — fetches the current - `script/install`, runs it on the repo and commits the result without + `script/fetch-policy`, runs it on the repo and commits the result without pushing; identical across repos - [ ] README **Entrypoints** section documents the scripts and links the standard diff --git a/prompts/REPO_POLICIES.md b/prompts/REPO_POLICIES.md index 0e2d201..f86f65d 100644 --- a/prompts/REPO_POLICIES.md +++ b/prompts/REPO_POLICIES.md @@ -110,7 +110,7 @@ style conventions are in separate documents: - `script/fmt-check` - `script/check` - `script/docker` - - `script/install` + - `script/fetch-policy` - `script/update-policy` The scripts must be POSIX sh (`#!/bin/sh`, `set -eu`, no bashisms) so they @@ -191,10 +191,10 @@ style conventions are in separate documents: `script/check`. - `script/install-precommit` installs the git pre-commit hook. The `make hooks` target shims to it. - - `script/install` fetches the vendored policy files from the `prompts` repo - over HTTP and writes them into the repo it is given, or its own repo with - no argument. - - `script/update-policy` fetches the current `script/install` from the + - `script/fetch-policy` fetches the vendored policy files from the `prompts` + repo over HTTP and writes them into the repo it is given, or its own repo + with no argument. + - `script/update-policy` fetches the current `script/fetch-policy` from the `prompts` repo, runs it on its own repo and commits the result. It does not push. The `make update-policy` target shims to it. - `script/projectname` (literally that filename) simply outputs the @@ -937,19 +937,19 @@ style conventions are in separate documents: feature branch. - One command brings a repo up to standards: `make update-policy`. It runs - `script/update-policy`, which fetches the current `script/install` from the - head of `main` in the `prompts` repo and runs it on the repo. It then commits - the files that changed and does not push, so a person reviews and pushes the - commit. + `script/update-policy`, which fetches the current `script/fetch-policy` from + the head of `main` in the `prompts` repo and runs it on the repo. It then + commits the files that changed and does not push, so a person reviews and + pushes the commit. - `script/install` fetches each vendored file from `prompts` over HTTP and - writes it into the repo. It skips a language's files when git tracks no + `script/fetch-policy` fetches each vendored file from `prompts` over HTTP + and writes it into the repo. It skips a language's files when git tracks no source file of that language. A file the repo lacks is written whole. A `prompts/NAME.md` goes to `docs/NAME.md`, unless the repo keeps it at - `NAME.md`. It also installs `script/install` and `script/update-policy` in - the repo, so a repo updated once can update itself. The list of vendored - files is at the top of `script/install`. The script replaces each file and - keeps only the repo's own entries: + `NAME.md`. It also writes `script/fetch-policy` and `script/update-policy` + into the repo, so a repo updated once can update itself. The list of + vendored files is at the top of `script/fetch-policy`. The script replaces + each file and keeps only the repo's own entries: - in `.gitignore`, `.editorconfig` and `.dockerignore`: the lines below the comment that ends the canonical file - in a `.gitignore` or `.dockerignore` lacking that comment: every entry the @@ -1182,7 +1182,7 @@ style conventions are in separate documents: - `Makefile` - `script/` entrypoints (`bootstrap`, `setup`, `projectname`, `test`, `lint`, `fmt`, `fmt-check`, `check`, `docker`, `cibuild`, `precommit`, - `install-precommit`, `install`, `update-policy`) + `install-precommit`, `fetch-policy`, `update-policy`) - `Dockerfile`, `.dockerignore` - `.gitea/workflows/check.yml` - Go: `go.mod`, `go.sum`, `.golangci.yml` diff --git a/script/install b/script/fetch-policy similarity index 96% rename from script/install rename to script/fetch-policy index 842f727..dc9d5e7 100755 --- a/script/install +++ b/script/fetch-policy @@ -1,10 +1,10 @@ #!/bin/sh -# script/install: write the current policy files from the prompts repo -# into a repo clone, over HTTP. It commits nothing; script/update-policy -# does that. Identical in all repos. Our own extension to -# scripts-to-rule-them-all. +# script/fetch-policy: write the current policy files from the prompts +# repo into a repo clone, over HTTP. It commits nothing; +# script/update-policy does that. Identical in all repos. Our own +# extension to scripts-to-rule-them-all. # -# Usage: script/install [path of a repo clone] +# Usage: script/fetch-policy [path of a repo clone] # Without a path it updates the repo this script sits in. # # Standard output is the full hash of the prompts commit, then each path @@ -50,12 +50,12 @@ prompts/GO_HTTP_SERVER_CONVENTIONS.md prompts/LLM_PROSE_TELLS.md prompts/NEW_REPO_CHECKLIST.md prompts/REPO_POLICIES.md -script/install +script/fetch-policy script/update-policy " die() { - echo "install: $*" >&2 + echo "fetch-policy: $*" >&2 exit 1 } @@ -226,7 +226,7 @@ $own" } main() { - [ "$#" -le 1 ] || die "usage: script/install [path of a repo clone]" + [ "$#" -le 1 ] || die "usage: script/fetch-policy [path of a repo clone]" target="${1:-$(dirname "$0")/..}" cd "$target" || die "no such directory: $target" diff --git a/script/update-policy b/script/update-policy index d58aa88..a30e0c9 100755 --- a/script/update-policy +++ b/script/update-policy @@ -1,12 +1,12 @@ #!/bin/sh # script/update-policy: bring this repo up to standards. It fetches the -# current script/install from the prompts repo over HTTP, runs it on this -# repo and commits the files it wrote. It does not push. Identical in all -# repos. Our own extension to scripts-to-rule-them-all. +# current script/fetch-policy from the prompts repo over HTTP, runs it +# on this repo and commits the files it wrote. It does not push. +# Identical in all repos. Our own extension to scripts-to-rule-them-all. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" -INSTALL_URL="https://git.eeqj.de/sneak/prompts/raw/branch/main/script/install" +FETCH_POLICY_URL="https://git.eeqj.de/sneak/prompts/raw/branch/main/script/fetch-policy" die() { echo "update-policy: $*" >&2 @@ -22,10 +22,10 @@ main() { trap 'rm -rf "$tmp"' EXIT curl --fail --silent --show-error --max-time 60 \ - --output "$tmp/install" "$INSTALL_URL" || - die "cannot fetch $INSTALL_URL" + --output "$tmp/fetch-policy" "$FETCH_POLICY_URL" || + die "cannot fetch $FETCH_POLICY_URL" - sh "$tmp/install" "$ROOT" > "$tmp/written" + sh "$tmp/fetch-policy" "$ROOT" > "$tmp/written" commit="$(head -n 1 "$tmp/written")" paths="$(tail -n +2 "$tmp/written")" diff --git a/test/update-policy.sh b/test/update-policy.sh index 79399f1..d902b0c 100755 --- a/test/update-policy.sh +++ b/test/update-policy.sh @@ -1,13 +1,13 @@ #!/bin/sh -# test/update-policy.sh: test script/install and script/update-policy on -# throwaway repos. Each scenario gets one temp directory holding a repo, -# its local bare origin, a local git repository of the canonical files -# in place of prompts, and a stub curl that serves them, so nothing -# touches the network. +# test/update-policy.sh: test script/fetch-policy and +# script/update-policy on throwaway repos. Each scenario gets one temp +# directory holding a repo, its local bare origin, a local git +# repository of the canonical files in place of prompts, and a stub curl +# that serves them, so nothing touches the network. set -eu SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd -P)/script" -INSTALL="$SCRIPT_DIR/install" +FETCH_POLICY="$SCRIPT_DIR/fetch-policy" UPDATE_POLICY="$SCRIPT_DIR/update-policy" dir="" @@ -60,8 +60,8 @@ case "$url" in "$HASH" 0000000000000000000000000000000000000000 > "$output" fi ;; - "$site/raw/branch/main/script/install") - serve_file script/install + "$site/raw/branch/main/script/fetch-policy") + serve_file script/fetch-policy ;; "$site/compare/$first...$HASH.patch") git -C "$canonical" format-patch --stdout --root "$HASH" > "$output" @@ -79,7 +79,7 @@ EOF write_canonical_files() { mkdir -p "$dir/canonical/prompts" "$dir/canonical/script" - cp "$INSTALL" "$UPDATE_POLICY" "$dir/canonical/script/" + cp "$FETCH_POLICY" "$UPDATE_POLICY" "$dir/canonical/script/" cat > "$dir/canonical/.gitignore" << 'EOF' *.log *.tmp @@ -208,7 +208,7 @@ start_scenario() { git -C "$dir/repo" remote add origin "$dir/origin.git" mkdir "$dir/repo/script" - cp "$INSTALL" "$UPDATE_POLICY" "$dir/repo/script/" + cp "$FETCH_POLICY" "$UPDATE_POLICY" "$dir/repo/script/" printf '#!/bin/sh\necho example\n' > "$dir/repo/script/projectname" chmod +x "$dir/repo/script/projectname" mkdir -p "$dir/repo/cmd/app" @@ -261,12 +261,12 @@ run_update_policy() { script/update-policy "$@") > "$dir/output" 2>&1 || status=$? } -# run_install : run the script in this source tree, from -# outside the repo it updates. -run_install() { +# run_fetch_policy : run the script in this source tree, +# from outside the repo it updates. +run_fetch_policy() { status=0 (cd "$dir" && PATH="$dir/bin:$PATH" TMPDIR="$dir/tmp" \ - "$INSTALL" "$@") > "$dir/output" 2>&1 || status=$? + "$FETCH_POLICY" "$@") > "$dir/output" 2>&1 || status=$? } head_of_repo() { @@ -478,26 +478,27 @@ test_nothing_changed() { expect_nothing_written } -test_target_lacking_install_gets_both_scripts() { - start_scenario "a repo lacking script/install gets it, and the current script/update-policy, in the commit" - rm "$dir/repo/script/install" +test_target_lacking_fetch_policy_gets_both_scripts() { + start_scenario "a repo lacking script/fetch-policy gets it, and the current script/update-policy, in the commit" + rm "$dir/repo/script/fetch-policy" echo "# An older version." >> "$dir/repo/script/update-policy" commit_and_push_fixture .prettierrc run_update_policy expect_success - expect_same_as_canonical script/install + expect_same_as_canonical script/fetch-policy expect_same_as_canonical script/update-policy - expect_committed_executable script/install + expect_committed_executable script/fetch-policy expect_committed_executable script/update-policy expect_new_commit_not_pushed - [ "$(files_in_commit)" = ".prettierrc script/install script/update-policy " ] || + [ "$(files_in_commit)" = ".prettierrc script/fetch-policy script/update-policy " ] || fail "the commit holds other files: $(files_in_commit)" } # The shell reads a script in blocks, so the padding makes it read the # last line only after main has returned. It finds that line only if -# script/install left the old file in place under a new name. The old -# file is an earlier canonical version, so script/install replaces it. +# script/fetch-policy left the old file in place under a new name. The +# old file is an earlier canonical version, so script/fetch-policy +# replaces it. test_update_policy_replaces_itself() { start_scenario "script/update-policy replaces its own file and still exits 0" { @@ -524,44 +525,44 @@ test_update_policy_replaces_itself() { expect_new_commit_not_pushed } -test_install_with_path_commits_nothing() { - start_scenario "script/install with a path writes into that clone and commits nothing" - rm "$dir/repo/script/install" "$dir/repo/script/update-policy" +test_fetch_policy_with_path_commits_nothing() { + start_scenario "script/fetch-policy with a path writes into that clone and commits nothing" + rm "$dir/repo/script/fetch-policy" "$dir/repo/script/update-policy" commit_and_push_fixture .prettierrc - run_install "$dir/repo" + run_fetch_policy "$dir/repo" expect_success expect_file .prettierrc << 'EOF' { "tabWidth": 4 } EOF - expect_same_as_canonical script/install + expect_same_as_canonical script/fetch-policy expect_same_as_canonical script/update-policy - expect_executable script/install + expect_executable script/fetch-policy expect_executable script/update-policy expect_no_commit [ "$(head -n 1 "$dir/output")" = "$HASH" ] || fail "the first line of output is not the hash" - expect_output "script/install" + expect_output "script/fetch-policy" [ -z "$(ls -A "$dir/tmp")" ] || fail "a temporary directory is left" } -test_install_without_script_directory() { - start_scenario "script/install with a path writes both scripts into a clone with no script directory" +test_fetch_policy_without_script_directory() { + start_scenario "script/fetch-policy with a path writes both scripts into a clone with no script directory" commit_and_push_fixture .prettierrc remove_from_fixture script - run_install "$dir/repo" + run_fetch_policy "$dir/repo" expect_success - expect_same_as_canonical script/install + expect_same_as_canonical script/fetch-policy expect_same_as_canonical script/update-policy - expect_executable script/install + expect_executable script/fetch-policy expect_executable script/update-policy expect_no_commit } -test_install_without_argument_updates_own_repo() { - start_scenario "script/install with no argument updates the repo it sits in" +test_fetch_policy_without_argument_updates_own_repo() { + start_scenario "script/fetch-policy with no argument updates the repo it sits in" commit_and_push_fixture .prettierrc status=0 - (cd "$dir" && PATH="$dir/bin:$PATH" repo/script/install) \ + (cd "$dir" && PATH="$dir/bin:$PATH" repo/script/fetch-policy) \ > "$dir/output" 2>&1 || status=$? expect_success expect_file .prettierrc << 'EOF' @@ -570,19 +571,19 @@ EOF expect_no_commit } -test_install_bad_target() { - start_scenario "script/install refuses a path that is not the top of a clone" +test_fetch_policy_bad_target() { + start_scenario "script/fetch-policy refuses a path that is not the top of a clone" commit_and_push_fixture .prettierrc - run_install "$dir/repo/script" + run_fetch_policy "$dir/repo/script" expect_failure expect_output "not the top of a git clone" - run_install "$dir/bin" + run_fetch_policy "$dir/bin" expect_failure expect_output "not the top of a git clone" - run_install "$dir/no-such-directory" + run_fetch_policy "$dir/no-such-directory" expect_failure expect_output "no such directory" - run_install "$dir/repo" extra + run_fetch_policy "$dir/repo" extra expect_failure expect_output "usage:" expect_nothing_written @@ -591,7 +592,7 @@ test_install_bad_target() { test_failed_fetch_stops() { for url in \ "/api/v1/repos/sneak/prompts/branches/main" \ - "/raw/branch/main/script/install" \ + "/raw/branch/main/script/fetch-policy" \ "/compare/" \ "/raw/commit/"; do start_scenario "a failed fetch of $url stops with nothing written" @@ -661,14 +662,14 @@ EOF } test_untracked_script_stops() { - start_scenario "an untracked script/install is not overwritten" - rm "$dir/repo/script/install" + start_scenario "an untracked script/fetch-policy is not overwritten" + rm "$dir/repo/script/fetch-policy" commit_and_push_fixture .prettierrc - echo "our own script" > "$dir/repo/script/install" - run_install "$dir/repo" + echo "our own script" > "$dir/repo/script/fetch-policy" + run_fetch_policy "$dir/repo" expect_failure - expect_output "script/install has uncommitted changes" - expect_file script/install << 'EOF' + expect_output "script/fetch-policy has uncommitted changes" + expect_file script/fetch-policy << 'EOF' our own script EOF expect_no_commit @@ -680,7 +681,7 @@ test_ignored_file_stops() { remove_from_fixture docs/API_POLICIES.md echo "docs/API_POLICIES.md" >> "$dir/repo/.git/info/exclude" echo "our own notes" > "$dir/repo/docs/API_POLICIES.md" - run_install "$dir/repo" + run_fetch_policy "$dir/repo" expect_failure expect_output "docs/API_POLICIES.md is ignored by git" expect_file docs/API_POLICIES.md << 'EOF' @@ -690,7 +691,7 @@ EOF } test_own_script_stops() { - for script in script/install script/update-policy; do + for script in script/fetch-policy script/update-policy; do start_scenario "a tracked $script with a line the canonical file has never held stops" echo "echo our own script" >> "$dir/repo/$script" commit_and_push_fixture .prettierrc @@ -848,9 +849,9 @@ test_former_canonical_gitignore_line_replaced() { } test_former_canonical_script_line_replaced() { - start_scenario "a script/install line an earlier canonical commit held is replaced" - expect_former_canonical_line_replaced script/install "echo an older install" - expect_same_as_canonical script/install + start_scenario "a script/fetch-policy line an earlier canonical commit held is replaced" + expect_former_canonical_line_replaced script/fetch-policy "echo an older version" + expect_same_as_canonical script/fetch-policy } # A line another file's history removed does not count as held by this @@ -878,12 +879,12 @@ main() { test_language_files_need_a_source_file test_javascript_source_brings_its_styleguide test_nothing_changed - test_target_lacking_install_gets_both_scripts + test_target_lacking_fetch_policy_gets_both_scripts test_update_policy_replaces_itself - test_install_with_path_commits_nothing - test_install_without_script_directory - test_install_without_argument_updates_own_repo - test_install_bad_target + test_fetch_policy_with_path_commits_nothing + test_fetch_policy_without_script_directory + test_fetch_policy_without_argument_updates_own_repo + test_fetch_policy_bad_target test_failed_fetch_stops test_one_missing_file_stops_all test_branch_response_without_hash_stops