diff options
Diffstat (limited to 'tree-sitter/dsk/dsk-cli/src/commands/self.ts')
-rw-r--r-- | tree-sitter/dsk/dsk-cli/src/commands/self.ts | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/tree-sitter/dsk/dsk-cli/src/commands/self.ts b/tree-sitter/dsk/dsk-cli/src/commands/self.ts new file mode 100644 index 0000000..2b43fd6 --- /dev/null +++ b/tree-sitter/dsk/dsk-cli/src/commands/self.ts @@ -0,0 +1,71 @@ +/** + * Self Packaging Command - Build and package the dsk CLI for distribution + */ + +import { Command } from 'commander'; +import chalk from 'chalk'; +import { execa } from 'execa'; +import { existsSync, mkdirSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +/** + * Create the self:package command + */ +export function createSelfPackageCommand(): Command { + const cmd = new Command('self:package'); + + cmd + .description('Build and package the dsk CLI into a .tgz for distribution') + .option('-v, --verbose', 'Show detailed build output') + .action(async (options) => { + const projectRoot = resolveProjectRoot(); + if (!existsSync(join(projectRoot, 'package.json'))) { + console.error(chalk.red('❌ Could not locate package.json for dsk-cli')); + process.exit(1); + } + + const pkg = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf-8')); + console.log(chalk.blue(`📦 Packaging ${pkg.name}@${pkg.version}`)); + + // 1) Build TypeScript → dist + console.log(chalk.blue('🏗️ Building CLI...')); + await execa('bun', ['x', 'tsc'], { cwd: projectRoot, stdio: options.verbose ? 'inherit' : 'inherit' }); + + // 2) Pack npm tarball using bun pack (fallback to npm pack) + console.log(chalk.blue('🧰 Creating package tarball...')); + let tgzName = ''; + try { + const { stdout } = await execa('bun', ['pack'], { cwd: projectRoot }); + tgzName = stdout.trim().split(/\s|\n/).pop() || ''; + } catch { + const { stdout } = await execa('npm', ['pack'], { cwd: projectRoot }); + tgzName = stdout.trim().split(/\s|\n/).pop() || ''; + } + + if (!tgzName) { + console.error(chalk.red('❌ Failed to determine generated package filename')); + process.exit(1); + } + + const releaseDir = join(projectRoot, 'release'); + mkdirSync(releaseDir, { recursive: true }); + const src = join(projectRoot, tgzName); + const dest = join(releaseDir, tgzName); + await execa('bash', ['-lc', `mv -f ${JSON.stringify(src)} ${JSON.stringify(dest)}`]); + + console.log(chalk.green(`✅ Created ${dest}`)); + }); + + return cmd; +} + +function resolveProjectRoot(): string { + const __filename = fileURLToPath(import.meta.url); + const __dirname = dirname(__filename); + // When compiled, this file lives under dist/commands. Project root is two levels up. + const candidate = join(__dirname, '..', '..'); + return candidate; +} + + |