UNPKG

linear-cmd

Version:

A GitHub CLI-like tool for Linear - manage issues, accounts, and more

141 lines (140 loc) 5.09 kB
import { exec } from 'child_process'; import { Command } from 'commander'; import { readFileSync } from 'fs'; import { platform } from 'os'; import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; import { promisify } from 'util'; import { Logger } from '../lib/logger.js'; const execAsync = promisify(exec); const __dirname = dirname(fileURLToPath(import.meta.url)); export function createUpdateCommand() { return new Command('update').description('Update the linear-cmd package to the latest version').action(async () => { try { Logger.loading('Checking current version...'); const currentVersion = getCurrentVersion(); if (!currentVersion) { Logger.error('Could not determine current version'); return; } Logger.loading('Checking latest version...'); const latestVersion = await getLatestVersion(); if (!latestVersion) { Logger.error('Could not fetch latest version from npm'); return; } Logger.info(`📦 Current version: ${currentVersion}`); Logger.info(`📦 Latest version: ${latestVersion}`); if (currentVersion === latestVersion) { Logger.success('linear-cmd is already up to date!'); return; } Logger.loading('Detecting package manager...'); const packageManager = await detectPackageManager(); if (!packageManager) { Logger.error('Could not detect how linear-cmd was installed'); Logger.dim('Please update manually using your package manager'); return; } Logger.info(`📦 Detected package manager: ${packageManager}`); Logger.loading(`Updating linear-cmd from ${currentVersion} to ${latestVersion}...`); const updateCommand = getUpdateCommand(packageManager); const { stdout, stderr } = await execAsync(updateCommand); if (stderr && !stderr.includes('npm WARN')) { Logger.error(`Error updating: ${stderr}`); return; } Logger.success(`linear-cmd updated successfully from ${currentVersion} to ${latestVersion}!`); if (stdout) { Logger.dim(stdout); } } catch (error) { Logger.error('Error updating', error); } }); } async function detectPackageManager() { const npmPath = await getGlobalNpmPath(); if (!npmPath) { return null; } const possiblePaths = [ { manager: 'npm', patterns: ['/npm/', '\\npm\\', '/node/', '\\node\\'] }, { manager: 'yarn', patterns: ['/yarn/', '\\yarn\\', '/.yarn/', '\\.yarn\\'] }, { manager: 'pnpm', patterns: ['/pnpm/', '\\pnpm\\', '/.pnpm/', '\\.pnpm\\'] } ]; for (const { manager, patterns } of possiblePaths) { if (patterns.some((pattern) => npmPath.includes(pattern))) { return manager; } } // Default to npm if we can't determine return 'npm'; } async function getGlobalNpmPath() { const isWindows = platform() === 'win32'; try { // Try to find the linear-cmd executable const whereCommand = isWindows ? 'where' : 'which'; const { stdout } = await execAsync(`${whereCommand} linear-cmd`); const execPath = stdout.trim(); if (execPath) { // On Unix systems, this might be a symlink, so resolve it if (!isWindows) { try { const { stdout: realPath } = await execAsync(`readlink -f "${execPath}"`); return realPath.trim() || execPath; } catch { return execPath; } } return execPath; } } catch { // If which/where fails, try npm list try { const { stdout } = await execAsync('npm list -g --depth=0 linear-cmd'); if (stdout.includes('linear-cmd')) { return 'npm'; } } catch { // Continue to other methods } } return null; } function getCurrentVersion() { try { const packagePath = join(__dirname, '../../package.json'); const packageJson = JSON.parse(readFileSync(packagePath, 'utf8')); return packageJson.version; } catch { return null; } } async function getLatestVersion() { try { const { stdout } = await execAsync('npm view linear-cmd version'); return stdout.trim(); } catch { return null; } } function getUpdateCommand(packageManager) { switch (packageManager) { case 'npm': return 'npm update -g linear-cmd'; case 'yarn': return 'yarn global upgrade linear-cmd'; case 'pnpm': return 'pnpm update -g linear-cmd'; default: return 'npm update -g linear-cmd'; } }