Skip to content

Commit 25cc921

Browse files
authored
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?
1 parent 340cc1c commit 25cc921

File tree

5 files changed

+92
-9
lines changed

5 files changed

+92
-9
lines changed

.changeset/dirty-trains-yawn.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fix relative config handling with the `--config` flag

packages/astro/src/core/config.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import path from 'path';
77
import { pathToFileURL, fileURLToPath } from 'url';
88
import { mergeConfig as mergeViteConfig } from 'vite';
99
import { z } from 'zod';
10-
import load from '@proload/core';
10+
import load, { ProloadError } from '@proload/core';
1111
import loadTypeScript from '@proload/plugin-tsm';
1212
import postcssrc from 'postcss-load-config';
1313
import { arraify, isObject } from './util.js';
@@ -379,11 +379,20 @@ export async function loadConfig(configOptions: LoadConfigOptions): Promise<Astr
379379

380380
if (flags?.config) {
381381
userConfigPath = /^\.*\//.test(flags.config) ? flags.config : `./${flags.config}`;
382-
userConfigPath = fileURLToPath(new URL(userConfigPath, pathToFileURL(root)));
382+
userConfigPath = fileURLToPath(new URL(userConfigPath, appendForwardSlash(pathToFileURL(root).toString())));
383383
}
384+
384385
// Automatically load config file using Proload
385386
// If `userConfigPath` is `undefined`, Proload will search for `astro.config.[cm]?[jt]s`
386-
const config = await load('astro', { mustExist: false, cwd: root, filePath: userConfigPath });
387+
let config;
388+
try {
389+
config = await load('astro', { mustExist: !!userConfigPath, cwd: root, filePath: userConfigPath });
390+
} catch (err) {
391+
if (err instanceof ProloadError && flags.config) {
392+
throw new Error(`Unable to resolve --config "${flags.config}"! Does the file exist?`);
393+
}
394+
throw err;
395+
}
387396
if (config) {
388397
userConfig = config.value;
389398
}

packages/astro/test/config.test.js

+54
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,60 @@ describe('config', () => {
6464
});
6565
});
6666

67+
describe('relative path', () => {
68+
it('can be passed via relative --config', async () => {
69+
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
70+
const configFileURL = 'my-config.mjs';
71+
const { local } = await cliServerLogSetup([
72+
'--root',
73+
fileURLToPath(projectRootURL),
74+
'--config',
75+
configFileURL,
76+
]);
77+
78+
const localURL = new URL(local);
79+
expect(localURL.port).to.equal('8080');
80+
});
81+
})
82+
83+
describe('relative path with leading ./', () => {
84+
it('can be passed via relative --config', async () => {
85+
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
86+
const configFileURL = './my-config.mjs';
87+
const { local } = await cliServerLogSetup([
88+
'--root',
89+
fileURLToPath(projectRootURL),
90+
'--config',
91+
configFileURL,
92+
]);
93+
94+
const localURL = new URL(local);
95+
expect(localURL.port).to.equal('8080');
96+
});
97+
})
98+
99+
describe('incorrect path', () => {
100+
it('fails and exits when config does not exist', async () => {
101+
const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url);
102+
const configFileURL = './does-not-exist.mjs';
103+
let exit = 0;
104+
try {
105+
await cliServerLogSetup([
106+
'--root',
107+
fileURLToPath(projectRootURL),
108+
'--config',
109+
configFileURL,
110+
]);
111+
} catch (e) {
112+
if (e.message.includes('Unable to resolve --config')) {
113+
exit = 1;
114+
}
115+
}
116+
117+
expect(exit).to.equal(1, "Throws helpful error message when --config does not exist");
118+
});
119+
})
120+
67121
describe('port', () => {
68122
it('can be specified in astro.config.mjs', async () => {
69123
expect(portFixture.config.server.port).to.deep.equal(5006);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
server: {
3+
port: 8080,
4+
},
5+
}

packages/astro/test/test-utils.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,32 @@ export function cli(/** @type {string[]} */ ...args) {
151151

152152
export async function parseCliDevStart(proc) {
153153
let stdout = '';
154+
let stderr = '';
154155

155156
for await (const chunk of proc.stdout) {
156157
stdout += chunk;
157-
158158
if (chunk.includes('Local')) break;
159159
}
160+
if (!stdout) {
161+
for await (const chunk of proc.stderr) {
162+
stderr += chunk;
163+
break;
164+
}
165+
}
160166

161167
proc.kill();
162168
stdout = stripAnsi(stdout);
169+
stderr = stripAnsi(stderr);
170+
171+
if (stderr) {
172+
throw new Error(stderr);
173+
}
174+
163175
const messages = stdout
164176
.split('\n')
165177
.filter((ln) => !!ln.trim())
166178
.map((ln) => ln.replace(/[🚀]/g, '').replace(/\s+/g, ' ').trim());
179+
167180
return { messages };
168181
}
169182

@@ -172,11 +185,8 @@ export async function cliServerLogSetup(flags = [], cmd = 'dev') {
172185

173186
const { messages } = await parseCliDevStart(proc);
174187

175-
const localRaw = (messages[1] ?? '').includes('Local') ? messages[1] : undefined;
176-
const networkRaw = (messages[2] ?? '').includes('Network') ? messages[2] : undefined;
177-
178-
const local = localRaw?.replace(/Local\s*/g, '');
179-
const network = networkRaw?.replace(/Network\s*/g, '');
188+
const local = messages.find(msg => msg.includes('Local'))?.replace(/Local\s*/g, '');
189+
const network = messages.find(msg => msg.includes('Network'))?.replace(/Network\s*/g, '');
180190

181191
return { local, network };
182192
}

0 commit comments

Comments
 (0)