feat: install.sh version gate — --force + per-commit 0.0cN
gates / consistency-and-conventions (push) Successful in 33s
gates / consistency-and-conventions (push) Successful in 33s
Architect-approved (C): install.sh now skips+aborts (exit 0) when the installed version equals the current git-derived version, with a --force flag to re-install. Version scheme 0.0cN (N = git commit count) bumps by construction on every commit. - install_version(): derives 0.0c$count via git rev-list; empty when .git absent (gate skipped); INSTALL_VERSION_OVERRIDE presence-check seam for tests (empty override simulates no-git deterministically) - Gate after arg parse, before phases; numeric comparison (strip 0.0c, -eq); messages: 'Already installed (X). Use --force to re-install.' and '(dry-run) Would skip install: already at version X', both exit 0 - flag_set installed_version after 'Bootstrap complete' banner (not in dry-run, even under --force, never on phase failure) - Docs: SCRIPTS.md flag table + gate description, AGENT_Context line count 248->301 + flags + flow diagram, README --force row, tests/README row, AGENT_TODO Done entry Verified: new tests/t-install-version.sh 21 checks (9 contracted cases, real install.sh + hermetic env seams); suite 20 files / 461 checks / 0 fail / 0 skip; make gen byte-idempotent; make check OK; make lint 0 FAIL, 0 WARN; bash -n clean; git diff --check clean; Reviewer APPROVE_WITH_NOTES with 3 mutation disproofs (8/21, 9/21, 4/21 fail)
This commit is contained in:
@@ -11,18 +11,18 @@
|
||||
<!-- GEN:START docmap -->
|
||||
| ## 1. Project Overview | 28–43 |
|
||||
| ## 2. Directory Structure | 44–210 |
|
||||
| ## 3. Installation Flow | 211–264 |
|
||||
| ## 4. The `pos` CLI System | 265–346 |
|
||||
| ## 5. Shared Library — `lib/common.sh` | 347–378 |
|
||||
| ## 6. Docker Compose / ScaleTail | 379–421 |
|
||||
| ## 7. Optional Apps (`apps/`) | 422–451 |
|
||||
| ## 8. Entertainment Module | 452–465 |
|
||||
| ## 9. Systemd Services | 466–477 |
|
||||
| ## 10. Configuration Files | 478–504 |
|
||||
| ## 11. Coding Conventions | 505–537 |
|
||||
| ## 12. Development Workflow | 538–590 |
|
||||
| ## 13. Key File Quick Reference | 591–666 |
|
||||
| ## 14. Common Tasks for Agents | 667–700 |
|
||||
| ## 3. Installation Flow | 211–269 |
|
||||
| ## 4. The `pos` CLI System | 270–351 |
|
||||
| ## 5. Shared Library — `lib/common.sh` | 352–383 |
|
||||
| ## 6. Docker Compose / ScaleTail | 384–426 |
|
||||
| ## 7. Optional Apps (`apps/`) | 427–456 |
|
||||
| ## 8. Entertainment Module | 457–470 |
|
||||
| ## 9. Systemd Services | 471–482 |
|
||||
| ## 10. Configuration Files | 483–509 |
|
||||
| ## 11. Coding Conventions | 510–542 |
|
||||
| ## 12. Development Workflow | 543–595 |
|
||||
| ## 13. Key File Quick Reference | 596–671 |
|
||||
| ## 14. Common Tasks for Agents | 672–705 |
|
||||
<!-- GEN:END docmap -->
|
||||
|
||||
## 1. Project Overview
|
||||
@@ -211,7 +211,11 @@ Linux_post_install/
|
||||
## 3. Installation Flow
|
||||
|
||||
```
|
||||
User runs: ./install.sh [--apps|--full|--feature|--dry-run|--skip <phase>|--steps <spec>]
|
||||
User runs: ./install.sh [--apps|--full|--feature|--dry-run|--force|--skip <phase>|--steps <spec>]
|
||||
│
|
||||
├─ Version gate: compares installed version (flag) vs current (0.0c<commit count>)
|
||||
│ └─ match + no --force → "Already installed. Use --force to re-install." / exit 0
|
||||
│ (--dry-run variant prints "Would skip install"); no git or no flag → skip gate
|
||||
│
|
||||
├─ Phase 1: preinstall.sh (requires root)
|
||||
│ └─ apt update + installs 25+ packages + yt-dlp + fail2ban
|
||||
@@ -249,6 +253,7 @@ User runs: ./install.sh [--apps|--full|--feature|--dry-run|--skip <phase>|--step
|
||||
| `--full` | Core install + all apps (non-interactive) |
|
||||
| `--feature` | Install `features/` scripts to `/usr/local/bin/` (asks before overwriting), set their flags |
|
||||
| `--dry-run` | Preview without executing |
|
||||
| `--force` | Re-install even if the version matches |
|
||||
| `--skip <phase>` | Skip a phase (repeatable): `preinstall`, `scripts`, `postinstall`, `scalepoint`, `apps` |
|
||||
| `--steps <spec>` | Run only specific phases. Format: `1,3,4` or `1-3` |
|
||||
| `--no-color` | Disable colored output |
|
||||
@@ -592,7 +597,7 @@ Use conventional prefixes: `feat:`, `fix:`, `docs:`, `refactor:`, `chore:`
|
||||
|
||||
| File | Lines | Purpose |
|
||||
|------|-------|---------|
|
||||
| `install.sh` | 248 | Main orchestrator — 4 phases with CLI flags, `--feature`, prebuilt arch bins |
|
||||
| `install.sh` | 301 | Main orchestrator — 4 phases with CLI flags, `--feature`, `--force`, version gate, prebuilt arch bins |
|
||||
| `preinstall.sh` | 76 | System packages + hotspot deps + yt-dlp + fail2ban |
|
||||
| `postinstall.sh` | 168 | fail2ban config, PATH, bash completion, systemd (flag-gated) |
|
||||
| `lib/common.sh` | 151 | Shared library (log/warn/err/run/spawn, dry-run aware, `load_system_env`, CONFIG_DIR) |
|
||||
|
||||
+3
-1
@@ -34,7 +34,8 @@ Everything that runs during the bootstrap install: `install.sh`, `preinstall.sh`
|
||||
1. **Pre-parse `--no-color`** before anything else, so colors are disabled early (`TERM=dumb` is exported).
|
||||
2. Source `lib/common.sh` (logging, `run`, `spawn`, …) and `lib/flags.sh` (feature flags).
|
||||
3. Parse CLI options.
|
||||
4. For each phase, `should_run <num> <name>` decides whether to run it:
|
||||
4. **Version gate:** derive the current version (`0.0c<git commit count>` via `install_version()`; empty when `.git` is absent). If the installed version (stored as the `installed_version` flag) matches and `--force` is not given, skip the install — with `--dry-run` it prints `(dry-run) Would skip install: already at version <v>`, otherwise `Already installed (<v>). Use --force to re-install.` and exits 0. When no `installed_version` flag exists or the current version cannot be determined (no `.git`), the gate is skipped.
|
||||
5. For each phase, `should_run <num> <name>` decides whether to run it:
|
||||
- `--skip <phase>` removes a phase (takes precedence).
|
||||
- `--steps <spec>` restricts the run to the listed phases only (`1,3,4` or `1-3`).
|
||||
- Phase map: `1=preinstall`, `2=scripts`, `3=postinstall`, `4=scalepoint` (+ `apps` handled separately).
|
||||
@@ -63,6 +64,7 @@ No config file — everything is command-line:
|
||||
| `--full` | Core install + every app (non-interactive) |
|
||||
| `--feature` | Install `features/` scripts to `/usr/local/bin/` (prompts on overwrite), sets their flags |
|
||||
| `--dry-run` | Log every action instead of executing. **Note:** applies to `install.sh` itself; `postinstall.sh` runs as a subprocess and does not inherit `DRY_RUN` |
|
||||
| `--force` | Re-install even if the version matches |
|
||||
| `--skip <phase>` | Skip a phase (repeatable): `preinstall`, `scripts`, `postinstall`, `scalepoint`, `apps` |
|
||||
| `--steps <spec>` | Run only listed phases: `1,3,4` or `1-3` |
|
||||
| `--no-color` | Disable colored output |
|
||||
|
||||
Reference in New Issue
Block a user