A listed file the repo lacks is now written whole, with no keep rule. A prompts/NAME.md goes to docs/NAME.md unless the repo keeps it at NAME.md, and any other file goes to its own path. A language's files are skipped when git tracks no source file of that language. A listed path git ignores now stops the script before it writes. README bullets split into short sentences, and a false sentence about template repos deleted. Model: opus-5-5
This commit is contained in:
1 parent
f4275b9ac0
commit
76b75fa79f
4 files changed
+166
-45
No files matched your search
+112
-15
@@ -117,13 +117,20 @@ EOF
|
||||
echo '{ "tabWidth": 4 }' > "$dir/canonical/.prettierrc"
|
||||
echo "new policy" > "$dir/canonical/prompts/REPO_POLICIES.md"
|
||||
echo "new api policy" > "$dir/canonical/prompts/API_POLICIES.md"
|
||||
for name in CODE_STYLEGUIDE CODE_STYLEGUIDE_GO CODE_STYLEGUIDE_JS \
|
||||
CODE_STYLEGUIDE_PYTHON EXISTING_REPO_CHECKLIST \
|
||||
GO_HTTP_SERVER_CONVENTIONS LLM_PROSE_TELLS NEW_REPO_CHECKLIST; do
|
||||
echo "new $name" > "$dir/canonical/prompts/$name.md"
|
||||
done
|
||||
mkdir -p "$dir/canonical/.gitea/workflows"
|
||||
echo "name: check" > "$dir/canonical/.gitea/workflows/check.yml"
|
||||
}
|
||||
|
||||
# commit_canonical: commit the canonical files as they stand. The stub
|
||||
# curl serves only the newest commit; every other commit gets a 404.
|
||||
commit_canonical() {
|
||||
git -C "$dir/canonical" add .gitignore .dockerignore .editorconfig \
|
||||
.golangci.yml .prettierrc prompts script
|
||||
.golangci.yml .prettierrc .gitea prompts script
|
||||
git -C "$dir/canonical" commit -q -m "Canonical"
|
||||
HASH="$(git -C "$dir/canonical" rev-parse HEAD)"
|
||||
}
|
||||
@@ -174,7 +181,8 @@ EOF
|
||||
}
|
||||
|
||||
# start_scenario <name>: make a new temp directory holding a repo with
|
||||
# the outdated files, not yet committed, and an empty origin.
|
||||
# a Go source file and the outdated files, not yet committed, and an
|
||||
# empty origin.
|
||||
start_scenario() {
|
||||
scenario="$1"
|
||||
rm -rf "$dir"
|
||||
@@ -203,18 +211,46 @@ start_scenario() {
|
||||
cp "$INSTALL" "$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"
|
||||
echo "package main" > "$dir/repo/cmd/app/main.go"
|
||||
write_outdated_files
|
||||
}
|
||||
|
||||
# commit_and_push_fixture <paths...>: commit those paths, remove the
|
||||
# rest of the outdated files, and record the commit as $before.
|
||||
# commit_and_push_fixture <paths...>: commit those paths as they stand
|
||||
# and every other shared file as the canonical file has it, so the
|
||||
# script changes only those paths. Record the commit as $before.
|
||||
commit_and_push_fixture() {
|
||||
(
|
||||
cd "$dir/repo"
|
||||
git add script "$@"
|
||||
git add script cmd "$@"
|
||||
git clean -q -f -x
|
||||
for file in $(git -C "$dir/canonical" ls-files); do
|
||||
case "$file" in
|
||||
script/*) continue ;;
|
||||
prompts/REPO_POLICIES.md) path="REPO_POLICIES.md" ;;
|
||||
prompts/*) path="docs/${file#prompts/}" ;;
|
||||
*) path="$file" ;;
|
||||
esac
|
||||
if [ -z "$(git ls-files -- "$path")" ]; then
|
||||
mkdir -p "$(dirname "$path")"
|
||||
cp "$dir/canonical/$file" "$path"
|
||||
git add "$path"
|
||||
fi
|
||||
done
|
||||
git commit -q -m "Fixture"
|
||||
git push -q origin HEAD
|
||||
git clean -q -f -x
|
||||
)
|
||||
before="$(git -C "$dir/repo" rev-parse HEAD)"
|
||||
}
|
||||
|
||||
# remove_from_fixture <paths...>: delete those paths from the repo and
|
||||
# its origin, and record the commit as $before.
|
||||
remove_from_fixture() {
|
||||
(
|
||||
cd "$dir/repo"
|
||||
git rm -q -r "$@"
|
||||
git commit -q -m "Remove from fixture"
|
||||
git push -q origin HEAD
|
||||
)
|
||||
before="$(git -C "$dir/repo" rev-parse HEAD)"
|
||||
}
|
||||
@@ -365,25 +401,55 @@ EOF
|
||||
[ -z "$(ls -A "$dir/tmp")" ] || fail "a temporary directory is left"
|
||||
}
|
||||
|
||||
test_files_not_carried_are_skipped() {
|
||||
start_scenario "files the repo does not carry skipped"
|
||||
test_files_the_repo_lacks_are_written_whole() {
|
||||
start_scenario "files the repo lacks are written whole"
|
||||
mkdir "$dir/repo/docs"
|
||||
mv "$dir/repo/REPO_POLICIES.md" "$dir/repo/docs/REPO_POLICIES.md"
|
||||
commit_and_push_fixture docs/REPO_POLICIES.md
|
||||
echo "print()" > "$dir/repo/tool.py"
|
||||
echo "export {}" > "$dir/repo/web.ts"
|
||||
commit_and_push_fixture docs/REPO_POLICIES.md tool.py web.ts
|
||||
remove_from_fixture REPO_POLICIES.md .gitignore .golangci.yml .gitea \
|
||||
docs/API_POLICIES.md docs/CODE_STYLEGUIDE_GO.md \
|
||||
docs/CODE_STYLEGUIDE_JS.md docs/CODE_STYLEGUIDE_PYTHON.md
|
||||
run_update_policy
|
||||
expect_success
|
||||
|
||||
expect_same_as_canonical .gitignore
|
||||
expect_same_as_canonical .golangci.yml
|
||||
expect_same_as_canonical .gitea/workflows/check.yml
|
||||
expect_file docs/REPO_POLICIES.md << 'EOF'
|
||||
new policy
|
||||
EOF
|
||||
expect_absent REPO_POLICIES.md
|
||||
expect_file docs/API_POLICIES.md << 'EOF'
|
||||
new api policy
|
||||
EOF
|
||||
expect_absent API_POLICIES.md
|
||||
expect_absent docs/API_POLICIES.md
|
||||
expect_absent .gitignore
|
||||
expect_absent .dockerignore
|
||||
expect_absent .editorconfig
|
||||
expect_file docs/CODE_STYLEGUIDE_GO.md << 'EOF'
|
||||
new CODE_STYLEGUIDE_GO
|
||||
EOF
|
||||
expect_file docs/CODE_STYLEGUIDE_JS.md << 'EOF'
|
||||
new CODE_STYLEGUIDE_JS
|
||||
EOF
|
||||
expect_file docs/CODE_STYLEGUIDE_PYTHON.md << 'EOF'
|
||||
new CODE_STYLEGUIDE_PYTHON
|
||||
EOF
|
||||
expect_new_commit_not_pushed
|
||||
}
|
||||
|
||||
test_language_files_need_a_source_file() {
|
||||
start_scenario "a repo with no source file of a language gets none of its files"
|
||||
commit_and_push_fixture .prettierrc
|
||||
remove_from_fixture cmd .golangci.yml docs/CODE_STYLEGUIDE_GO.md \
|
||||
docs/GO_HTTP_SERVER_CONVENTIONS.md docs/CODE_STYLEGUIDE_JS.md \
|
||||
docs/CODE_STYLEGUIDE_PYTHON.md
|
||||
run_update_policy
|
||||
expect_success
|
||||
expect_absent .golangci.yml
|
||||
expect_absent .prettierrc
|
||||
expect_absent docs/CODE_STYLEGUIDE_GO.md
|
||||
expect_absent docs/GO_HTTP_SERVER_CONVENTIONS.md
|
||||
expect_absent docs/CODE_STYLEGUIDE_JS.md
|
||||
expect_absent docs/CODE_STYLEGUIDE_PYTHON.md
|
||||
expect_new_commit_not_pushed
|
||||
}
|
||||
|
||||
@@ -463,6 +529,19 @@ EOF
|
||||
[ -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"
|
||||
commit_and_push_fixture .prettierrc
|
||||
remove_from_fixture script
|
||||
run_install "$dir/repo"
|
||||
expect_success
|
||||
expect_same_as_canonical script/install
|
||||
expect_same_as_canonical script/update-policy
|
||||
expect_executable script/install
|
||||
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"
|
||||
commit_and_push_fixture .prettierrc
|
||||
@@ -580,6 +659,21 @@ EOF
|
||||
expect_no_commit
|
||||
}
|
||||
|
||||
test_ignored_file_stops() {
|
||||
start_scenario "an ignored file at a listed path is not overwritten"
|
||||
commit_and_push_fixture .prettierrc
|
||||
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"
|
||||
expect_failure
|
||||
expect_output "docs/API_POLICIES.md is ignored by git"
|
||||
expect_file docs/API_POLICIES.md << 'EOF'
|
||||
our own notes
|
||||
EOF
|
||||
expect_no_commit
|
||||
}
|
||||
|
||||
test_own_script_stops() {
|
||||
start_scenario "a tracked script/install with a line the canonical file has never held stops"
|
||||
echo "echo our own installer" >> "$dir/repo/script/install"
|
||||
@@ -731,11 +825,13 @@ test_line_removed_from_another_file_still_stops() {
|
||||
|
||||
main() {
|
||||
test_own_entries_kept
|
||||
test_files_not_carried_are_skipped
|
||||
test_files_the_repo_lacks_are_written_whole
|
||||
test_language_files_need_a_source_file
|
||||
test_nothing_changed
|
||||
test_target_lacking_install_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_failed_fetch_stops
|
||||
@@ -744,6 +840,7 @@ main() {
|
||||
test_own_entry_above_closing_comment
|
||||
test_uncommitted_change_stops
|
||||
test_untracked_script_stops
|
||||
test_ignored_file_stops
|
||||
test_own_script_stops
|
||||
test_gitignore_lacks_canonical_last_line
|
||||
test_fetched_golangci_without_deny_list
|
||||
|
||||
Reference in new issue
Block a user