Skip to content

Commit

Permalink
Add a proper cli
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp committed Mar 15, 2021
1 parent 47d1c22 commit 39ce064
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 33 deletions.
30 changes: 2 additions & 28 deletions astro.mjs
Original file line number Diff line number Diff line change
@@ -1,30 +1,4 @@
#!/usr/bin/env node
import { join as pathJoin, resolve as pathResolve } from 'path';
import { cli } from './lib/cli.js';

import generate from './lib/generate.js';
import devServer from './lib/dev.js';

const root = pathResolve(process.argv[2]);

if(!root) {
console.error('Must provide a project root');
process.exit(1);
}

const fileProtocolRoot = `file:https://${root}/`;

async function run() {
const astroConfig = (await import(pathJoin(root, 'astro.config.mjs'))).default;
astroConfig.projectRoot = new URL(astroConfig.projectRoot + '/', fileProtocolRoot);
astroConfig.hmxRoot = new URL(astroConfig.hmxRoot + '/', fileProtocolRoot);


// Should use an args parser eventually
if(process.argv.includes('--generate')) {
return generate(astroConfig);
} else {
return devServer(astroConfig);
}
}

run().catch(err => setTimeout(() => {throw err}));
cli(process.argv);
16 changes: 13 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "astro",
"version": "1.0.0",
"version": "0.0.1",
"main": "index.js",
"private": true,
"author": "Skypack",
Expand Down Expand Up @@ -30,16 +30,19 @@
"es-module-lexer": "^0.4.1",
"gray-matter": "^4.0.2",
"htmlparser2": "^6.0.0",
"kleur": "^4.1.4",
"magic-string": "^0.25.3",
"micromark": "^2.11.4",
"micromark-extension-gfm": "^0.3.3",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"snowpack": "^3.1.0-pre.12",
"svelte": "^3.35.0",
"vue": "^3.0.7"
"vue": "^3.0.7",
"yargs-parser": "^20.2.7"
},
"devDependencies": {
"@types/yargs-parser": "^20.2.0",
"copyfiles": "^2.4.1",
"estree-walker": "^3.0.0",
"preact": "^10.5.12",
Expand Down
105 changes: 105 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import type { AstroConfig } from './@types/astro';

import * as colors from 'kleur/colors';
import { join as pathJoin, resolve as pathResolve } from 'path';
import { existsSync, promises as fsPromises } from 'fs';
import yargs from 'yargs-parser';

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 loadConfig(rawRoot: string | undefined): Promise<AstroConfig | undefined> {
if(typeof rawRoot === 'undefined') {
rawRoot = process.cwd();
}

const root = pathResolve(rawRoot);
const fileProtocolRoot = `file:https://${root}/`;
const astroConfigPath = pathJoin(root, 'astro.config.mjs');

if(!existsSync(astroConfigPath)) {
return undefined;
}

const astroConfig: AstroConfig = (await import(astroConfigPath)).default;
astroConfig.projectRoot = new URL(astroConfig.projectRoot + '/', fileProtocolRoot);
astroConfig.hmxRoot = new URL(astroConfig.hmxRoot + '/', fileProtocolRoot);
return astroConfig;
}

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

0 comments on commit 39ce064

Please sign in to comment.