Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
name: Node CI

on: [pull_request]
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master

jobs:
build:
Expand Down
86 changes: 55 additions & 31 deletions __tests__/config/utils/env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ describe('readLocalEnvFile', () => {
let backupSystemEnv = {};

const baseFlags = {
cwd: '/tmp/project',
cwd: normalize('/tmp/project'),
env: undefined,
loadSystemEnv: false,
};

beforeEach(() => {
beforeAll(() => {
mockFs({
'/tmp/project': {
'.env': stripIndent`
Expand All @@ -63,29 +63,37 @@ describe('readLocalEnvFile', () => {
},
'/tmp/project-two': {
'.env': stripIndent`
ACCOUNT_SID=ACyyyyyyy
AUTH_TOKEN=123456789a
TWILIO=https://www.twilio.com
ACCOUNT_SID=ACyyyyyyyyy
AUTH_TOKEN=a987654321
MY_PHONE_NUMBER=+99999
SECRET_API_KEY=ahoy
`,
'.env.prod': stripIndent`
ACCOUNT_SID=
AUTH_TOKEN=
TWILIO=https://www.twilio.com
MY_PHONE_NUMBER=+444444444
SECRET_API_KEY=
`,
},
});
});

beforeEach(() => {
backupSystemEnv = { ...process.env };
});

afterEach(() => {
afterAll(() => {
mockFs.restore();
});

afterEach(() => {
process.env = { ...backupSystemEnv };
});

it('should throw an error if you use --load-system-env without --env', async () => {
const errorMessage = stripIndent`
If you are using --load-system-env you'll also have to supply a --env flag.

The .env file you are pointing at will be used to primarily load environment variables.
Any empty entries in the .env file will fall back to the system's environment variables.
`;
Expand All @@ -95,8 +103,21 @@ describe('readLocalEnvFile', () => {
).rejects.toEqual(new Error(errorMessage));
});

it('should throw an error if the specified file does not exist', async () => {
expect(
readLocalEnvFile({ ...baseFlags, env: '/tmp/invalid-project/.env' })
).rejects.toEqual(
new Error(
`Failed to find .env file at "${path.resolve(
'/tmp/invalid-project/.env'
)}"`
)
);
});

it('should load the default env variables', async () => {
expect(await readLocalEnvFile(baseFlags)).toEqual({
const result = await readLocalEnvFile(baseFlags);
expect(result).toEqual({
localEnv: {
ACCOUNT_SID: 'ACxxxxxxx',
AUTH_TOKEN: '123456789f',
Expand All @@ -108,7 +129,8 @@ describe('readLocalEnvFile', () => {
});

it('should load env variables from a different filename', async () => {
expect(await readLocalEnvFile({ ...baseFlags, env: '.env.prod' })).toEqual({
const result = await readLocalEnvFile({ ...baseFlags, env: '.env.prod' });
expect(result).toEqual({
localEnv: {
ACCOUNT_SID: '',
AUTH_TOKEN: '',
Expand All @@ -120,30 +142,33 @@ describe('readLocalEnvFile', () => {
});

it('should load the default env variables with different cwd', async () => {
expect(
await readLocalEnvFile({ ...baseFlags, cwd: '/tmp/project-two' })
).toEqual({
const result = await readLocalEnvFile({
...baseFlags,
cwd: normalize('/tmp/project-two'),
});
expect(result).toEqual({
localEnv: {
ACCOUNT_SID: 'ACyyyyyyy',
AUTH_TOKEN: '123456789a',
TWILIO: 'https://www.twilio.com',
ACCOUNT_SID: 'ACyyyyyyyyy',
AUTH_TOKEN: 'a987654321',
MY_PHONE_NUMBER: '+99999',
SECRET_API_KEY: 'ahoy',
},
envPath: normalize('/tmp/project-two/.env'),
});
});

it('should load env variables from a different filename & cwd', async () => {
expect(
await readLocalEnvFile({
...baseFlags,
cwd: '/tmp/project-two',
env: '.env.prod',
})
).toEqual({
const result = await readLocalEnvFile({
...baseFlags,
cwd: normalize('/tmp/project-two'),
env: '.env.prod',
});
expect(result).toEqual({
localEnv: {
ACCOUNT_SID: '',
AUTH_TOKEN: '',
TWILIO: 'https://www.twilio.com',
MY_PHONE_NUMBER: '+444444444',
SECRET_API_KEY: '',
},
envPath: normalize('/tmp/project-two/.env.prod'),
});
Expand All @@ -156,13 +181,12 @@ describe('readLocalEnvFile', () => {
SECRET_API_KEY: 'psst',
};

expect(
await readLocalEnvFile({
...baseFlags,
env: '.env.prod',
loadSystemEnv: true,
})
).toEqual({
const result = await readLocalEnvFile({
...baseFlags,
env: '.env.prod',
loadSystemEnv: true,
});
expect(result).toEqual({
localEnv: {
ACCOUNT_SID: 'ACzzzzzzz',
AUTH_TOKEN: '',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"commitizen": "^3.1.1",
"cz-conventional-changelog": "^2.1.0",
"husky": "^3.0.0",
"jest": "^26.0.1",
"jest": "^26.2.2",
"jest-express": "^1.10.1",
"lint-staged": "^8.2.1",
"listr-silent-renderer": "^1.1.1",
Expand Down
7 changes: 6 additions & 1 deletion src/config/utils/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ export async function readLocalEnvFile(flags: {
contentEnvFile = '';
}

const localEnv = dotenv.parse(contentEnvFile);
let localEnv;
try {
localEnv = dotenv.parse(contentEnvFile);
} catch (err) {
throw new Error('Failed to parse .env file');
}

if (flags.loadSystemEnv && typeof flags.env !== 'undefined') {
for (const key of Object.keys(localEnv)) {
Expand Down