mirror of
https://github.com/toddbluhm/env-cmd.git
synced 2025-12-08 18:23:33 +00:00
Updated typescript-eslint packages and fixed lint errors
- Updated commander - Brought coverage back up to 100% - Updated tsconfig to adhere to linter parser update
This commit is contained in:
parent
ae7981691e
commit
f5e2e33939
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,3 +10,6 @@ package-lock.json
|
|||||||
|
|
||||||
# Code Editor directory
|
# Code Editor directory
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
|
# Ignore compiled dist/tests
|
||||||
|
dist/test
|
||||||
|
|||||||
66
dist/get-env-vars.js
vendored
66
dist/get-env-vars.js
vendored
@ -1,66 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const parse_rc_file_1 = require("./parse-rc-file");
|
|
||||||
const parse_env_file_1 = require("./parse-env-file");
|
|
||||||
const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json'];
|
|
||||||
const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json'];
|
|
||||||
function getEnvVars(options) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
options = options || {};
|
|
||||||
options.envFile = options.envFile || {};
|
|
||||||
// Check for rc file usage
|
|
||||||
if (options.rc) {
|
|
||||||
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath });
|
|
||||||
}
|
|
||||||
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getEnvVars = getEnvVars;
|
|
||||||
function getEnvFile({ filePath, fallback }) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
// Use env file
|
|
||||||
if (filePath) {
|
|
||||||
try {
|
|
||||||
return yield parse_env_file_1.getEnvFileVars(filePath);
|
|
||||||
}
|
|
||||||
catch (e) { }
|
|
||||||
if (!fallback) {
|
|
||||||
throw new Error(`Unable to locate env file at location (${filePath})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Use the default env file locations
|
|
||||||
for (const path of ENV_FILE_DEFAULT_LOCATIONS) {
|
|
||||||
try {
|
|
||||||
return yield parse_env_file_1.getEnvFileVars(path);
|
|
||||||
}
|
|
||||||
catch (e) { }
|
|
||||||
}
|
|
||||||
throw new Error(`Unable to locate env file at default locations (${ENV_FILE_DEFAULT_LOCATIONS})`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.getEnvFile = getEnvFile;
|
|
||||||
async function getRCFile({ environments, filePath }) {
|
|
||||||
// User provided an .rc file path
|
|
||||||
if (filePath) {
|
|
||||||
try {
|
|
||||||
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (e.name !== 'PathError')
|
|
||||||
console.log(e);
|
|
||||||
throw new Error(`Unable to locate .rc file at location (${filePath})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Use the default .rc file locations
|
|
||||||
for (const filePath of RC_FILE_DEFAULT_LOCATIONS) {
|
|
||||||
try {
|
|
||||||
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (e.name !== 'PathError')
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error(`Unable to locate .rc file at default locations (${RC_FILE_DEFAULT_LOCATIONS})`);
|
|
||||||
}
|
|
||||||
exports.getRCFile = getRCFile;
|
|
||||||
5
dist/env-cmd.js → dist/src/env-cmd.js
vendored
5
dist/env-cmd.js → dist/src/env-cmd.js
vendored
@ -31,11 +31,10 @@ exports.CLI = CLI;
|
|||||||
* @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options }
|
* @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options }
|
||||||
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
|
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
|
||||||
*/
|
*/
|
||||||
async function EnvCmd({ command, commandArgs, envFile, rc, options }) {
|
async function EnvCmd({ command, commandArgs, envFile, rc, options = {} }) {
|
||||||
options = options || {};
|
|
||||||
let env = await get_env_vars_1.getEnvVars({ envFile, rc });
|
let env = await get_env_vars_1.getEnvVars({ envFile, rc });
|
||||||
// Override the merge order if --no-override flag set
|
// Override the merge order if --no-override flag set
|
||||||
if (options.noOverride) {
|
if (options.noOverride === true) {
|
||||||
env = Object.assign({}, env, process.env);
|
env = Object.assign({}, env, process.env);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
61
dist/src/get-env-vars.js
vendored
Normal file
61
dist/src/get-env-vars.js
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
const parse_rc_file_1 = require("./parse-rc-file");
|
||||||
|
const parse_env_file_1 = require("./parse-env-file");
|
||||||
|
const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json'];
|
||||||
|
const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json'];
|
||||||
|
async function getEnvVars(options = {}) {
|
||||||
|
options.envFile = options.envFile !== undefined ? options.envFile : {};
|
||||||
|
// Check for rc file usage
|
||||||
|
if (options.rc !== undefined) {
|
||||||
|
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath });
|
||||||
|
}
|
||||||
|
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback });
|
||||||
|
}
|
||||||
|
exports.getEnvVars = getEnvVars;
|
||||||
|
async function getEnvFile({ filePath, fallback }) {
|
||||||
|
// Use env file
|
||||||
|
if (filePath !== undefined) {
|
||||||
|
try {
|
||||||
|
return await parse_env_file_1.getEnvFileVars(filePath);
|
||||||
|
}
|
||||||
|
catch (e) { }
|
||||||
|
if (fallback !== true) {
|
||||||
|
throw new Error(`Unable to locate env file at location (${filePath})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use the default env file locations
|
||||||
|
for (const path of ENV_FILE_DEFAULT_LOCATIONS) {
|
||||||
|
try {
|
||||||
|
return await parse_env_file_1.getEnvFileVars(path);
|
||||||
|
}
|
||||||
|
catch (e) { }
|
||||||
|
}
|
||||||
|
throw new Error(`Unable to locate env file at default locations (${ENV_FILE_DEFAULT_LOCATIONS})`);
|
||||||
|
}
|
||||||
|
exports.getEnvFile = getEnvFile;
|
||||||
|
async function getRCFile({ environments, filePath }) {
|
||||||
|
// User provided an .rc file path
|
||||||
|
if (filePath !== undefined) {
|
||||||
|
try {
|
||||||
|
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
if (e.name !== 'PathError')
|
||||||
|
console.error(e);
|
||||||
|
throw new Error(`Unable to locate .rc file at location (${filePath})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use the default .rc file locations
|
||||||
|
for (const filePath of RC_FILE_DEFAULT_LOCATIONS) {
|
||||||
|
try {
|
||||||
|
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
if (e.name !== 'PathError')
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(`Unable to locate .rc file at default locations (${RC_FILE_DEFAULT_LOCATIONS})`);
|
||||||
|
}
|
||||||
|
exports.getRCFile = getRCFile;
|
||||||
0
dist/index.d.ts → dist/src/index.d.ts
vendored
0
dist/index.d.ts → dist/src/index.d.ts
vendored
0
dist/index.js → dist/src/index.js
vendored
0
dist/index.js → dist/src/index.js
vendored
18
dist/parse-args.js → dist/src/parse-args.js
vendored
18
dist/parse-args.js → dist/src/parse-args.js
vendored
@ -15,16 +15,18 @@ function parseArgs(args) {
|
|||||||
const noOverride = !program.override;
|
const noOverride = !program.override;
|
||||||
const useShell = !!program.useShell;
|
const useShell = !!program.useShell;
|
||||||
let rc;
|
let rc;
|
||||||
if (program.environments && program.environments.length) {
|
if (program.environments !== undefined && program.environments.length !== 0) {
|
||||||
rc = rc || {};
|
rc = {
|
||||||
rc.environments = program.environments;
|
environments: program.environments,
|
||||||
rc.filePath = program.rcFile;
|
filePath: program.rcFile
|
||||||
|
};
|
||||||
}
|
}
|
||||||
let envFile;
|
let envFile;
|
||||||
if (program.file) {
|
if (program.file !== undefined) {
|
||||||
envFile = envFile || {};
|
envFile = {
|
||||||
envFile.filePath = program.file;
|
filePath: program.file,
|
||||||
envFile.fallback = program.fallback;
|
fallback: program.fallback
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
command,
|
command,
|
||||||
@ -15,7 +15,7 @@ async function getEnvFileVars(envFilePath) {
|
|||||||
// Get the file extension
|
// Get the file extension
|
||||||
const ext = path.extname(absolutePath).toLowerCase();
|
const ext = path.extname(absolutePath).toLowerCase();
|
||||||
let env = {};
|
let env = {};
|
||||||
if (~REQUIRE_HOOK_EXTENSIONS.indexOf(ext)) {
|
if (REQUIRE_HOOK_EXTENSIONS.indexOf(ext) > -1) {
|
||||||
const possiblePromise = require(absolutePath); /* eslint-disable-line */
|
const possiblePromise = require(absolutePath); /* eslint-disable-line */
|
||||||
env = utils_1.isPromise(possiblePromise) ? await possiblePromise : possiblePromise;
|
env = utils_1.isPromise(possiblePromise) ? await possiblePromise : possiblePromise;
|
||||||
}
|
}
|
||||||
@ -48,11 +48,11 @@ function parseEnvVars(envString) {
|
|||||||
while ((match = envParseRegex.exec(envString)) !== null) {
|
while ((match = envParseRegex.exec(envString)) !== null) {
|
||||||
// Note: match[1] is the full env=var line
|
// Note: match[1] is the full env=var line
|
||||||
const key = match[2].trim();
|
const key = match[2].trim();
|
||||||
const value = match[3].trim() || '';
|
const value = match[3].trim();
|
||||||
// remove any surrounding quotes
|
// remove any surrounding quotes
|
||||||
matches[key] = value
|
matches[key] = value
|
||||||
.replace(/(^['"]|['"]$)/g, '')
|
.replace(/(^['"]|['"]$)/g, '')
|
||||||
.replace(/\\n/g, `\n`);
|
.replace(/\\n/g, '\n');
|
||||||
}
|
}
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ async function getRCFileVars({ environments, filePath }) {
|
|||||||
let environmentFound = false;
|
let environmentFound = false;
|
||||||
environments.forEach((name) => {
|
environments.forEach((name) => {
|
||||||
const envVars = parsedData[name];
|
const envVars = parsedData[name];
|
||||||
if (envVars) {
|
if (envVars !== undefined) {
|
||||||
environmentFound = true;
|
environmentFound = true;
|
||||||
result = Object.assign({}, result, envVars);
|
result = Object.assign({}, result, envVars);
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ function parseRCFile(fileData) {
|
|||||||
console.error(`Error:
|
console.error(`Error:
|
||||||
Failed to parse the .rc file.
|
Failed to parse the .rc file.
|
||||||
Please make sure its a valid JSON format.`);
|
Please make sure its a valid JSON format.`);
|
||||||
throw new Error(`Unable to parse JSON in .rc file.`);
|
throw new Error('Unable to parse JSON in .rc file.');
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/// <reference types="node" />
|
/// <reference types="node" />
|
||||||
import { ChildProcess } from 'child_process';
|
import { ChildProcess } from 'child_process';
|
||||||
export declare class TermSignals {
|
export declare class TermSignals {
|
||||||
private terminateSpawnedProcessFuncHandlers;
|
private readonly terminateSpawnedProcessFuncHandlers;
|
||||||
_exitCalled: boolean;
|
_exitCalled: boolean;
|
||||||
handleTermSignals(proc: ChildProcess): void;
|
handleTermSignals(proc: ChildProcess): void;
|
||||||
/**
|
/**
|
||||||
@ -22,7 +22,7 @@ class TermSignals {
|
|||||||
};
|
};
|
||||||
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
|
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
|
||||||
});
|
});
|
||||||
process.once('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']);
|
process.once('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM);
|
||||||
// Terminate parent process if child process receives termination events
|
// Terminate parent process if child process receives termination events
|
||||||
proc.on('exit', (code, signal) => {
|
proc.on('exit', (code, signal) => {
|
||||||
this._removeProcessListeners();
|
this._removeProcessListeners();
|
||||||
@ -42,10 +42,10 @@ class TermSignals {
|
|||||||
* Terminate parent process helper
|
* Terminate parent process helper
|
||||||
*/
|
*/
|
||||||
_terminateProcess(code, signal) {
|
_terminateProcess(code, signal) {
|
||||||
if (signal != null) {
|
if (signal !== undefined) {
|
||||||
return process.kill(process.pid, signal);
|
return process.kill(process.pid, signal);
|
||||||
}
|
}
|
||||||
if (code != null) {
|
if (code !== undefined) {
|
||||||
return process.exit(code);
|
return process.exit(code);
|
||||||
}
|
}
|
||||||
throw new Error('Unable to terminate parent process successfully');
|
throw new Error('Unable to terminate parent process successfully');
|
||||||
@ -57,7 +57,7 @@ class TermSignals {
|
|||||||
SIGNALS_TO_HANDLE.forEach((signal) => {
|
SIGNALS_TO_HANDLE.forEach((signal) => {
|
||||||
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
|
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
|
||||||
});
|
});
|
||||||
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']);
|
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* General exception handler
|
* General exception handler
|
||||||
0
dist/spawn.d.ts → dist/src/spawn.d.ts
vendored
0
dist/spawn.d.ts → dist/src/spawn.d.ts
vendored
0
dist/spawn.js → dist/src/spawn.js
vendored
0
dist/spawn.js → dist/src/spawn.js
vendored
0
dist/types.d.ts → dist/src/types.d.ts
vendored
0
dist/types.d.ts → dist/src/types.d.ts
vendored
0
dist/types.js → dist/src/types.js
vendored
0
dist/types.js → dist/src/types.js
vendored
2
dist/utils.d.ts → dist/src/utils.d.ts
vendored
2
dist/utils.d.ts → dist/src/utils.d.ts
vendored
@ -9,4 +9,4 @@ export declare function parseArgList(list: string): string[];
|
|||||||
/**
|
/**
|
||||||
* A simple function to test if the value is a promise
|
* A simple function to test if the value is a promise
|
||||||
*/
|
*/
|
||||||
export declare function isPromise(value: any | PromiseLike<Object>): boolean;
|
export declare function isPromise(value: any | PromiseLike<Object>): value is Promise<any>;
|
||||||
4
dist/utils.js → dist/src/utils.js
vendored
4
dist/utils.js → dist/src/utils.js
vendored
@ -8,7 +8,7 @@ const os = require("os");
|
|||||||
function resolveEnvFilePath(userPath) {
|
function resolveEnvFilePath(userPath) {
|
||||||
// Make sure a home directory exist
|
// Make sure a home directory exist
|
||||||
const home = os.homedir();
|
const home = os.homedir();
|
||||||
if (home) {
|
if (home !== undefined) {
|
||||||
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`);
|
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`);
|
||||||
}
|
}
|
||||||
return path.resolve(process.cwd(), userPath);
|
return path.resolve(process.cwd(), userPath);
|
||||||
@ -25,6 +25,6 @@ exports.parseArgList = parseArgList;
|
|||||||
* A simple function to test if the value is a promise
|
* A simple function to test if the value is a promise
|
||||||
*/
|
*/
|
||||||
function isPromise(value) {
|
function isPromise(value) {
|
||||||
return value && typeof value.then === 'function';
|
return value !== undefined && typeof value.then === 'function';
|
||||||
}
|
}
|
||||||
exports.isPromise = isPromise;
|
exports.isPromise = isPromise;
|
||||||
15
package.json
15
package.json
@ -2,8 +2,8 @@
|
|||||||
"name": "env-cmd",
|
"name": "env-cmd",
|
||||||
"version": "10.0.0",
|
"version": "10.0.0",
|
||||||
"description": "Executes a command using the environment variables in an env file",
|
"description": "Executes a command using the environment variables in an env file",
|
||||||
"main": "dist/index.js",
|
"main": "dist/src/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/src/index.d.ts",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
},
|
},
|
||||||
@ -48,7 +48,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/toddbluhm/env-cmd#readme",
|
"homepage": "https://github.com/toddbluhm/env-cmd#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^2.0.0",
|
"commander": "^3.0.0",
|
||||||
"cross-spawn": "^6.0.0"
|
"cross-spawn": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -57,12 +57,13 @@
|
|||||||
"@types/mocha": "^5.0.0",
|
"@types/mocha": "^5.0.0",
|
||||||
"@types/node": "^12.0.0",
|
"@types/node": "^12.0.0",
|
||||||
"@types/sinon": "^7.0.0",
|
"@types/sinon": "^7.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^1.0.0",
|
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||||
"@typescript-eslint/parser": "^1.0.0",
|
"@typescript-eslint/parser": "^2.0.0",
|
||||||
"chai": "^4.0.0",
|
"chai": "^4.0.0",
|
||||||
"coveralls": "^3.0.0",
|
"coveralls": "^3.0.0",
|
||||||
"eslint": "^5.0.0",
|
"eslint": "^6.0.0",
|
||||||
"eslint-config-standard-with-typescript": "^8.0.0",
|
"eslint-config-standard": "^14.0.0",
|
||||||
|
"eslint-config-standard-with-typescript": "toddbluhm/eslint-config-standard-with-typescript#compiled",
|
||||||
"eslint-plugin-import": "^2.0.0",
|
"eslint-plugin-import": "^2.0.0",
|
||||||
"eslint-plugin-node": "^9.0.0",
|
"eslint-plugin-node": "^9.0.0",
|
||||||
"eslint-plugin-promise": "^4.0.0",
|
"eslint-plugin-promise": "^4.0.0",
|
||||||
|
|||||||
@ -32,12 +32,11 @@ export async function CLI (args: string[]): Promise<{ [key: string]: any }> {
|
|||||||
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
|
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
|
||||||
*/
|
*/
|
||||||
export async function EnvCmd (
|
export async function EnvCmd (
|
||||||
{ command, commandArgs, envFile, rc, options }: EnvCmdOptions
|
{ command, commandArgs, envFile, rc, options = {} }: EnvCmdOptions
|
||||||
): Promise<{ [key: string]: any }> {
|
): Promise<{ [key: string]: any }> {
|
||||||
options = options || {}
|
|
||||||
let env = await getEnvVars({ envFile, rc })
|
let env = await getEnvVars({ envFile, rc })
|
||||||
// Override the merge order if --no-override flag set
|
// Override the merge order if --no-override flag set
|
||||||
if (options.noOverride) {
|
if (options.noOverride === true) {
|
||||||
env = Object.assign({}, env, process.env)
|
env = Object.assign({}, env, process.env)
|
||||||
} else {
|
} else {
|
||||||
// Add in the system environment variables to our environment list
|
// Add in the system environment variables to our environment list
|
||||||
|
|||||||
@ -5,11 +5,10 @@ import { getEnvFileVars } from './parse-env-file'
|
|||||||
const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json']
|
const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json']
|
||||||
const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json']
|
const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json']
|
||||||
|
|
||||||
export async function getEnvVars (options?: GetEnvVarOptions): Promise<{ [key: string]: any }> {
|
export async function getEnvVars (options: GetEnvVarOptions = {}): Promise<{ [key: string]: any }> {
|
||||||
options = options || {}
|
options.envFile = options.envFile !== undefined ? options.envFile : {}
|
||||||
options.envFile = options.envFile || {}
|
|
||||||
// Check for rc file usage
|
// Check for rc file usage
|
||||||
if (options.rc) {
|
if (options.rc !== undefined) {
|
||||||
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath })
|
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath })
|
||||||
}
|
}
|
||||||
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback })
|
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback })
|
||||||
@ -19,11 +18,11 @@ export async function getEnvFile (
|
|||||||
{ filePath, fallback }: { filePath?: string, fallback?: boolean }
|
{ filePath, fallback }: { filePath?: string, fallback?: boolean }
|
||||||
): Promise<{ [key: string]: any }> {
|
): Promise<{ [key: string]: any }> {
|
||||||
// Use env file
|
// Use env file
|
||||||
if (filePath) {
|
if (filePath !== undefined) {
|
||||||
try {
|
try {
|
||||||
return await getEnvFileVars(filePath)
|
return await getEnvFileVars(filePath)
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
if (!fallback) {
|
if (fallback !== true) {
|
||||||
throw new Error(`Unable to locate env file at location (${filePath})`)
|
throw new Error(`Unable to locate env file at location (${filePath})`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,11 +41,11 @@ export async function getRCFile (
|
|||||||
{ environments, filePath }: { environments: string[], filePath?: string }
|
{ environments, filePath }: { environments: string[], filePath?: string }
|
||||||
): Promise<{ [key: string]: any }> {
|
): Promise<{ [key: string]: any }> {
|
||||||
// User provided an .rc file path
|
// User provided an .rc file path
|
||||||
if (filePath) {
|
if (filePath !== undefined) {
|
||||||
try {
|
try {
|
||||||
return await getRCFileVars({ environments, filePath })
|
return await getRCFileVars({ environments, filePath })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name !== 'PathError') console.log(e)
|
if (e.name !== 'PathError') console.error(e)
|
||||||
throw new Error(`Unable to locate .rc file at location (${filePath})`)
|
throw new Error(`Unable to locate .rc file at location (${filePath})`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,7 +55,7 @@ export async function getRCFile (
|
|||||||
try {
|
try {
|
||||||
return await getRCFileVars({ environments, filePath })
|
return await getRCFileVars({ environments, filePath })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.name !== 'PathError') console.log(e)
|
if (e.name !== 'PathError') console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,21 +13,23 @@ export function parseArgs (args: string[]): EnvCmdOptions {
|
|||||||
|
|
||||||
// Reprocess the args with the command and command args removed
|
// Reprocess the args with the command and command args removed
|
||||||
program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))
|
program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))
|
||||||
const noOverride = !program.override
|
const noOverride = !(program.override as boolean)
|
||||||
const useShell = !!program.useShell
|
const useShell = !!(program.useShell as boolean)
|
||||||
|
|
||||||
let rc: any
|
let rc: any
|
||||||
if (program.environments && program.environments.length) {
|
if (program.environments !== undefined && program.environments.length !== 0) {
|
||||||
rc = rc || {}
|
rc = {
|
||||||
rc.environments = program.environments
|
environments: program.environments,
|
||||||
rc.filePath = program.rcFile
|
filePath: program.rcFile
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let envFile: any
|
let envFile: any
|
||||||
if (program.file) {
|
if (program.file !== undefined) {
|
||||||
envFile = envFile || {}
|
envFile = {
|
||||||
envFile.filePath = program.file
|
filePath: program.file,
|
||||||
envFile.fallback = program.fallback
|
fallback: program.fallback
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export async function getEnvFileVars (envFilePath: string): Promise<{ [key: stri
|
|||||||
// Get the file extension
|
// Get the file extension
|
||||||
const ext = path.extname(absolutePath).toLowerCase()
|
const ext = path.extname(absolutePath).toLowerCase()
|
||||||
let env = {}
|
let env = {}
|
||||||
if (~REQUIRE_HOOK_EXTENSIONS.indexOf(ext)) {
|
if (REQUIRE_HOOK_EXTENSIONS.indexOf(ext) > -1) {
|
||||||
const possiblePromise = require(absolutePath) /* eslint-disable-line */
|
const possiblePromise = require(absolutePath) /* eslint-disable-line */
|
||||||
env = isPromise(possiblePromise) ? await possiblePromise : possiblePromise
|
env = isPromise(possiblePromise) ? await possiblePromise : possiblePromise
|
||||||
} else {
|
} else {
|
||||||
@ -50,12 +50,12 @@ export function parseEnvVars (envString: string): { [key: string]: string } {
|
|||||||
while ((match = envParseRegex.exec(envString)) !== null) {
|
while ((match = envParseRegex.exec(envString)) !== null) {
|
||||||
// Note: match[1] is the full env=var line
|
// Note: match[1] is the full env=var line
|
||||||
const key = match[2].trim()
|
const key = match[2].trim()
|
||||||
const value = match[3].trim() || ''
|
const value = match[3].trim()
|
||||||
|
|
||||||
// remove any surrounding quotes
|
// remove any surrounding quotes
|
||||||
matches[key] = value
|
matches[key] = value
|
||||||
.replace(/(^['"]|['"]$)/g, '')
|
.replace(/(^['"]|['"]$)/g, '')
|
||||||
.replace(/\\n/g, `\n`)
|
.replace(/\\n/g, '\n')
|
||||||
}
|
}
|
||||||
return matches
|
return matches
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export async function getRCFileVars (
|
|||||||
let environmentFound = false
|
let environmentFound = false
|
||||||
environments.forEach((name): void => {
|
environments.forEach((name): void => {
|
||||||
const envVars = parsedData[name]
|
const envVars = parsedData[name]
|
||||||
if (envVars) {
|
if (envVars !== undefined) {
|
||||||
environmentFound = true
|
environmentFound = true
|
||||||
result = {
|
result = {
|
||||||
...result,
|
...result,
|
||||||
@ -70,7 +70,7 @@ export function parseRCFile (fileData: string): { [key: string]: any } {
|
|||||||
console.error(`Error:
|
console.error(`Error:
|
||||||
Failed to parse the .rc file.
|
Failed to parse the .rc file.
|
||||||
Please make sure its a valid JSON format.`)
|
Please make sure its a valid JSON format.`)
|
||||||
throw new Error(`Unable to parse JSON in .rc file.`)
|
throw new Error('Unable to parse JSON in .rc file.')
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ const SIGNALS_TO_HANDLE: NodeJS.Signals[] = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export class TermSignals {
|
export class TermSignals {
|
||||||
private terminateSpawnedProcessFuncHandlers: { [key: string]: any } = {}
|
private readonly terminateSpawnedProcessFuncHandlers: { [key: string]: any } = {}
|
||||||
public _exitCalled = false
|
public _exitCalled = false
|
||||||
|
|
||||||
public handleTermSignals (proc: ChildProcess): void {
|
public handleTermSignals (proc: ChildProcess): void {
|
||||||
@ -22,7 +22,7 @@ export class TermSignals {
|
|||||||
}
|
}
|
||||||
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal])
|
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal])
|
||||||
})
|
})
|
||||||
process.once('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM'])
|
process.once('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM)
|
||||||
|
|
||||||
// Terminate parent process if child process receives termination events
|
// Terminate parent process if child process receives termination events
|
||||||
proc.on('exit', (code: number | undefined, signal: string | undefined): void => {
|
proc.on('exit', (code: number | undefined, signal: string | undefined): void => {
|
||||||
@ -45,10 +45,10 @@ export class TermSignals {
|
|||||||
* Terminate parent process helper
|
* Terminate parent process helper
|
||||||
*/
|
*/
|
||||||
public _terminateProcess (code?: number, signal?: string): void {
|
public _terminateProcess (code?: number, signal?: string): void {
|
||||||
if (signal != null) {
|
if (signal !== undefined) {
|
||||||
return process.kill(process.pid, signal)
|
return process.kill(process.pid, signal)
|
||||||
}
|
}
|
||||||
if (code != null) {
|
if (code !== undefined) {
|
||||||
return process.exit(code)
|
return process.exit(code)
|
||||||
}
|
}
|
||||||
throw new Error('Unable to terminate parent process successfully')
|
throw new Error('Unable to terminate parent process successfully')
|
||||||
@ -61,7 +61,7 @@ export class TermSignals {
|
|||||||
SIGNALS_TO_HANDLE.forEach((signal): void => {
|
SIGNALS_TO_HANDLE.forEach((signal): void => {
|
||||||
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal])
|
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal])
|
||||||
})
|
})
|
||||||
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM'])
|
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import * as os from 'os'
|
|||||||
export function resolveEnvFilePath (userPath: string): string {
|
export function resolveEnvFilePath (userPath: string): string {
|
||||||
// Make sure a home directory exist
|
// Make sure a home directory exist
|
||||||
const home = os.homedir()
|
const home = os.homedir()
|
||||||
if (home) {
|
if (home !== undefined) {
|
||||||
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`)
|
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`)
|
||||||
}
|
}
|
||||||
return path.resolve(process.cwd(), userPath)
|
return path.resolve(process.cwd(), userPath)
|
||||||
@ -22,6 +22,6 @@ export function parseArgList (list: string): string[] {
|
|||||||
/**
|
/**
|
||||||
* A simple function to test if the value is a promise
|
* A simple function to test if the value is a promise
|
||||||
*/
|
*/
|
||||||
export function isPromise (value: any | PromiseLike<Object>): boolean {
|
export function isPromise (value: any | PromiseLike<Object>): value is Promise<any> {
|
||||||
return value && typeof value.then === 'function'
|
return value !== undefined && typeof value.then === 'function'
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import * as envFile from '../src/parse-env-file'
|
|||||||
describe('getEnvVars', (): void => {
|
describe('getEnvVars', (): void => {
|
||||||
let getRCFileVarsStub: sinon.SinonStub<any, any>
|
let getRCFileVarsStub: sinon.SinonStub<any, any>
|
||||||
let getEnvFileVarsStub: sinon.SinonStub<any, any>
|
let getEnvFileVarsStub: sinon.SinonStub<any, any>
|
||||||
|
let logStub: sinon.SinonStub<any, any>
|
||||||
|
|
||||||
const pathError = new Error()
|
const pathError = new Error()
|
||||||
pathError.name = 'PathError'
|
pathError.name = 'PathError'
|
||||||
@ -14,6 +15,7 @@ describe('getEnvVars', (): void => {
|
|||||||
before((): void => {
|
before((): void => {
|
||||||
getRCFileVarsStub = sinon.stub(rcFile, 'getRCFileVars')
|
getRCFileVarsStub = sinon.stub(rcFile, 'getRCFileVars')
|
||||||
getEnvFileVarsStub = sinon.stub(envFile, 'getEnvFileVars')
|
getEnvFileVarsStub = sinon.stub(envFile, 'getEnvFileVars')
|
||||||
|
logStub = sinon.stub(console, 'error')
|
||||||
})
|
})
|
||||||
|
|
||||||
after((): void => {
|
after((): void => {
|
||||||
@ -62,6 +64,17 @@ describe('getEnvVars', (): void => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should log to error console on non-path errors', async (): Promise<void> => {
|
||||||
|
getRCFileVarsStub.rejects(new Error('Non-path Error'))
|
||||||
|
try {
|
||||||
|
await getEnvVars({ rc: { environments: ['production'] } })
|
||||||
|
assert.fail('should not get here.')
|
||||||
|
} catch (e) {
|
||||||
|
assert.match(logStub.getCall(0).args[0].message, /non-path error/gi)
|
||||||
|
assert.match(e.message, /locate \.rc/gi)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('should find .rc file at custom path location', async (): Promise<void> => {
|
it('should find .rc file at custom path location', async (): Promise<void> => {
|
||||||
getRCFileVarsStub.returns({ THANKS: 'FORALLTHEFISH' })
|
getRCFileVarsStub.returns({ THANKS: 'FORALLTHEFISH' })
|
||||||
const envs = await getEnvVars({
|
const envs = await getEnvVars({
|
||||||
@ -84,7 +97,19 @@ describe('getEnvVars', (): void => {
|
|||||||
})
|
})
|
||||||
assert.fail('should not get here.')
|
assert.fail('should not get here.')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e)
|
assert.match(e.message, /locate \.rc/gi)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should log to error console on non-path errors', async (): Promise<void> => {
|
||||||
|
getRCFileVarsStub.rejects(new Error('Non-path Error'))
|
||||||
|
try {
|
||||||
|
await getEnvVars({
|
||||||
|
rc: { environments: ['production'], filePath: '../.custom-rc' }
|
||||||
|
})
|
||||||
|
assert.fail('should not get here.')
|
||||||
|
} catch (e) {
|
||||||
|
assert.match(logStub.getCall(0).args[0].message, /non-path error/gi)
|
||||||
assert.match(e.message, /locate \.rc/gi)
|
assert.match(e.message, /locate \.rc/gi)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -63,7 +63,7 @@ describe('parseEnvVars', (): void => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should preserve newlines when surrounded in quotes', (): void => {
|
it('should preserve newlines when surrounded in quotes', (): void => {
|
||||||
const envVars = parseEnvVars(`ONE_NEWLINE="ONE\\n"\nTWO_NEWLINES="HELLO\\nWORLD\\n"\nTHREE_NEWLINES="HELLO\\n\\nWOR\\nLD"\n`)
|
const envVars = parseEnvVars('ONE_NEWLINE="ONE\\n"\nTWO_NEWLINES="HELLO\\nWORLD\\n"\nTHREE_NEWLINES="HELLO\\n\\nWOR\\nLD"\n')
|
||||||
assert(envVars.ONE_NEWLINE === 'ONE\n')
|
assert(envVars.ONE_NEWLINE === 'ONE\n')
|
||||||
assert(envVars.TWO_NEWLINES === 'HELLO\nWORLD\n')
|
assert(envVars.TWO_NEWLINES === 'HELLO\nWORLD\n')
|
||||||
assert(envVars.THREE_NEWLINES === 'HELLO\n\nWOR\nLD')
|
assert(envVars.THREE_NEWLINES === 'HELLO\n\nWOR\nLD')
|
||||||
@ -104,47 +104,47 @@ describe('getEnvFileVars', (): void => {
|
|||||||
it('should parse a json file', async (): Promise<void> => {
|
it('should parse a json file', async (): Promise<void> => {
|
||||||
const env = await getEnvFileVars('./test/test-files/test.json')
|
const env = await getEnvFileVars('./test/test-files/test.json')
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR WHAT?!',
|
THANKS: 'FOR WHAT?!',
|
||||||
'ANSWER': 42,
|
ANSWER: 42,
|
||||||
'ONLY': 'IN PRODUCTION',
|
ONLY: 'IN PRODUCTION',
|
||||||
'GALAXY': 'hitch\nhiking'
|
GALAXY: 'hitch\nhiking'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should parse a json file keeping all newlines intact', async (): Promise<void> => {
|
it('should parse a json file keeping all newlines intact', async (): Promise<void> => {
|
||||||
const env = await getEnvFileVars('./test/test-files/test-newlines.json')
|
const env = await getEnvFileVars('./test/test-files/test-newlines.json')
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR WHAT?!',
|
THANKS: 'FOR WHAT?!',
|
||||||
'ANSWER': 42,
|
ANSWER: 42,
|
||||||
'ONLY': 'IN\n PRODUCTION',
|
ONLY: 'IN\n PRODUCTION',
|
||||||
'GALAXY': 'hitch\nhiking\n\n'
|
GALAXY: 'hitch\nhiking\n\n'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should parse a js file', async (): Promise<void> => {
|
it('should parse a js file', async (): Promise<void> => {
|
||||||
const env = await getEnvFileVars('./test/test-files/test.js')
|
const env = await getEnvFileVars('./test/test-files/test.js')
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR ALL THE FISH',
|
THANKS: 'FOR ALL THE FISH',
|
||||||
'ANSWER': 0,
|
ANSWER: 0,
|
||||||
'GALAXY': 'hitch\nhiking'
|
GALAXY: 'hitch\nhiking'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should parse an async js file', async (): Promise<void> => {
|
it('should parse an async js file', async (): Promise<void> => {
|
||||||
const env = await getEnvFileVars('./test/test-files/test-async.js')
|
const env = await getEnvFileVars('./test/test-files/test-async.js')
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR ALL THE FISH',
|
THANKS: 'FOR ALL THE FISH',
|
||||||
'ANSWER': 0
|
ANSWER: 0
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should parse an env file', async (): Promise<void> => {
|
it('should parse an env file', async (): Promise<void> => {
|
||||||
const env = await getEnvFileVars('./test/test-files/test')
|
const env = await getEnvFileVars('./test/test-files/test')
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR WHAT?!',
|
THANKS: 'FOR WHAT?!',
|
||||||
'ANSWER': '42',
|
ANSWER: '42',
|
||||||
'ONLY': 'IN=PRODUCTION',
|
ONLY: 'IN=PRODUCTION',
|
||||||
'GALAXY': 'hitch\nhiking'
|
GALAXY: 'hitch\nhiking'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -30,9 +30,9 @@ describe('getRCFileVars', (): void => {
|
|||||||
const res = await getRCFileVars({ environments: ['production'], filePath: rcFilePath })
|
const res = await getRCFileVars({ environments: ['production'], filePath: rcFilePath })
|
||||||
assert.exists(res)
|
assert.exists(res)
|
||||||
assert.deepEqual(res, {
|
assert.deepEqual(res, {
|
||||||
'THANKS': 'FOR WHAT?!',
|
THANKS: 'FOR WHAT?!',
|
||||||
'ANSWER': 42,
|
ANSWER: 42,
|
||||||
'ONLY': 'IN PRODUCTION'
|
ONLY: 'IN PRODUCTION'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ describe('getRCFileVars', (): void => {
|
|||||||
const res = await getRCFileVars({ environments: ['test'], filePath: rcJSONFilePath })
|
const res = await getRCFileVars({ environments: ['test'], filePath: rcJSONFilePath })
|
||||||
assert.exists(res)
|
assert.exists(res)
|
||||||
assert.deepEqual(res, {
|
assert.deepEqual(res, {
|
||||||
'THANKS': 'FOR MORE FISHIES',
|
THANKS: 'FOR MORE FISHIES',
|
||||||
'ANSWER': 21
|
ANSWER: 21
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ describe('getRCFileVars', (): void => {
|
|||||||
filePath: './test/test-files/.rc-test-async.js'
|
filePath: './test/test-files/.rc-test-async.js'
|
||||||
})
|
})
|
||||||
assert.deepEqual(env, {
|
assert.deepEqual(env, {
|
||||||
'THANKS': 'FOR WHAT?!',
|
THANKS: 'FOR WHAT?!',
|
||||||
'ANSWER': 42,
|
ANSWER: 42,
|
||||||
'ONLY': 'IN PRODUCTION'
|
ONLY: 'IN PRODUCTION'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"./src/**/*"
|
"./src/**/*",
|
||||||
|
"./test/**/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user