Skip to content

Commit 8f81eff

Browse files
committed
Fixed an issue in environment to better handle when a directory is (incorrectly) passed as the value for --output-file
1 parent f4baacb commit 8f81eff

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/shared/environment.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ async function validateEnvFile(
3838
}
3939
return false;
4040
}
41+
const stat = await fs.stat(envFilePath);
42+
if (!stat.isFile()) {
43+
if (shouldLog) {
44+
ux.warn(
45+
`${envFilePath} is a directory, not a file. Proceeding without loading environment variables.`
46+
);
47+
}
48+
return false;
49+
}
4150
return true;
4251
}
4352

test/hooks/prerun.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ jest.mock('fs-extra', () => ({
2727
default: {
2828
pathExists: jest.fn(),
2929
readFile: jest.fn(),
30+
stat: jest
31+
.fn<() => Promise<{ isFile: () => boolean }>>()
32+
.mockResolvedValue({ isFile: () => true }),
3033
},
3134
}));
3235

test/shared/environment.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import fs from 'fs-extra';
33
import path from 'path';
44

55
import { DEFAULT_ENV_PATH, getEnv } from '../../src/shared/index.js';
6+
import { ux } from '@oclif/core/ux';
67

78
jest.mock('@oclif/core/ux', () => ({
89
ux: {
@@ -14,6 +15,9 @@ jest.mock('fs-extra', () => ({
1415
default: {
1516
pathExists: jest.fn(),
1617
readFile: jest.fn(),
18+
stat: jest.fn<() => Promise<{ isFile: () => boolean }>>().mockResolvedValue({
19+
isFile: () => true,
20+
}),
1721
},
1822
}));
1923

@@ -54,6 +58,7 @@ jest.mock('dotenv', () => ({
5458

5559
const mockedPathExists = fs.pathExists as unknown as jest.Mock<() => Promise<boolean>>;
5660
const mockedReadFile = fs.readFile as unknown as jest.Mock<() => Promise<string>>;
61+
const mockedStat = fs.stat as unknown as jest.Mock<() => Promise<{ isFile: () => boolean }>>;
5762
const mockedRelative = path.relative as jest.Mock<(from: string, to: string) => string>;
5863

5964
describe('getEnv (shared/environment)', () => {
@@ -159,6 +164,32 @@ describe('getEnv (shared/environment)', () => {
159164
});
160165
});
161166

167+
describe('path is a directory', () => {
168+
it('returns empty env when path is a directory (not a file)', async () => {
169+
mockedPathExists.mockResolvedValue(true);
170+
mockedStat.mockResolvedValueOnce({ isFile: () => false });
171+
const shouldLog = false;
172+
173+
const result = await getEnv([], shouldLog, 'some-dir');
174+
175+
expect(result.env).toEqual({});
176+
expect(result.envFilePath).toBe('some-dir');
177+
expect(mockedReadFile).not.toHaveBeenCalled();
178+
});
179+
180+
it('warns when path is a directory and shouldLog is true', async () => {
181+
mockedPathExists.mockResolvedValue(true);
182+
mockedStat.mockResolvedValueOnce({ isFile: () => false });
183+
const shouldLog = true;
184+
185+
await getEnv([], shouldLog, '/path/to/dir');
186+
187+
expect(ux.warn).toHaveBeenCalledWith(
188+
'/path/to/dir is a directory, not a file. Proceeding without loading environment variables.'
189+
);
190+
});
191+
});
192+
162193
describe('successful load', () => {
163194
it('returns parsed env and relative path', async () => {
164195
mockedPathExists.mockResolvedValue(true);

0 commit comments

Comments
 (0)