|
| 1 | +import { chmodSync, copyFileSync, existsSync, readdirSync } from 'fs'; |
| 2 | +import { GluegunCommand } from 'gluegun'; |
| 3 | +import { join } from 'path'; |
| 4 | + |
| 5 | +import { ExtendedGluegunToolbox } from '../../interfaces/extended-gluegun-toolbox'; |
| 6 | + |
| 7 | +/** |
| 8 | + * Install git helper scripts to /usr/local/bin |
| 9 | + */ |
| 10 | +const NewCommand: GluegunCommand = { |
| 11 | + alias: ['is'], |
| 12 | + description: 'Install git helper scripts (gitget, gitgets, gitgett) to /usr/local/bin', |
| 13 | + hidden: false, |
| 14 | + name: 'install-scripts', |
| 15 | + run: async (toolbox: ExtendedGluegunToolbox) => { |
| 16 | + const { |
| 17 | + helper, |
| 18 | + print: { error, info, spin, success }, |
| 19 | + system: { startTimer }, |
| 20 | + } = toolbox; |
| 21 | + |
| 22 | + // Start timer |
| 23 | + const timer = startTimer(); |
| 24 | + |
| 25 | + // Source directory (relative to built CLI) |
| 26 | + const sourceDir = join(__dirname, '..', '..', 'templates', 'bash-scripts', 'git'); |
| 27 | + const targetDir = '/usr/local/bin'; |
| 28 | + |
| 29 | + // Check if source directory exists |
| 30 | + if (!existsSync(sourceDir)) { |
| 31 | + error(`Source directory not found: ${sourceDir}`); |
| 32 | + return process.exit(1); |
| 33 | + } |
| 34 | + |
| 35 | + // Check if target directory exists |
| 36 | + if (!existsSync(targetDir)) { |
| 37 | + error(`Target directory not found: ${targetDir}`); |
| 38 | + info('You may need to create it first: sudo mkdir -p /usr/local/bin'); |
| 39 | + return process.exit(1); |
| 40 | + } |
| 41 | + |
| 42 | + // Get all script files |
| 43 | + const scripts = readdirSync(sourceDir).filter(file => !file.startsWith('.')); |
| 44 | + |
| 45 | + if (scripts.length === 0) { |
| 46 | + error('No scripts found to install.'); |
| 47 | + return process.exit(1); |
| 48 | + } |
| 49 | + |
| 50 | + info(`Installing ${scripts.length} script${scripts.length > 1 ? 's' : ''} to ${targetDir}...`); |
| 51 | + info(''); |
| 52 | + |
| 53 | + const installed: string[] = []; |
| 54 | + const failed: string[] = []; |
| 55 | + |
| 56 | + for (const script of scripts) { |
| 57 | + const sourcePath = join(sourceDir, script); |
| 58 | + const targetPath = join(targetDir, script); |
| 59 | + const spinner = spin(`Installing ${script}`); |
| 60 | + |
| 61 | + try { |
| 62 | + // Copy file |
| 63 | + copyFileSync(sourcePath, targetPath); |
| 64 | + |
| 65 | + // Set executable permissions (rwxr-xr-x = 0o755) |
| 66 | + chmodSync(targetPath, 0o755); |
| 67 | + |
| 68 | + spinner.succeed(`Installed ${script}`); |
| 69 | + installed.push(script); |
| 70 | + } catch (err) { |
| 71 | + spinner.fail(`Failed to install ${script}`); |
| 72 | + if (err.code === 'EACCES') { |
| 73 | + error(` Permission denied. Try running with sudo: sudo lt git install-scripts`); |
| 74 | + } else { |
| 75 | + error(` ${err.message}`); |
| 76 | + } |
| 77 | + failed.push(script); |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + // Summary |
| 82 | + info(''); |
| 83 | + if (failed.length === 0) { |
| 84 | + success(`${installed.length} script${installed.length > 1 ? 's' : ''} installed in ${helper.msToMinutesAndSeconds(timer())}m.`); |
| 85 | + } else { |
| 86 | + error(`${installed.length} installed, ${failed.length} failed.`); |
| 87 | + } |
| 88 | + |
| 89 | + if (installed.length > 0) { |
| 90 | + info(''); |
| 91 | + info('Installed scripts:'); |
| 92 | + const descriptions: Record<string, string> = { |
| 93 | + gitget: 'lt git get - checkout branch', |
| 94 | + gitgets: 'lt git get + npm start', |
| 95 | + gitgett: 'lt git get + lint + test + test:e2e', |
| 96 | + }; |
| 97 | + for (const script of installed) { |
| 98 | + const desc = descriptions[script] || 'run from anywhere in terminal'; |
| 99 | + info(` ${script} - ${desc}`); |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + info(''); |
| 104 | + |
| 105 | + if (!toolbox.parameters.options.fromGluegunMenu) { |
| 106 | + process.exit(failed.length > 0 ? 1 : 0); |
| 107 | + } |
| 108 | + |
| 109 | + return 'scripts installed'; |
| 110 | + }, |
| 111 | +}; |
| 112 | + |
| 113 | +export default NewCommand; |
0 commit comments