about summary refs log tree commit diff stats
path: root/tree-sitter/dsk/dsk-cli/src/commands/package.ts
blob: 515c2ce45373842b875b235222c28b856e25e6d2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
 * Package Command - Create distributable artifacts for C and JS outputs
 */

import { Command } from 'commander';
import chalk from 'chalk';
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
import { join } from 'path';
import { execa } from 'execa';

/**
 * Create the package command
 */
export function createPackageCommand(): Command {
  const pkgCommand = new Command('package');

  pkgCommand
    .description('Package C and JS artifacts into distributable archives')
    .action(async () => {
      if (!existsSync('grammar.js')) {
        console.error(chalk.red('❌ No grammar.js found. Are you in a DSL project directory?'));
        process.exit(1);
      }

      console.log(chalk.blue('📦 Packaging artifacts...'));

      // Ensure build is up to date
      await execa('dsk', ['build'], { stdio: 'inherit' });

      const distDir = 'dist';
      mkdirSync(distDir, { recursive: true });

      // Zip C outputs (simple tar.gz using system tar to avoid extra deps)
      const cDir = 'generated/c';
      if (existsSync(cDir)) {
        const cArchive = join(distDir, 'c-artifacts.tar.gz');
        await execa('tar', ['-czf', cArchive, '-C', 'generated', 'c'], { stdio: 'inherit' });
        console.log(chalk.green(`✅ C artifacts: ${cArchive}`));
      }

      // Pack JS package
      const jsDir = 'generated/js';
      if (existsSync(jsDir)) {
        // Prefer bun pack, fallback to npm pack
        let pkgPath = '';
        try {
          const { stdout } = await execa('bun', ['pack'], { cwd: jsDir });
          pkgPath = stdout.trim();
        } catch {
          const { stdout } = await execa('npm', ['pack'], { cwd: jsDir });
          pkgPath = stdout.trim();
        }
        const fileName = pkgPath.split(/\s|\n/).pop() as string;
        const srcPath = join(jsDir, fileName);
        const destPath = join(distDir, fileName);
        await execa('bash', ['-lc', `cp ${JSON.stringify(srcPath)} ${JSON.stringify(destPath)}`]);
        console.log(chalk.green(`✅ JS package: ${destPath}`));
      }

      console.log(chalk.blue('🎉 Packaging complete.'));
    });

  return pkgCommand;
}