Skip to content

Make install.sh run unattended and survive a reinstall - #208

Merged
dmccoystephenson merged 1 commit into
mainfrom
feature/install-sh-rerunnable
Sep 30, 2026
Merged

dmccoystephenson merged 1 commit into
mainfrom
feature/install-sh-rerunnable

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

  • install.sh now starts with #!/bin/sh and set -e, so it names its shell and stops at the first failed step. Before this change, if the git install was declined, /bin/fishe was still written and pointed at a directory that was never cloned.
  • /usr/games is created with mkdir -p, so the File exists error no longer appears on Debian/Ubuntu, where the directory is normally present already.
  • apt-get install -y git removes the confirmation prompt that stopped non-interactive runs.
  • If /usr/games/FishE/.git already exists, the clone is updated with git -C … pull and not cloned again, so the script can be run a second time.
  • tests/test_installScript.py checks these points by reading the script's text, following the approach in tests/test_shellEntryPoints.py. The script needs root and changes /usr/games and /bin, so neither the suite nor CI can run it.
  • The install line in the README now says the script runs without prompting and can be run again.

Closes #205

Test plan

  • Full suite run under the dummy SDL drivers (in-process os.environ + pytest.main): 923 passed
  • With install.sh stashed back to main's version, all 5 new tests fail. With the change restored, they pass.
  • sh -n install.sh returns 0
  • Not verified: the script was not run end to end as root on a real Debian host. No automated coverage exists for that path, so a first install followed by a reinstall on a scratch VM is recommended before relying on it.

This PR description was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).

🤖 Generated with Claude Code


drafted by Claude on behalf of Daniel Stephenson

Add a #!/bin/sh shebang and set -e, create /usr/games with mkdir -p,
install git with apt-get -y, and pull an existing clone instead of
failing on git clone. Assert the contract from tests/test_installScript.py,
since the script needs root and can't be run by the suite or CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dmccoystephenson

Copy link
Copy Markdown
Member Author

Self-review rubric (CI run 36687265692 green on the PR head):

  • Scope: PASS. There are three files: install.sh (the fix), tests/test_installScript.py (its tests), and one README sentence describing the new behavior. No unrelated churn is included.
  • Tests-new: PASS. No new public functions were added. Each of the four points in install.sh: stops at an apt prompt, errors on an existing /usr/games, and fails on reinstall #205 (shebang, set -e, mkdir -p, apt-get -y, the existing-clone branch) has its own test.
  • Tests-fix: PASS. With install.sh stashed back to main's version, all 5 tests in tests/test_installScript.py failed. After git stash pop, they all passed.
  • Sibling structure: PASS. The new test file follows tests/test_shellEntryPoints.py: a module docstring stating the contract, a REPOSITORY_ROOT file reader, comment-stripping so a comment can't satisfy a test, and # prepare / # call / # check.
  • Sibling renames: PASS. No renames.
  • Docs: PASS. README.md:27 now says the script runs without prompting and can be run again. No schema, PLANNING.md or version change is needed for an installer-only change.
  • Issue resolution: PASS. Every item listed in install.sh: stops at an apt prompt, errors on an existing /usr/games, and fails on reinstall #205 is changed in install.sh.
  • CI: PASS. test is green (923 tests locally, full suite in CI).
  • Schema-sync / Money-format / Deterministic-tests / Headless-pygame: not applicable. No persisted field, money display, randomness or pygame path is touched.
  • camelCase: PASS. The helpers are readInstallScript and commandLines.

Notes:

  • install.sh:14 — the existing-install check looks for $INSTALL_DIR/.git. If /usr/games/FishE exists but is not a clone, git clone still fails, and set -e now stops the script before /bin/fishe is written. This is the intended behavior: a directory that is not a clone is not overwritten.
  • Coverage gap: CI cannot run install.sh, since it needs root, apt and writes to /bin. The tests check the script's text, not its behavior. sh -n install.sh passes. A real first install followed by a reinstall on a Debian host is still recommended.
  • Out-of-diff finding, filed separately: run.sh's first line is # /bin/bash, a comment and not a shebang, and the script uses the bash-only &>. Under dash, if ! command -v python3 &> /dev/null takes the "Python could not be found" branch even when Python is installed. This was reproduced with dash -c. It is outside install.sh: stops at an apt prompt, errors on an existing /usr/games, and fails on reinstall #205's scope.

This review was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).


drafted by Claude on behalf of Daniel Stephenson

@dmccoystephenson
dmccoystephenson merged commit 0ad4191 into main Sep 30, 2026
1 check passed
@dmccoystephenson
dmccoystephenson deleted the feature/install-sh-rerunnable branch September 30, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

install.sh: stops at an apt prompt, errors on an existing /usr/games, and fails on reinstall

1 participant