Skip to content

Commit

Permalink
feat(core): specify a custom .env file for workspace:run-commands (#2505
Browse files Browse the repository at this point in the history
)

* feat(core): add envFile option to commands runner

* feat(core): add tests for dotenv functionality in command runner
  • Loading branch information
rarmatei committed Feb 19, 2020
1 parent 6fe7889 commit eee8c18
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 4 deletions.
6 changes: 6 additions & 0 deletions docs/angular/api-workspace/builders/run-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ Type: `string`

Command to run in child process

### envFile

Type: `string`

You may specify a custom .env file path if your file containing environment variables is located elsewhere.

### outputPath

Type: `string`
Expand Down
6 changes: 6 additions & 0 deletions docs/react/api-workspace/builders/run-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Type: `string`

Command to run in child process

### envFile

Type: `string`

You may specify a custom .env file path if your file containing environment variables is located elsewhere.

### outputPath

Type: `string`
Expand Down
6 changes: 6 additions & 0 deletions docs/web/api-workspace/builders/run-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ Type: `string`

Command to run in child process

### envFile

Type: `string`

You may specify a custom .env file path if your file containing environment variables is located elsewhere.

### outputPath

Type: `string`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { schema } from '@angular-devkit/core';
import { fileSync } from 'tmp';
import { readFileSync } from 'fs';
import { readFileSync, writeFileSync, unlinkSync } from 'fs';
import { TestingArchitectHost } from '@angular-devkit/architect/testing';
import { Architect } from '@angular-devkit/architect';
import { join } from 'path';
Expand Down Expand Up @@ -270,4 +270,79 @@ describe('Command Runner Builder', () => {
});
});
});

describe('dotenv', () => {
beforeAll(() => {
writeFileSync('.env', 'NRWL_SITE=https://nrwl.io/');
});

beforeEach(() => {
delete process.env.NRWL_SITE;
delete process.env.NX_SITE;
});

afterAll(() => {
unlinkSync('.env');
});

it('should load the root .env file by default if there is one', async () => {
let f = fileSync().name;
let run = await architect.scheduleBuilder(
'@nrwl/workspace:run-commands',
{
commands: [
{
command: `echo $NRWL_SITE >> ${f}`
}
]
}
);

let result = await run.result;

expect(result).toEqual(jasmine.objectContaining({ success: true }));
expect(readFile(f)).toEqual('https://nrwl.io/');
});

it('should load the specified .env file instead of the root one', async () => {
const devEnv = fileSync().name;
writeFileSync(devEnv, 'NX_SITE=https://nx.dev/');
let f = fileSync().name;
let run = await architect.scheduleBuilder(
'@nrwl/workspace:run-commands',
{
commands: [
{
command: `echo $NX_SITE >> ${f} && echo $NRWL_SITE >> ${f}`
}
],
envFile: devEnv
}
);

let result = await run.result;

expect(result).toEqual(jasmine.objectContaining({ success: true }));
expect(readFile(f)).toEqual('https://nx.dev/');
});

it('should error if the specified .env file does not exist', async () => {
let f = fileSync().name;
let run = await architect.scheduleBuilder(
'@nrwl/workspace:run-commands',
{
commands: [
{
command: `echo $NX_SITE >> ${f} && echo $NRWL_SITE >> ${f}`
}
],
envFile: '/somePath/.fakeEnv'
}
);

await expect(run.result).rejects.toThrow(
`no such file or directory, open '/somePath/.fakeEnv'`
);
});
});
});
17 changes: 14 additions & 3 deletions packages/workspace/src/builders/run-commands/run-commands.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,26 @@ import { exec } from 'child_process';
import { Observable } from 'rxjs';
import { TEN_MEGABYTES } from '@nrwl/workspace/src/core/file-utils';

try {
require('dotenv').config();
} catch (e) {}
function loadEnvVars(path?: string) {
if (path) {
const result = require('dotenv').config({ path });
if (result.error) {
throw result.error;
}
} else {
try {
require('dotenv').config();
} catch (e) {}
}
}

export interface RunCommandsBuilderOptions extends JsonObject {
commands: { command: string }[];
color?: boolean;
parallel?: boolean;
readyWhen?: string;
args?: string;
envFile?: string;
parsedArgs?: { [key: string]: string };
}

Expand All @@ -27,6 +37,7 @@ function run(
options: RunCommandsBuilderOptions,
context: BuilderContext
): Observable<BuilderOutput> {
loadEnvVars(options.envFile);
options.parsedArgs = parseArgs(options.args);
return Observable.create(async observer => {
if (!options.commands) {
Expand Down
4 changes: 4 additions & 0 deletions packages/workspace/src/builders/run-commands/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
"type": "string",
"description": "Extra arguments. You can pass them as follows: ng run project:target --args='--wait=100'. You can them use {args.wait} syntax to interpolate them in the workspace config file."
},
"envFile": {
"type": "string",
"description": "You may specify a custom .env file path if your file containing environment variables is located elsewhere."
},
"color": {
"type": "boolean",
"description": "Use colors when showing output of command",
Expand Down

0 comments on commit eee8c18

Please sign in to comment.