From 504c04d144a2a3e3880c0fa340a2854e9fa18e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arwid=20Thornstro=CC=88m?= Date: Wed, 13 Aug 2025 09:16:41 +0200 Subject: [PATCH] added update command --- src/commands/update/update.ts | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/commands/update/update.ts diff --git a/src/commands/update/update.ts b/src/commands/update/update.ts new file mode 100644 index 0000000..9177c27 --- /dev/null +++ b/src/commands/update/update.ts @@ -0,0 +1,93 @@ +import { GluegunMenuToolbox } from '@lenne.tech/gluegun-menu'; +import chalk = require('chalk'); +import * as fs from 'fs'; +import * as path from 'path'; + +const findPwcliRepoRoot = (): string | null => { + // When compiled, __dirname will be .../build/commands/update + // Repo root is .../ (three levels up from build/commands/update to build, then one more to repo root) + const candidates = [ + path.resolve(__dirname, '../../../..'), // repo root when running from build/commands/update + path.resolve(__dirname, '../../..'), // fallback to build (in case structure differs) + process.cwd(), // last resort + ]; + + for (const candidate of candidates) { + try { + const pkgPath = path.join(candidate, 'package.json'); + if (!fs.existsSync(pkgPath)) continue; + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + if (pkg && pkg.name === 'pwcli') { + return candidate; + } + } catch {} + } + return null; +}; + +module.exports = { + name: 'update', + alias: ['up'], + description: 'Update the pwcli repository to latest main and rebuild (up)', + hidden: false, + run: async (toolbox: GluegunMenuToolbox) => { + const { print, system } = toolbox; + + const runCmd = async (cmd: string, cwd: string) => + await system.run(cmd, { cwd, trim: true }); + + const repoRoot = findPwcliRepoRoot(); + if (!repoRoot) { + print.error( + chalk.red( + 'Unable to locate the pwcli repository. This command only supports updating the pwcli repo.', + ), + ); + process.exit(1); + } + + print.info(`Updating repository: ${chalk.cyan(repoRoot)}`); + + try { + // Ensure we are inside a git repo and on main (or switch to main) + await runCmd('git rev-parse --is-inside-work-tree', repoRoot); + + await runCmd('git fetch origin main', repoRoot); + + try { + await runCmd('git checkout main', repoRoot); + } catch {} + + let behindCountStr = '0'; + try { + behindCountStr = await runCmd( + 'git rev-list --count HEAD..origin/main', + repoRoot, + ); + } catch {} + + const behindCount = parseInt((behindCountStr || '0').trim(), 10) || 0; + + if (behindCount === 0) { + print.success(chalk.green('Everything is up to date.')); + process.exit(0); + return; + } + + print.info( + chalk.yellow(`Updating ${behindCount} commit(s) from origin/main...`), + ); + + await runCmd('git pull --ff-only origin main', repoRoot); + + print.info(chalk.yellow('Running yarn build...')); + await runCmd('yarn build', repoRoot); + + print.success(chalk.green('Update complete. Exiting pwcli...')); + process.exit(0); + } catch (e) { + print.error(chalk.red('Update failed. Please check the logs above.')); + process.exit(1); + } + }, +};