Skip to content

Commit

Permalink
refactor(env): apply environment variables in cli
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-mitchell committed Jan 22, 2024
1 parent b3ce605 commit 12bb619
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 31 deletions.
9 changes: 7 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import process from "node:process";
import meow from "meow";
import { $ } from "execa";
import { applyEnvironmentVariables, getCommands } from "./helpers/index.js";
import { parseEnvironmentVariables, getCommands } from "./helpers/index.js";
import { getTasks } from "./tasks.js";

const cli = meow(`
Expand Down Expand Up @@ -69,7 +69,12 @@ if (input.length === 0 || helpShortFlag) {

const { hideTimer, persist: persistentOutput, allOptional, environment } = cli.flags;

applyEnvironmentVariables(environment);
const env = parseEnvironmentVariables(environment);

process.env = {
...process.env,
...env,
};

const tasks = getTasks({
commands: getCommands(input),
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from "./get-commands/index.js";
export * from "./tasks/index.js";
export * from "./apply-environment-variables.js";
export * from "./parse-environment-variables.js";
export type * from "./types.js";
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import process from "node:process";
import type { MatchAll } from "./types.js";

/**
Expand All @@ -16,7 +15,7 @@ import type { MatchAll } from "./types.js";
const environmentVariableRegex = /(?=[^,])(?<env>[^:,]*)(?::["'](?<quoted>[^"']*)["']|:(?<value>[^,]*))?/g;

/**
* Parses environment variable input into separate values, applying them to `process.env`.
* Parses environment variable input into separate values.
*
* Separates values by comma. Values are set to `"true"`. If a value has a `:`,
* it will be split and set to the value following the `:`. Commas in values must be quoted.
Expand All @@ -25,21 +24,26 @@ const environmentVariableRegex = /(?=[^,])(?<env>[^:,]*)(?::["'](?<quoted>[^"']*
* @example
* // listr -e FOO -e BAR,LIST:\"a,b,c\",FOO,BAR:\'baz\' -e FIZZ:'buzz bazz'
* applyEnvironmentVariables(["FOO", "BAR,LIST:\"a,b,c\",FOO,BAR:'baz'", "FIZZ:buzz bazz"]);
*
* process.env.FOO = "true";
* process.env.BAR = "baz";
* process.env.LIST = "a,b,c";
* process.env.FIZZ = "buzz bazz";
* //=> {
* //=> FOO: "true",
* //=> BAR: "baz",
* //=> LIST: "a,b,c",
* //=> FIZZ: "buzz bazz",
* //=> }
*/
export const applyEnvironmentVariables = (environment: string[]) => {
export const parseEnvironmentVariables = (environment: string[]): Record<string, string> => {
const parsedEnvironmentVariables: Record<string, string> = {};

for (const argument of environment) {
const pairs = argument.matchAll(environmentVariableRegex) as MatchAll<"env", "quoted" | "value">;

for (const pair of pairs) {
const key = pair.groups.env;
const value = pair.groups.quoted ?? pair.groups.value;

process.env[key] = value ?? String(true);
parsedEnvironmentVariables[key] = value ?? String(true);
}
}

return parsedEnvironmentVariables;
};
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
/* eslint-disable @typescript-eslint/naming-convention */
import process from "node:process";
import anyTest, { type TestFn } from "ava";
import { applyEnvironmentVariables } from "../../src/helpers/apply-environment-variables.js";

const test = anyTest as TestFn<{
originalProcessEnv: typeof process["env"];
}>;

test.beforeEach("reset process.env", t => {
t.context.originalProcessEnv = process.env;
process.env = {};
});

test.after("reapply process.env", t => {
process.env = t.context.originalProcessEnv;
});
import test from "ava";
import { parseEnvironmentVariables } from "../../src/helpers/parse-environment-variables.js";

type MacroArgs = {
env_Vars: string[];
expected: string[] | Record<string, string>;
};

const verifyEnv = test.macro((t, { env_Vars: input, expected }: MacroArgs) => {
applyEnvironmentVariables(input);
const env = parseEnvironmentVariables(input);

if (Array.isArray(expected)) {
t.deepEqual(Object.keys(process.env), expected);
t.deepEqual(Object.keys(env), expected);
} else {
t.deepEqual(process.env, expected);
t.deepEqual(env, expected);
}
});

Expand Down

0 comments on commit 12bb619

Please sign in to comment.