Skip to content

Commit

Permalink
Improve options
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky committed May 10, 2019
1 parent 2eb9c8e commit cf7a221
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 26 deletions.
7 changes: 5 additions & 2 deletions src/exec.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import isCi from 'is-ci'
import execa from 'execa'
import PluginError from 'plugin-error'

Expand All @@ -13,10 +14,12 @@ import { printEcho } from './echo.js'
// with whitespaces escaping. Also escaping is shell-specific, e.g. on Windows
// `cmd.exe` only use double quotes not single quotes.
export const exec = function(input, opts) {
const optsA = parseOpts(opts)
return execCommand(input, optsA)
const optsB = parseOpts({ opts, defaultOpts })
return execCommand(input, optsB)
}

const defaultOpts = { verbose: isCi }

// Fire the command with `execa()`
export const execCommand = async function(input, opts) {
printEcho({ input, opts })
Expand Down
17 changes: 8 additions & 9 deletions src/options.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { validate } from 'jest-validate'
import isCi from 'is-ci'

import { pickBy } from './utils.js'

// Parse main arguments and options
// TODO: validate options (including that `input` is a string)
export const parseOpts = function(opts = {}) {
export const parseOpts = function({ opts = {}, defaultOpts, forcedOpts = {} }) {
const optsA = pickBy(opts, value => value !== undefined)
const optsB = { ...DEFAULT_OPTS, ...defaultOpts, ...optsA, ...forcedOpts }

validate(optsA, { exampleConfig: EXAMPLE_OPTS })
const exampleConfig = pickBy(
{ ...EXAMPLE_OPTS, ...defaultOpts },
(value, key) => forcedOpts[key] === undefined,
)
validate(optsB, { exampleConfig })

const optsB = { ...DEFAULT_OPTS, ...optsA }
const optsC = addStdio({ opts: optsB })
return optsC
}

const DEFAULT_OPTS = {
// We default `opts.echo` to `false` for less verbosity.
// However on CI we want to be verbose.
echo: isCi,
}
const DEFAULT_OPTS = {}

const EXAMPLE_OPTS = {
...DEFAULT_OPTS,
Expand Down
18 changes: 7 additions & 11 deletions src/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,23 @@ import { execCommand } from './exec.js'
// call to those functions would be more efficient that creating lots of
// child processes through streaming.
export const stream = function(mapFunc, opts) {
const optsA = { ...DEFAULT_OPTS, ...opts }
const { maxConcurrency, ...optsB } = parseOpts(optsA)
const { maxConcurrency, ...optsA } = parseOpts({ opts, defaultOpts })

// `maxConcurrency` `through2` option is not specified because `gulp.src()`
// always has a `highWaterMark` of `16` meaning only 16 files are processed
// at a time in parallel. `maxConcurrency` can then only be used to decrease
// that level of parallelism but `16` is already quite low.
return through.obj(
{ maxConcurrency },
execVinyl.bind(null, { mapFunc, opts: optsB }),
execVinyl.bind(null, { mapFunc, opts: optsA }),
)
}

const DEFAULT_OPTS = {
// Without `pipe`, `vinyl.exec` does not get `stdout|stderr` properties.
// Also we do not want to print to console by default because it would be
// done on each iteration.
stdout: 'pipe',
stderr: 'pipe',
// Prevents echoing by default because it would be done on each iteration.
echo: false,
const defaultOpts = {
// Prevents by default because it would be done on each iteration.
// Also without `stdout|stderr: pipe`, `vinyl.exec` does not get
// `stdout|stderr` properties.
verbose: false,
// The default is 16 which is too low
maxConcurrency: 100,
}
Expand Down
9 changes: 5 additions & 4 deletions src/task.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import isCi from 'is-ci'
import renameFn from 'rename-fn'

import { parseOpts } from './options.js'
import { execCommand } from './exec.js'

// Create a Gulp task
export const task = function(input, opts) {
const optsA = { ...opts, ...FORCED_OPTS }
const optsB = parseOpts(optsA)
const optsA = parseOpts({ opts, defaultOpts, forcedOpts })

const gulpTask = execCommand.bind(null, input, optsB)
const gulpTask = execCommand.bind(null, input, optsA)

// Log the command and arguments as the inner function name
renameFn(gulpTask, input)

return gulpTask
}

const defaultOpts = { verbose: isCi }
// The `echo` option is not needed since the function name shows it already
const FORCED_OPTS = { echo: false }
const forcedOpts = { echo: false }
7 changes: 7 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Like Lodash pickBy()
export const pickBy = function(object, condition) {
const pairs = Object.entries(object).filter(([key, value]) =>
condition(value, key),
)
return Object.fromEntries(pairs)
}

0 comments on commit cf7a221

Please sign in to comment.