feat: add gsd update subcommand for self-update
Adds a CLI subcommand that checks npm for the latest version and runs `npm install -g gsd-pi@latest` if an update is available. Prints current/latest version and clear success/failure messages.
This commit is contained in:
parent
40e30f61dc
commit
0858092098
2 changed files with 53 additions and 0 deletions
|
|
@ -74,6 +74,7 @@ function parseCliArgs(argv: string[]): CliFlags {
|
|||
process.stdout.write(' --help, -h Print this help and exit\n')
|
||||
process.stdout.write('\nSubcommands:\n')
|
||||
process.stdout.write(' config Re-run the setup wizard\n')
|
||||
process.stdout.write(' update Update GSD to the latest version\n')
|
||||
process.exit(0)
|
||||
} else if (!arg.startsWith('--') && !arg.startsWith('-')) {
|
||||
flags.messages.push(arg)
|
||||
|
|
@ -92,6 +93,13 @@ if (cliFlags.messages[0] === 'config') {
|
|||
process.exit(0)
|
||||
}
|
||||
|
||||
// `gsd update` — update to the latest version via npm
|
||||
if (cliFlags.messages[0] === 'update') {
|
||||
const { runUpdate } = await import('./update-cmd.js')
|
||||
await runUpdate()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// Pi's tool bootstrap can mis-detect already-installed fd/rg on some systems
|
||||
// because spawnSync(..., ["--version"]) returns EPERM despite a zero exit code.
|
||||
// Provision local managed binaries first so Pi sees them without probing PATH.
|
||||
|
|
|
|||
45
src/update-cmd.ts
Normal file
45
src/update-cmd.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { execSync } from 'node:child_process'
|
||||
import { compareSemver } from './update-check.js'
|
||||
|
||||
const NPM_PACKAGE = 'gsd-pi'
|
||||
|
||||
export async function runUpdate(): Promise<void> {
|
||||
const current = process.env.GSD_VERSION || '0.0.0'
|
||||
const bold = '\x1b[1m'
|
||||
const dim = '\x1b[2m'
|
||||
const green = '\x1b[32m'
|
||||
const yellow = '\x1b[33m'
|
||||
const reset = '\x1b[0m'
|
||||
|
||||
process.stdout.write(`${dim}Current version:${reset} v${current}\n`)
|
||||
process.stdout.write(`${dim}Checking npm registry...${reset}\n`)
|
||||
|
||||
// Fetch latest version
|
||||
let latest: string
|
||||
try {
|
||||
latest = execSync(`npm view ${NPM_PACKAGE} version`, {
|
||||
encoding: 'utf-8',
|
||||
stdio: ['ignore', 'pipe', 'ignore'],
|
||||
}).trim()
|
||||
} catch {
|
||||
process.stderr.write(`${yellow}Failed to reach npm registry.${reset}\n`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (compareSemver(latest, current) <= 0) {
|
||||
process.stdout.write(`${green}Already up to date.${reset}\n`)
|
||||
return
|
||||
}
|
||||
|
||||
process.stdout.write(`${dim}Updating:${reset} v${current} → ${bold}v${latest}${reset}\n`)
|
||||
|
||||
try {
|
||||
execSync(`npm install -g ${NPM_PACKAGE}@latest`, {
|
||||
stdio: 'inherit',
|
||||
})
|
||||
process.stdout.write(`\n${green}${bold}Updated to v${latest}${reset}\n`)
|
||||
} catch {
|
||||
process.stderr.write(`\n${yellow}Update failed. Try manually: npm install -g ${NPM_PACKAGE}@latest${reset}\n`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue