diff --git a/packages/cli/bin.ts b/packages/cli/bin.ts index 5b071d73..61fc1d3f 100644 --- a/packages/cli/bin.ts +++ b/packages/cli/bin.ts @@ -6,8 +6,9 @@ import { add } from './commands/add/index.ts'; import { create } from './commands/create.ts'; import { migrate } from './commands/migrate.ts'; import { check } from './commands/check.ts'; +import { kit } from './commands/kit.ts'; import { helpConfig } from './utils/common.ts'; program.name(pkg.name).version(pkg.version, '-v, --version').configureHelp(helpConfig); -program.addCommand(create).addCommand(add).addCommand(migrate).addCommand(check); +program.addCommand(create).addCommand(add).addCommand(migrate).addCommand(check).addCommand(kit); program.parse(); diff --git a/packages/cli/commands/check.ts b/packages/cli/commands/check.ts index 23797d20..26f0ecf8 100644 --- a/packages/cli/commands/check.ts +++ b/packages/cli/commands/check.ts @@ -1,46 +1,8 @@ -import process from 'node:process'; -import { execSync } from 'node:child_process'; -import pc from 'picocolors'; -import { Command } from 'commander'; -import * as resolve from 'empathic/resolve'; -import { resolveCommand } from 'package-manager-detector/commands'; -import { getUserAgent } from '../utils/package-manager.ts'; - -export const check = new Command('check') - .description('a CLI for checking your Svelte code') - // flags that we'll want to pass to `svelte-check` - .allowUnknownOption(true) - .option('-C, --cwd ', 'path to working directory', process.cwd()) - .configureHelp({ - formatHelp() { - // we'll pass the responsibility of presenting the help menu over to `svelte-check` - runCheck(process.cwd(), ['--help']); - return ''; - } - }) - .action((options, check: Command) => { - const cwd: string = options.cwd; - const args: string[] = check.args; - - runCheck(cwd, args); - }); - -function runCheck(cwd: string, args: string[]) { - const pm = getUserAgent() ?? 'npm'; - - // validates that `svelte-check` is locally installed - const resolved = resolve.from(cwd, 'svelte-check', true); - if (!resolved) { - const cmd = resolveCommand(pm, 'add', ['-D', 'svelte-check'])!; - console.error( - `'svelte-check' is not installed locally. Install it with: ${pc.bold(`${cmd.command} ${cmd.args.join(' ')}`)}` - ); - process.exit(1); - } - - // avoids printing the stack trace for `sv` when `svelte-check` exits with an error code - try { - const cmd = resolveCommand(pm, 'execute-local', ['svelte-check', ...args])!; - execSync(`${cmd.command} ${cmd.args.join(' ')}`, { stdio: 'inherit', cwd }); - } catch {} -} +import { createCommand } from '../utils/external-package.js'; + +export const check = createCommand( + 'check', + 'svelte-check', + 'svelte-check', + 'a CLI for checking your Svelte code' +); diff --git a/packages/cli/commands/kit.ts b/packages/cli/commands/kit.ts new file mode 100644 index 00000000..98497098 --- /dev/null +++ b/packages/cli/commands/kit.ts @@ -0,0 +1,8 @@ +import { createCommand } from '../utils/external-package.js'; + +export const kit = createCommand( + 'kit', + '@sveltejs/kit', + 'svelte-kit', + 'a CLI for working with your SvelteKit project' +); diff --git a/packages/cli/utils/external-package.ts b/packages/cli/utils/external-package.ts new file mode 100644 index 00000000..d3fe918b --- /dev/null +++ b/packages/cli/utils/external-package.ts @@ -0,0 +1,56 @@ +import process from 'node:process'; +import { execSync } from 'node:child_process'; +import pc from 'picocolors'; +import { Command } from 'commander'; +import * as resolve from 'empathic/resolve'; +import { resolveCommand } from 'package-manager-detector/commands'; +import { getUserAgent } from './package-manager.ts'; + +export function createCommand( + name: string, + package_name: string, + package_binary: string, + description: string +) { + return ( + new Command(name) + .description(description) + // allow options for the external package + .allowUnknownOption(true) + .option('-C, --cwd ', 'path to working directory', process.cwd()) + .configureHelp({ + formatHelp() { + // pass the responsibility of presenting the help menu over to the external package + runPackage(package_name, package_binary, process.cwd(), ['--help']); + return ''; + } + }) + .action((options, check: Command) => { + const cwd: string = options.cwd; + const args: string[] = check.args; + + runPackage(package_name, package_binary, cwd, args); + }) + ); +} + +function runPackage(name: string, binary: string, cwd: string, args: string[]) { + const pm = getUserAgent() ?? 'npm'; + + // validates that the package is locally installed + // try to find package.json as package might not have a main export + const resolved = resolve.from(cwd, `${name}/package.json`, true); + if (!resolved) { + const cmd = resolveCommand(pm, 'add', ['-D', name])!; + console.error( + `'${name}' is not installed locally. Install it with: ${pc.bold(`${cmd.command} ${cmd.args.join(' ')}`)}` + ); + process.exit(1); + } + + // avoids printing the stack trace for `sv` when the external package exits with an error code + try { + const cmd = resolveCommand(pm, 'execute-local', [binary, ...args])!; + execSync(`${cmd.command} ${cmd.args.join(' ')}`, { stdio: 'inherit', cwd }); + } catch {} +}