summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fred K. Schott <fkschott@gmail.com> 2022-01-25 15:07:51 -0800
committerGravatar GitHub <noreply@github.com> 2022-01-25 15:07:51 -0800
commitc70c4ea2112db164eaecfa1198b73e185b6c57db (patch)
tree11880c9feb51b8e5312addff2a58d2346fe80e91
parent831a9adc209a9ebeb882441c71baaa6ad5be742b (diff)
downloadastro-c70c4ea2112db164eaecfa1198b73e185b6c57db.tar.gz
astro-c70c4ea2112db164eaecfa1198b73e185b6c57db.tar.zst
astro-c70c4ea2112db164eaecfa1198b73e185b6c57db.zip
clean up config loading and flag merging (#2469)
-rw-r--r--packages/astro/src/@types/astro.ts17
-rw-r--r--packages/astro/src/cli/index.ts88
-rw-r--r--packages/astro/src/core/config.ts45
3 files changed, 79 insertions, 71 deletions
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 805317dfc..abe62b13a 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -19,6 +19,18 @@ export interface AstroComponentMetadata {
componentExport?: { value: string; namespace?: boolean };
}
+/** The flags supported by the Astro CLI */
+export interface CLIFlags {
+ projectRoot?: string;
+ site?: string;
+ sitemap?: boolean;
+ hostname?: string;
+ port?: number;
+ config?: string;
+ experimentalStaticBuild?: boolean;
+ drafts?: boolean;
+}
+
/**
* Astro.* available in all components
* Docs: https://docs.astro.build/reference/api-reference/#astro-global
@@ -115,6 +127,11 @@ export interface AstroUserConfig {
* Default: false
*/
drafts?: boolean;
+ /**
+ * Experimental: Enables "static build mode" for faster builds.
+ * Default: false
+ */
+ experimentalStaticBuild?: boolean;
};
/** Options for the development server run with `astro dev`. */
devOptions?: {
diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts
index 0031a08ae..e764e96b7 100644
--- a/packages/astro/src/cli/index.ts
+++ b/packages/astro/src/cli/index.ts
@@ -15,54 +15,7 @@ import { check } from './check.js';
import { formatConfigError, loadConfig } from '../core/config.js';
type Arguments = yargs.Arguments;
-type cliCommand = 'help' | 'version' | 'dev' | 'build' | 'preview' | 'reload' | 'check';
-interface CLIState {
- cmd: cliCommand;
- options: {
- projectRoot?: string;
- site?: string;
- sitemap?: boolean;
- hostname?: string;
- port?: number;
- config?: string;
- experimentalStaticBuild?: boolean;
- drafts?: boolean;
- };
-}
-
-/** Determine which action the user requested */
-function resolveArgs(flags: Arguments): CLIState {
- const options: CLIState['options'] = {
- projectRoot: typeof flags.projectRoot === 'string' ? flags.projectRoot : undefined,
- site: typeof flags.site === 'string' ? flags.site : undefined,
- sitemap: typeof flags.sitemap === 'boolean' ? flags.sitemap : undefined,
- port: typeof flags.port === 'number' ? flags.port : undefined,
- config: typeof flags.config === 'string' ? flags.config : undefined,
- hostname: typeof flags.hostname === 'string' ? flags.hostname : undefined,
- experimentalStaticBuild: typeof flags.experimentalStaticBuild === 'boolean' ? flags.experimentalStaticBuild : false,
- drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
- };
-
- if (flags.version) {
- return { cmd: 'version', options };
- } else if (flags.help) {
- return { cmd: 'help', options };
- }
-
- const cmd = flags._[2];
- switch (cmd) {
- case 'dev':
- return { cmd: 'dev', options };
- case 'build':
- return { cmd: 'build', options };
- case 'preview':
- return { cmd: 'preview', options };
- case 'check':
- return { cmd: 'check', options };
- default:
- return { cmd: 'help', options };
- }
-}
+type CLICommand = 'help' | 'version' | 'dev' | 'build' | 'preview' | 'reload' | 'check';
/** Display --help flag */
function printHelp() {
@@ -95,24 +48,28 @@ async function printVersion() {
console.log(pkgVersion);
}
-/** Merge CLI flags & config options (CLI flags take priority) */
-function mergeCLIFlags(astroConfig: AstroConfig, flags: CLIState['options']) {
- if (typeof flags.sitemap === 'boolean') astroConfig.buildOptions.sitemap = flags.sitemap;
- if (typeof flags.site === 'string') astroConfig.buildOptions.site = flags.site;
- if (typeof flags.port === 'number') astroConfig.devOptions.port = flags.port;
- if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
- if (typeof flags.experimentalStaticBuild === 'boolean') astroConfig.buildOptions.experimentalStaticBuild = flags.experimentalStaticBuild;
- if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
+/** Determine which command the user requested */
+function resolveCommand(flags: Arguments): CLICommand {
+ if (flags.version) {
+ return 'version';
+ } else if (flags.help) {
+ return 'help';
+ }
+ const cmd = flags._[2];
+ const supportedCommands = new Set(['dev', 'build', 'preview', 'check']);
+ if (supportedCommands.has(cmd)) {
+ return cmd as 'dev' | 'build' | 'preview' | 'check';
+ }
+ return 'help';
}
/** The primary CLI action */
export async function cli(args: string[]) {
const flags = yargs(args);
- const state = resolveArgs(flags);
- const options = { ...state.options };
- const projectRoot = options.projectRoot || flags._[3];
+ const cmd = resolveCommand(flags);
+ const projectRoot = flags.projectRoot || flags._[3];
- switch (state.cmd) {
+ switch (cmd) {
case 'help':
printHelp();
return process.exit(0);
@@ -131,8 +88,7 @@ export async function cli(args: string[]) {
if (flags.silent) logging.level = 'silent';
let config: AstroConfig;
try {
- config = await loadConfig({ cwd: projectRoot, filename: options.config });
- mergeCLIFlags(config, options);
+ config = await loadConfig({ cwd: projectRoot, flags });
} catch (err) {
if (err instanceof z.ZodError) {
console.error(formatConfigError(err));
@@ -142,7 +98,7 @@ export async function cli(args: string[]) {
process.exit(1);
}
- switch (state.cmd) {
+ switch (cmd) {
case 'dev': {
try {
await devServer(config, { logging });
@@ -154,6 +110,7 @@ export async function cli(args: string[]) {
return;
}
+
case 'build': {
try {
await build(config, { logging });
@@ -163,10 +120,12 @@ export async function cli(args: string[]) {
}
return;
}
+
case 'check': {
const ret = await check(config);
return process.exit(ret);
}
+
case 'preview': {
try {
await preview(config, { logging }); // this will keep running
@@ -175,8 +134,9 @@ export async function cli(args: string[]) {
}
return;
}
+
default: {
- throw new Error(`Error running ${state.cmd}`);
+ throw new Error(`Error running ${cmd}`);
}
}
}
diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts
index 6d5fd9a72..4c0b75449 100644
--- a/packages/astro/src/core/config.ts
+++ b/packages/astro/src/core/config.ts
@@ -1,4 +1,5 @@
-import type { AstroConfig, AstroUserConfig } from '../@types/astro';
+import type { AstroConfig, AstroUserConfig, CLIFlags } from '../@types/astro';
+import type { Arguments as Flags } from 'yargs-parser';
import * as colors from 'kleur/colors';
import path from 'path';
@@ -116,19 +117,47 @@ function addTrailingSlash(str: string): string {
return str.replace(/\/*$/, '/');
}
+/** Convert the generic "yargs" flag object into our own, custom TypeScript object. */
+function resolveFlags(flags: Partial<Flags>): CLIFlags {
+ return {
+ projectRoot: typeof flags.projectRoot === 'string' ? flags.projectRoot : undefined,
+ site: typeof flags.site === 'string' ? flags.site : undefined,
+ sitemap: typeof flags.sitemap === 'boolean' ? flags.sitemap : undefined,
+ port: typeof flags.port === 'number' ? flags.port : undefined,
+ config: typeof flags.config === 'string' ? flags.config : undefined,
+ hostname: typeof flags.hostname === 'string' ? flags.hostname : undefined,
+ experimentalStaticBuild: typeof flags.experimentalStaticBuild === 'boolean' ? flags.experimentalStaticBuild : false,
+ drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
+ };
+}
+
+/** Merge CLI flags & user config object (CLI flags take priority) */
+function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags) {
+ astroConfig.buildOptions = astroConfig.buildOptions || {};
+ astroConfig.devOptions = astroConfig.devOptions || {};
+ if (typeof flags.sitemap === 'boolean') astroConfig.buildOptions.sitemap = flags.sitemap;
+ if (typeof flags.site === 'string') astroConfig.buildOptions.site = flags.site;
+ if (typeof flags.port === 'number') astroConfig.devOptions.port = flags.port;
+ if (typeof flags.hostname === 'string') astroConfig.devOptions.hostname = flags.hostname;
+ if (typeof flags.experimentalStaticBuild === 'boolean') astroConfig.buildOptions.experimentalStaticBuild = flags.experimentalStaticBuild;
+ if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
+ return astroConfig;
+}
+
interface LoadConfigOptions {
cwd?: string;
- filename?: string;
+ flags?: Flags;
}
/** Attempt to load an `astro.config.mjs` file */
-export async function loadConfig(options: LoadConfigOptions): Promise<AstroConfig> {
- const root = options.cwd ? path.resolve(options.cwd) : process.cwd();
+export async function loadConfig(configOptions: LoadConfigOptions): Promise<AstroConfig> {
+ const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd();
+ const flags = resolveFlags(configOptions.flags || {});
let userConfig: AstroUserConfig = {};
let userConfigPath: string | undefined;
- if (options.filename) {
- userConfigPath = /^\.*\//.test(options.filename) ? options.filename : `./${options.filename}`;
+ if (flags?.config) {
+ userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(new URL(userConfigPath, `file://${root}/`));
}
// Automatically load config file using Proload
@@ -138,7 +167,9 @@ export async function loadConfig(options: LoadConfigOptions): Promise<AstroConfi
userConfig = config.value;
}
// normalize, validate, and return
- return validateConfig(userConfig, root);
+ const mergedConfig = mergeCLIFlags(userConfig, flags);
+ const validatedConfig = await validateConfig(mergedConfig, root);
+ return validatedConfig;
}
export function formatConfigError(err: z.ZodError) {