summaryrefslogtreecommitdiff
path: root/src/cli.ts
blob: 71c9691d766fc0588cf709d1333d3ea9130d265f (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import type { AstroConfig } from './@types/astro';

import * as colors from 'kleur/colors';
import { promises as fsPromises } from 'fs';
import yargs from 'yargs-parser';

import { loadConfig } from './config.js';
import { build } from './build.js';
import devServer from './dev.js';

const { readFile } = fsPromises;
const buildAndExit = async (...args: Parameters<typeof build>) => {
  const ret = await build(...args);
  process.exit(ret);
};

type Arguments = yargs.Arguments;
type cliState = 'help' | 'version' | 'dev' | 'build';

/** Determine which action the user requested */
function resolveArgs(flags: Arguments): cliState {
  if (flags.version) {
    return 'version';
  } else if (flags.help) {
    return 'help';
  }

  const cmd = flags._[2];
  switch (cmd) {
    case 'dev':
      return 'dev';
    case 'build':
      return 'build';
    default:
      return 'help';
  }
}

/** Display --help flag */
function printHelp() {
  console.error(`  ${colors.bold('astro')} - Futuristic web development tool.

  ${colors.bold('Commands:')}
  astro dev         Run Astro in development mode.
  astro build       Build a pre-compiled production version of your site.

  ${colors.bold('Flags:')}
  --version         Show the version number and exit.
  --help            Show this help message.
`);
}

/** Display --version flag */
async function printVersion() {
  const pkg = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf-8'));
  console.error(pkg.version);
}

/** Handle `astro run` command */
async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void>) {
  try {
    const astroConfig = await loadConfig(rawRoot);
    return cmd(astroConfig);
  } catch (err) {
    console.error(colors.red(err.toString() || err));
    process.exit(1);
  }
}

const cmdMap = new Map([
  ['build', buildAndExit],
  ['dev', devServer],
]);

/** The primary CLI action */
export async function cli(args: string[]) {
  const flags = yargs(args);
  const state = resolveArgs(flags);

  switch (state) {
    case 'help': {
      printHelp();
      process.exit(1);
      break;
    }
    case 'version': {
      await printVersion();
      process.exit(0);
      break;
    }
    case 'build':
    case 'dev': {
      const cmd = cmdMap.get(state)!;
      runCommand(flags._[3], cmd);
    }
  }
}