Skip to content

Auto-manage Laravel installer PHAR#42

Merged
munezaclovis merged 13 commits intomainfrom
feature/managed-packages
Mar 13, 2026
Merged

Auto-manage Laravel installer PHAR#42
munezaclovis merged 13 commits intomainfrom
feature/managed-packages

Conversation

@munezaclovis
Copy link
Copy Markdown
Contributor

Summary

  • Add internal/packages/ module that downloads, installs, and auto-updates managed PHAR packages (starting with laravel/installer)
  • PHARs are downloaded from GitHub releases to ~/.pv/internal/packages/, symlinked into ~/.pv/bin/, with versions tracked in versions.json
  • Background updater goroutine checks for updates every 24h while server runs, with one retry on failure
  • Wired into pv install (per-package progress bar), pv update (per-package status), and server.Start() (background goroutine with context-based shutdown)

Test Plan

  • go test ./internal/packages/ -v — 10 tests covering install, update, version normalization, background updater lifecycle
  • go test ./internal/config/ -run TestPackagesDir -v — PackagesDir path helper
  • go test ./... -timeout 60s — full suite passes (no regressions)
  • go vet ./... and gofmt -l . — clean
  • Manual: pv install shows ✓ laravel v* step
  • Manual: pv update shows ✓ laravel already up to date or ✓ laravel updated to v*

Introduces internal/packages with the Package type, Managed registry (laravel/installer), and path helpers PharPath(), SymlinkPath(), and LatestReleaseURL().
laravel/installer has never published PHAR assets on GitHub releases.
Add dual install method support: MethodComposer (via composer global
require) and MethodPHAR (via GitHub release download). Laravel installer
now uses MethodComposer, landing the binary at ~/.pv/composer/vendor/bin/
which is already on PATH via pv env. PHAR infrastructure remains for
future packages like phpstan and psalm.
- Thread context.Context through Install/Update/composer functions so
  the background updater respects shutdown signals (no more 30s hangs)
- Use exec.CommandContext for composer child processes (no orphans)
- Use http.NewRequestWithContext for GitHub API calls
- Log background updater failures to stderr instead of swallowing
- Context-aware retry delay (select on ctx.Done vs time.After)
- Track package install failures in cmd/install.go (exit non-zero)
- Fix os.Remove to only ignore ErrNotExist, not all errors
- Include GitHub response body in non-200 error messages
- Limit io.ReadAll to 1MB on GitHub API responses
- Make switch statements exhaustive (explicit MethodPHAR + error default)
- Wrap composer exec errors with %w to preserve exit code info
- Add Package.Validate() with init() check for registry correctness
- Guard against empty GitHub release tags
- Improve comment accuracy (Update docs, version field docs)
composer global update does nothing if the package was never added to
the global composer.json. Switch to composer global require which is
idempotent — installs if missing, updates if already present. This
fixes the E2E failure where composer show failed because the package
had never been installed.
CombinedOutput() mixed stderr warnings (e.g. "Changed current
directory to...") into stdout, corrupting JSON output from
composer global show --format=json. Now capture stdout and stderr
separately: return stdout-only on success for clean JSON, combine
them on error for diagnostics.
@munezaclovis munezaclovis merged commit 8c57d57 into main Mar 13, 2026
1 check passed
@munezaclovis munezaclovis deleted the feature/managed-packages branch March 13, 2026 19:11
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.

1 participant