Skip to content

Commit

Permalink
Merge pull request #376 from toddbluhm/dependabot/npm_and_yarn/comman…
Browse files Browse the repository at this point in the history
…der-12.1.0

chore(deps)!: bump commander from 5.1.0 to 12.1.0
  • Loading branch information
toddbluhm authored Dec 3, 2024
2 parents 8f6bbbf + 9942f3c commit e51b320
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 94 deletions.
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ ENV3=THE FISH
```json
{
"scripts": {
"test": "env-cmd mocha -R spec"
"test": "env-cmd -- mocha -R spec"
}
}
```

**Terminal**

```sh
./node_modules/.bin/env-cmd node index.js
./node_modules/.bin/env-cmd -- node index.js
```

### Using custom env file path
Expand All @@ -48,13 +48,13 @@ To use a custom env filename or path, pass the `-f` flag. This is a major breaki
**Terminal**

```sh
./node_modules/.bin/env-cmd -f ./custom/path/.env node index.js
./node_modules/.bin/env-cmd -f ./custom/path/.env -- node index.js
```

## 📜 Help

```text
Usage: _ [options] <command> [...args]
Usage: env-cmd [options] -- <command> [...args]
Options:
-v, --version output the version number
Expand Down Expand Up @@ -101,10 +101,10 @@ are found.
**Terminal**

```sh
./node_modules/.bin/env-cmd -e production node index.js
./node_modules/.bin/env-cmd -e production -- node index.js
# Or for multiple environments (where `production` vars override `test` vars,
# but both are included)
./node_modules/.bin/env-cmd -e test,production node index.js
./node_modules/.bin/env-cmd -e test,production -- node index.js
```

### `--no-override` option
Expand All @@ -125,7 +125,7 @@ commands together that share the same environment variables.
**Terminal**

```sh
./node_modules/.bin/env-cmd -f ./test/.env --use-shell "npm run lint && npm test"
./node_modules/.bin/env-cmd -f ./test/.env --use-shell -- "npm run lint && npm test"
```

### Asynchronous env file support
Expand All @@ -138,7 +138,7 @@ commands together that share the same environment variables.
**Terminal**

```sh
./node_modules/.bin/env-cmd -f ./async-file.js node index.js
./node_modules/.bin/env-cmd -f ./async-file.js -- node index.js
```

### `-x` expands vars in arguments
Expand All @@ -152,14 +152,14 @@ to provide arguments to a command that are based on environment variable values

```sh
# $VAR will be expanded into the env value it contains at runtime
./node_modules/.bin/env-cmd -x node index.js --arg=\$VAR
./node_modules/.bin/env-cmd -x -- node index.js --arg=\$VAR
```

or in `package.json` (use `\\` to insert a literal backslash)
```json
{
"script": {
"start": "env-cmd -x node index.js --arg=\\$VAR"
"start": "env-cmd -x -- node index.js --arg=\\$VAR"
}
}
```
Expand Down Expand Up @@ -252,11 +252,6 @@ usually just easier to have a file with all the vars in them, especially for dev

[`cross-env`](https://github.com/kentcdodds/cross-env) - Cross platform setting of environment scripts

## 🎊 Special Thanks

Special thanks to [`cross-env`](https://github.com/kentcdodds/cross-env) for inspiration (uses the
same `cross-spawn` lib underneath too).

## 📋 Contributing Guide

I welcome all pull requests. Please make sure you add appropriate test cases for any features
Expand Down
53 changes: 30 additions & 23 deletions dist/parse-args.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as commander from 'commander';
import { Command } from '@commander-js/extra-typings';
import { parseArgList } from './utils.js';
import { default as packageJson } from '../package.json' with { type: 'json' };
/**
Expand All @@ -7,48 +7,55 @@ import { default as packageJson } from '../package.json' with { type: 'json' };
export function parseArgs(args) {
// Run the initial arguments through commander in order to determine
// which value in the args array is the `command` to execute
let program = parseArgsUsingCommander(args);
const program = parseArgsUsingCommander(args);
const command = program.args[0];
// Grab all arguments after the `command` in the args array
const commandArgs = args.splice(args.indexOf(command) + 1);
// Reprocess the args with the command and command arguments removed
program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)));
// program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))
const parsedCmdOptions = program.opts();
// Set values for provided options
let noOverride = false;
// In commander `no-` negates the original value `override`
if (program.override === false) {
if (parsedCmdOptions.override === false) {
noOverride = true;
}
let useShell = false;
if (program.useShell === true) {
if (parsedCmdOptions.useShell === true) {
useShell = true;
}
let expandEnvs = false;
if (program.expandEnvs === true) {
if (parsedCmdOptions.expandEnvs === true) {
expandEnvs = true;
}
let verbose = false;
if (program.verbose === true) {
if (parsedCmdOptions.verbose === true) {
verbose = true;
}
let silent = false;
if (program.silent === true) {
if (parsedCmdOptions.silent === true) {
silent = true;
}
let rc;
if (program.environments !== undefined
&& Array.isArray(program.environments)
&& program.environments.length !== 0) {
if (parsedCmdOptions.environments !== undefined
&& Array.isArray(parsedCmdOptions.environments)
&& parsedCmdOptions.environments.length !== 0) {
rc = {
environments: program.environments,
filePath: program.rcFile,
environments: parsedCmdOptions.environments,
// if we get a boolean value assume not defined
filePath: parsedCmdOptions.rcFile === true ?
undefined :
parsedCmdOptions.rcFile,
};
}
let envFile;
if (program.file !== undefined) {
if (parsedCmdOptions.file !== undefined) {
envFile = {
filePath: program.file,
fallback: program.fallback,
// if we get a boolean value assume not defined
filePath: parsedCmdOptions.file === true ?
undefined :
parsedCmdOptions.file,
fallback: parsedCmdOptions.fallback,
};
}
const options = {
Expand All @@ -70,19 +77,19 @@ export function parseArgs(args) {
return options;
}
export function parseArgsUsingCommander(args) {
const program = new commander.Command();
return program
return new Command('env-cmd')
.description('CLI for executing commands using an environment from an env file.')
.version(packageJson.version, '-v, --version')
.usage('[options] <command> [...args]')
.option('-e, --environments [env1,env2,...]', 'The rc file environment(s) to use', parseArgList)
.usage('[options] -- <command> [...args]')
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
.option('-f, --file [path]', 'Custom env file path (default path: ./.env)')
.option('-r, --rc-file [path]', 'Custom rc file path (default path: ./.env-cmdrc.(js|cjs|mjs|json)')
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
.option('--no-override', 'Do not override existing environment variables')
.option('-r, --rc-file [path]', 'Custom rc file path (default path: ./.env-cmdrc(|.js|.json)')
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
.option('--use-shell', 'Execute the command in a new shell with the given environment')
.option('--verbose', 'Print helpful debugging information')
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
.allowUnknownOption(true)
.parse(['_', '_', ...args]);
.parse(['_', '_', ...args], { from: 'node' });
}
18 changes: 9 additions & 9 deletions dist/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Command } from 'commander';
import type { Command } from '@commander-js/extra-typings';
export type Environment = Partial<Record<string, string | number | boolean>>;
export type RCEnvironment = Partial<Record<string, Environment>>;
export interface CommanderOptions extends Command {
export type CommanderOptions = Command<[], {
environments?: true | string[];
expandEnvs?: boolean;
fallback?: boolean;
file?: true | string;
override?: boolean;
rcFile?: true | string;
silent?: boolean;
useShell?: boolean;
expandEnvs?: boolean;
verbose?: boolean;
silent?: boolean;
fallback?: boolean;
environments?: string[];
rcFile?: string;
file?: string;
}
}>;
export interface RCFileOptions {
environments: string[];
filePath?: string;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
},
"homepage": "https://github.com/toddbluhm/env-cmd#readme",
"dependencies": {
"commander": "^5.0.0",
"@commander-js/extra-typings": "^12.1.0",
"commander": "^12.1.0",
"cross-spawn": "^7.0.6"
},
"devDependencies": {
Expand Down
54 changes: 31 additions & 23 deletions src/parse-args.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as commander from 'commander'
import { Command } from '@commander-js/extra-typings'
import type { EnvCmdOptions, CommanderOptions, EnvFileOptions, RCFileOptions } from './types.ts'
import { parseArgList } from './utils.js'
import { default as packageJson } from '../package.json' with { type: 'json' };
Expand All @@ -9,54 +9,62 @@ import { default as packageJson } from '../package.json' with { type: 'json' };
export function parseArgs(args: string[]): EnvCmdOptions {
// Run the initial arguments through commander in order to determine
// which value in the args array is the `command` to execute
let program = parseArgsUsingCommander(args)
const program = parseArgsUsingCommander(args)

const command = program.args[0]
// Grab all arguments after the `command` in the args array
const commandArgs = args.splice(args.indexOf(command) + 1)

// Reprocess the args with the command and command arguments removed
program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))
// program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))

const parsedCmdOptions = program.opts()
// Set values for provided options
let noOverride = false
// In commander `no-` negates the original value `override`
if (program.override === false) {
if (parsedCmdOptions.override === false) {
noOverride = true
}
let useShell = false
if (program.useShell === true) {
if (parsedCmdOptions.useShell === true) {
useShell = true
}
let expandEnvs = false
if (program.expandEnvs === true) {
if (parsedCmdOptions.expandEnvs === true) {
expandEnvs = true
}
let verbose = false
if (program.verbose === true) {
if (parsedCmdOptions.verbose === true) {
verbose = true
}
let silent = false
if (program.silent === true) {
if (parsedCmdOptions.silent === true) {
silent = true
}

let rc: RCFileOptions | undefined
if (
program.environments !== undefined
&& Array.isArray(program.environments)
&& program.environments.length !== 0
parsedCmdOptions.environments !== undefined
&& Array.isArray(parsedCmdOptions.environments)
&& parsedCmdOptions.environments.length !== 0
) {
rc = {
environments: program.environments,
filePath: program.rcFile,
environments: parsedCmdOptions.environments,
// if we get a boolean value assume not defined
filePath: parsedCmdOptions.rcFile === true ?
undefined :
parsedCmdOptions.rcFile,
}
}

let envFile: EnvFileOptions | undefined
if (program.file !== undefined) {
if (parsedCmdOptions.file !== undefined) {
envFile = {
filePath: program.file,
fallback: program.fallback,
// if we get a boolean value assume not defined
filePath: parsedCmdOptions.file === true ?
undefined :
parsedCmdOptions.file,
fallback: parsedCmdOptions.fallback,
}
}

Expand All @@ -80,19 +88,19 @@ export function parseArgs(args: string[]): EnvCmdOptions {
}

export function parseArgsUsingCommander(args: string[]): CommanderOptions {
const program = new commander.Command() as CommanderOptions
return program
return new Command('env-cmd')
.description('CLI for executing commands using an environment from an env file.')
.version(packageJson.version, '-v, --version')
.usage('[options] <command> [...args]')
.option('-e, --environments [env1,env2,...]', 'The rc file environment(s) to use', parseArgList)
.usage('[options] -- <command> [...args]')
.option('-e, --environments [envs...]', 'The rc file environment(s) to use', parseArgList)
.option('-f, --file [path]', 'Custom env file path (default path: ./.env)')
.option('-r, --rc-file [path]', 'Custom rc file path (default path: ./.env-cmdrc.(js|cjs|mjs|json)')
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
.option('--fallback', 'Fallback to default env file path, if custom env file path not found')
.option('--no-override', 'Do not override existing environment variables')
.option('-r, --rc-file [path]', 'Custom rc file path (default path: ./.env-cmdrc(|.js|.json)')
.option('--silent', 'Ignore any env-cmd errors and only fail on executed program failure.')
.option('--use-shell', 'Execute the command in a new shell with the given environment')
.option('--verbose', 'Print helpful debugging information')
.option('-x, --expand-envs', 'Replace $var in args and command with environment variables')
.allowUnknownOption(true)
.parse(['_', '_', ...args])
.parse(['_', '_', ...args], { from: 'node' })
}
18 changes: 9 additions & 9 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { Command } from 'commander'
import type { Command } from '@commander-js/extra-typings'

// Define an export type
export type Environment = Partial<Record<string, string | number | boolean>>

export type RCEnvironment = Partial<Record<string, Environment>>

export interface CommanderOptions extends Command {
export type CommanderOptions = Command<[], {
environments?: true | string[]
expandEnvs?: boolean // Default: false
fallback?: boolean // Default false
file?: true | string
override?: boolean // Default: false
rcFile?: true | string
silent?: boolean // Default: false
useShell?: boolean // Default: false
expandEnvs?: boolean // Default: false
verbose?: boolean // Default: false
silent?: boolean // Default: false
fallback?: boolean // Default false
environments?: string[]
rcFile?: string
file?: string
}
}>

export interface RCFileOptions {
environments: string[]
Expand Down
Loading

0 comments on commit e51b320

Please sign in to comment.