summaryrefslogtreecommitdiff
path: root/src/cli.ts
blob: 0a5c9612d62d9da0be43db2d2555328f154b62a1 (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
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 generate from './generate.js';
import devServer from './dev.js';

const { readFile } = fsPromises;

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

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';
  }
}

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.
`);
}

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

async function runCommand(rawRoot: string, cmd: (a: AstroConfig) => Promise<void>) {
  const astroConfig = await loadConfig(rawRoot);
  if (typeof astroConfig === 'undefined') {
    console.error(colors.red('  An astro.config.mjs file is required.\n'));
    printHelp();
    process.exit(1);
  }

  return cmd(astroConfig);
}

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

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);
    }
  }
}