fix(#2987): relative config handling with --config flag (#3001)

* fix(#2987): relative config handling with `--config` flag

* test: fix tests

* fix: improve config test for failure case

* fix: test on windows?

* fix: test on windows?
This commit is contained in:
Nate Moore 2022-04-06 16:37:49 -05:00 committed by GitHub
parent 340cc1c8e4
commit 25cc9218f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 92 additions and 9 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix relative config handling with the `--config` flag

View file

@ -7,7 +7,7 @@ import path from 'path';
import { pathToFileURL, fileURLToPath } from 'url'; import { pathToFileURL, fileURLToPath } from 'url';
import { mergeConfig as mergeViteConfig } from 'vite'; import { mergeConfig as mergeViteConfig } from 'vite';
import { z } from 'zod'; import { z } from 'zod';
import load from '@proload/core'; import load, { ProloadError } from '@proload/core';
import loadTypeScript from '@proload/plugin-tsm'; import loadTypeScript from '@proload/plugin-tsm';
import postcssrc from 'postcss-load-config'; import postcssrc from 'postcss-load-config';
import { arraify, isObject } from './util.js'; import { arraify, isObject } from './util.js';
@ -379,11 +379,20 @@ export async function loadConfig(configOptions: LoadConfigOptions): Promise<Astr
if (flags?.config) { if (flags?.config) {
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`; userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
userConfigPath = fileURLToPath(new URL(userConfigPath, pathToFileURL(root))); userConfigPath = fileURLToPath(new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString())));
} }
// Automatically load config file using Proload // Automatically load config file using Proload
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s` // If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s`
const config = await load('astro', { mustExist: false, cwd: root, filePath: userConfigPath }); let config;
try {
config = await load('astro', { mustExist: !!userConfigPath, cwd: root, filePath: userConfigPath });
} catch (err) {
if (err instanceof ProloadError && flags.config) {
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
}
throw err;
}
if (config) { if (config) {
userConfig = config.value; userConfig = config.value;
} }

View file

@ -64,6 +64,60 @@ describe('config', () => {
}); });
}); });
describe('relative path', () => {
it('can be passed via relative --config', async () => {
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
const configFileURL = 'my-config.mjs';
const { local } = await cliServerLogSetup([
'--root',
fileURLToPath(projectRootURL),
'--config',
configFileURL,
]);
const localURL = new URL(local);
expect(localURL.port).to.equal('8080');
});
})
describe('relative path with leading ./', () => {
it('can be passed via relative --config', async () => {
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
const configFileURL = './my-config.mjs';
const { local } = await cliServerLogSetup([
'--root',
fileURLToPath(projectRootURL),
'--config',
configFileURL,
]);
const localURL = new URL(local);
expect(localURL.port).to.equal('8080');
});
})
describe('incorrect path', () => {
it('fails and exits when config does not exist', async () => {
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
const configFileURL = './does-not-exist.mjs';
let exit = 0;
try {
await cliServerLogSetup([
'--root',
fileURLToPath(projectRootURL),
'--config',
configFileURL,
]);
} catch (e) {
if (e.message.includes('Unable to resolve --config')) {
exit = 1;
}
}
expect(exit).to.equal(1, "Throws helpful error message when --config does not exist");
});
})
describe('port', () => { describe('port', () => {
it('can be specified in astro.config.mjs', async () => { it('can be specified in astro.config.mjs', async () => {
expect(portFixture.config.server.port).to.deep.equal(5006); expect(portFixture.config.server.port).to.deep.equal(5006);

View file

@ -0,0 +1,5 @@
export default {
server: {
port: 8080,
},
}

View file

@ -151,19 +151,32 @@ export function cli(/** @type {string[]} */ ...args) {
export async function parseCliDevStart(proc) { export async function parseCliDevStart(proc) {
let stdout = ''; let stdout = '';
let stderr = '';
for await (const chunk of proc.stdout) { for await (const chunk of proc.stdout) {
stdout += chunk; stdout += chunk;
if (chunk.includes('Local')) break; if (chunk.includes('Local')) break;
} }
if (!stdout) {
for await (const chunk of proc.stderr) {
stderr += chunk;
break;
}
}
proc.kill(); proc.kill();
stdout = stripAnsi(stdout); stdout = stripAnsi(stdout);
stderr = stripAnsi(stderr);
if (stderr) {
throw new Error(stderr);
}
const messages = stdout const messages = stdout
.split('\n') .split('\n')
.filter((ln) => !!ln.trim()) .filter((ln) => !!ln.trim())
.map((ln) => ln.replace(/[🚀┃]/g, '').replace(/\s+/g, ' ').trim()); .map((ln) => ln.replace(/[🚀┃]/g, '').replace(/\s+/g, ' ').trim());
return { messages }; return { messages };
} }
@ -172,11 +185,8 @@ export async function cliServerLogSetup(flags = [], cmd = 'dev') {
const { messages } = await parseCliDevStart(proc); const { messages } = await parseCliDevStart(proc);
const localRaw = (messages[1] ?? '').includes('Local') ? messages[1] : undefined; const local = messages.find(msg => msg.includes('Local'))?.replace(/Local\s*/g, '');
const networkRaw = (messages[2] ?? '').includes('Network') ? messages[2] : undefined; const network = messages.find(msg => msg.includes('Network'))?.replace(/Network\s*/g, '');
const local = localRaw?.replace(/Local\s*/g, '');
const network = networkRaw?.replace(/Network\s*/g, '');
return { local, network }; return { local, network };
} }