diff --git a/.changeset/dirty-trains-yawn.md b/.changeset/dirty-trains-yawn.md new file mode 100644 index 000000000000..aaf62059f19b --- /dev/null +++ b/.changeset/dirty-trains-yawn.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix relative config handling with the `--config` flag diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index c6b09b123a07..5231f5ffa45a 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -7,7 +7,7 @@ import path from 'path'; import { pathToFileURL, fileURLToPath } from 'url'; import { mergeConfig as mergeViteConfig } from 'vite'; import { z } from 'zod'; -import load from '@proload/core'; +import load, { ProloadError } from '@proload/core'; import loadTypeScript from '@proload/plugin-tsm'; import postcssrc from 'postcss-load-config'; import { arraify, isObject } from './util.js'; @@ -379,11 +379,20 @@ export async function loadConfig(configOptions: LoadConfigOptions): Promise { }); }); + 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', () => { it('can be specified in astro.config.mjs', async () => { expect(portFixture.config.server.port).to.deep.equal(5006); diff --git a/packages/astro/test/fixtures/astro-basic/my-config.mjs b/packages/astro/test/fixtures/astro-basic/my-config.mjs new file mode 100644 index 000000000000..7ed24f69f250 --- /dev/null +++ b/packages/astro/test/fixtures/astro-basic/my-config.mjs @@ -0,0 +1,5 @@ +export default { + server: { + port: 8080, + }, +} diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index ab04f96046b6..b850486c3ee2 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -151,19 +151,32 @@ export function cli(/** @type {string[]} */ ...args) { export async function parseCliDevStart(proc) { let stdout = ''; + let stderr = ''; for await (const chunk of proc.stdout) { stdout += chunk; - if (chunk.includes('Local')) break; } + if (!stdout) { + for await (const chunk of proc.stderr) { + stderr += chunk; + break; + } + } proc.kill(); stdout = stripAnsi(stdout); + stderr = stripAnsi(stderr); + + if (stderr) { + throw new Error(stderr); + } + const messages = stdout .split('\n') .filter((ln) => !!ln.trim()) .map((ln) => ln.replace(/[🚀┃]/g, '').replace(/\s+/g, ' ').trim()); + return { messages }; } @@ -172,11 +185,8 @@ export async function cliServerLogSetup(flags = [], cmd = 'dev') { const { messages } = await parseCliDevStart(proc); - const localRaw = (messages[1] ?? '').includes('Local') ? messages[1] : undefined; - const networkRaw = (messages[2] ?? '').includes('Network') ? messages[2] : undefined; - - const local = localRaw?.replace(/Local\s*/g, ''); - const network = networkRaw?.replace(/Network\s*/g, ''); + const local = messages.find(msg => msg.includes('Local'))?.replace(/Local\s*/g, ''); + const network = messages.find(msg => msg.includes('Network'))?.replace(/Network\s*/g, ''); return { local, network }; }