diff --git a/prompts/EXISTING_REPO_CHECKLIST.md b/prompts/EXISTING_REPO_CHECKLIST.md index 6557c14..87197ab 100644 --- a/prompts/EXISTING_REPO_CHECKLIST.md +++ b/prompts/EXISTING_REPO_CHECKLIST.md @@ -216,7 +216,9 @@ with your task. entries in `.gitignore`, `.editorconfig` and `.dockerignore` go below the comment that ends each canonical file. An entry above that comment which the canonical file lacks makes the script stop before it writes anything, - naming the file and the entry. + naming the file and the entry. It stops the same way on a line in + `.golangci.yml` that the canonical file lacks, apart from comments and the + repo's entries in the `deny` list of the `test-support` rule. - [ ] README has an **Entrypoints** section documenting the `script/` entrypoints and linking the standard - [ ] `script/lint` and `script/test` each run diff --git a/script/update-policy b/script/update-policy index 6984511..021ff4b 100755 --- a/script/update-policy +++ b/script/update-policy @@ -13,7 +13,8 @@ # canonical file's last line. An entry above that line which the # canonical file lacks stops the script. # - .golangci.yml: the entries the repo added to the deny list of the -# test-support rule +# test-support rule. Any other line the canonical file lacks stops +# the script, unless it is blank or a comment. set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" @@ -56,6 +57,16 @@ local_path() { fi } +# local_only_lines [end]: print each line of the local +# file, above line end if given, that the fetched file lacks. Blank +# lines and comments do not count. +local_only_lines() { + awk -v end="${3:-}" ' + NR == FNR { fetched[$0]; next } + (end == "" || FNR < end) && !/^[ \t]*(#|$)/ && !($0 in fetched) + ' "$1" "$2" +} + # keep_lines_below_last : append to the fetched file # whatever follows its last line in the local file. Stop if a line above # that one is missing from the fetched file, unless it is blank or a @@ -66,10 +77,7 @@ keep_lines_below_last() { if [ -z "$last" ] || [ -z "$number" ]; then die "$2 lacks this line; add it and put the repo's own entries below it: $last" fi - own="$(awk -v end="$number" ' - NR == FNR { fetched[$0]; next } - FNR < end && !/^#|^[ \t]*$/ && !($0 in fetched) - ' "$1" "$2")" + own="$(local_only_lines "$1" "$2" "$number")" if [ -n "$own" ]; then die "$2 has entries above its last canonical line that the canonical file lacks; move each below that line to keep it, or delete it: $own" @@ -80,7 +88,8 @@ $own" # keep_deny_entries : add to the deny list of the # test-support rule in the fetched file the entries only the local file # has. An entry is a "- pkg:" line, the lines under it and any comment -# above it. +# above it. Stop if the local file still has a line the result lacks, +# unless it is blank or a comment: replacing the file would delete it. keep_deny_entries() { awk ' function indent(line) { return match(line, /[^ ]/) - 1 } @@ -132,6 +141,11 @@ keep_deny_entries() { ' "$2" "$1" > "$1.merged" || die "the fetched $2 has no deny list in its test-support rule" mv "$1.merged" "$1" + own="$(local_only_lines "$1" "$2")" + if [ -n "$own" ]; then + die "$2 has lines the canonical file lacks; add each to the canonical file to keep it, or delete it: +$own" + fi } main() { diff --git a/test/update-policy.sh b/test/update-policy.sh index 489eb57..3573319 100755 --- a/test/update-policy.sh +++ b/test/update-policy.sh @@ -21,8 +21,10 @@ write_stub_curl() { cat > "$dir/bin/curl" << 'EOF' #!/bin/sh previous="" +fail_flag="" for argument in "$@"; do [ "$previous" = "--output" ] && output="$argument" + [ "$argument" = "--fail" ] && fail_flag=yes previous="$argument" done url="$previous" @@ -30,7 +32,9 @@ base="https://git.eeqj.de/sneak/prompts/raw/commit/$HASH/" path="${url#"$base"}" source="$(dirname "$0")/../canonical/$path" if [ "$path" = "$url" ] || [ ! -f "$source" ]; then - exit 22 + [ -n "$fail_flag" ] && exit 22 + echo "404 page not found" > "$output" + exit 0 fi cp "$source" "$output" EOF @@ -322,6 +326,8 @@ test_bad_commit_hash() { expect_failure expect_nothing_written done + # The last hash has the right form, so it is the one that reaches curl. + expect_output "cannot fetch" } test_push_failure() { @@ -420,6 +426,24 @@ EOF expect_nothing_written } +test_own_golangci_setting_stops() { + start_scenario "a .golangci.yml setting the canonical file lacks stops" + cat >> "$dir/repo/.golangci.yml" << 'EOF' + # A comment of our own. + forbidigo: + forbid: + - pattern: model.Operator +EOF + commit_and_push_fixture .golangci.yml .prettierrc + run_update_policy "$HASH" + expect_failure + expect_output ".golangci.yml has lines" + expect_output "forbidigo:" + expect_output "- pattern: model.Operator" + expect_output_without "A comment of our own." + expect_nothing_written +} + test_source_repo_stops() { start_scenario "the repo the policy files come from stops" printf '#!/bin/sh\necho prompts\n' > "$dir/repo/script/projectname" @@ -484,6 +508,7 @@ main() { test_uncommitted_change_stops test_gitignore_lacks_canonical_last_line test_fetched_golangci_without_deny_list + test_own_golangci_setting_stops test_source_repo_stops test_staged_file_stays_out_of_commit test_short_commit_hash_refused