Skip to content

Commit

Permalink
chore: Use @istanbuljs/load-nyc-config (#1192)
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyfarrell committed Oct 7, 2019
1 parent 04334e2 commit 408c1cb
Show file tree
Hide file tree
Showing 19 changed files with 161 additions and 136 deletions.
14 changes: 3 additions & 11 deletions bin/nyc.js
Expand Up @@ -4,7 +4,6 @@
const configUtil = require('../lib/config-util')
const foreground = require('foreground-child')
const NYC = require('../index.js')
const processArgs = require('../lib/process-args')

const sw = require('spawn-wrap')
const wrapper = require.resolve('./wrap.js')
Expand All @@ -13,13 +12,10 @@ const wrapper = require.resolve('./wrap.js')
// we keep these values in a few different forms,
// used in the various execution contexts of nyc:
// reporting, instrumenting subprocesses, etc.
const yargs = configUtil.buildYargs()
const instrumenterArgs = processArgs.hideInstrumenteeArgs()
const config = configUtil.loadConfig(yargs.parse(instrumenterArgs))
configUtil.addCommandsAndHelp(yargs)
const argv = yargs.config(config).parse(instrumenterArgs)

async function main () {
const { argv, childArgs, yargs } = await configUtil()

if (['check-coverage', 'report', 'instrument', 'merge'].includes(argv._[0])) {
// look in lib/commands for logic.
return
Expand Down Expand Up @@ -68,11 +64,7 @@ async function main () {
// set process.exitCode. Keep track so that both children are run, but
// a non-zero exit codes in either one leads to an overall non-zero exit code.
process.exitCode = 0
foreground(processArgs.hideInstrumenterArgs(
// use the same argv description, but don't exit
// for flags like --help.
configUtil.buildYargs().parse(process.argv.slice(2))
), async () => {
foreground(childArgs, async () => {
var mainChildExitCode = process.exitCode

await nyc.writeProcessIndex()
Expand Down
13 changes: 3 additions & 10 deletions index.js
Expand Up @@ -492,23 +492,16 @@ class NYC {
eachReport (filenames, iterator, baseDirectory) {
baseDirectory = baseDirectory || this.tempDirectory()

if (typeof filenames === 'function') {
iterator = filenames
filenames = undefined
}

var _this = this
var files = filenames || fs.readdirSync(baseDirectory)

files.forEach(function (f) {
const files = filenames || fs.readdirSync(baseDirectory)
files.forEach(f => {
var report
try {
report = JSON.parse(fs.readFileSync(
path.resolve(baseDirectory, f),
'utf-8'
))

_this.sourceMaps.reloadCachedSourceMapsSync(report)
this.sourceMaps.reloadCachedSourceMapsSync(report)
} catch (e) { // handle corrupt JSON output.
report = {}
}
Expand Down
85 changes: 29 additions & 56 deletions lib/config-util.js
@@ -1,61 +1,26 @@
'use strict'

const fs = require('fs')
const path = require('path')
const findUp = require('find-up')
const testExclude = require('test-exclude')
const Yargs = require('yargs/yargs')

var Config = {}
const processArgs = require('./process-args')
const { loadNycConfig } = require('@istanbuljs/load-nyc-config')

function guessCWD (cwd) {
async function guessCWD (cwd) {
cwd = cwd || process.env.NYC_CWD || process.cwd()
const pkgPath = findUp.sync('package.json', { cwd: cwd })
const pkgPath = await findUp('package.json', { cwd })
if (pkgPath) {
cwd = path.dirname(pkgPath)
}
return cwd
}

Config.loadConfig = function (argv, cwd) {
const rcOptions = [
argv.nycrcPath || '.nycrc',
'.nycrc.json',
'.nycrc.yml',
'.nycrc.yaml',
'nyc.config.js'
]
const rcPath = findUp.sync(rcOptions, { cwd: guessCWD(cwd) })
let config = {}

if (rcPath) {
const rcExt = path.extname(rcPath.toLowerCase())
if (rcExt === '.js') {
config = require(rcPath)
} else if (rcExt === '.yml' || rcExt === '.yaml') {
config = require('js-yaml').load(
fs.readFileSync(rcPath, 'utf8')
)
} else {
config = JSON.parse(
fs.readFileSync(rcPath, 'utf-8')
)
}
}

if (config.require) config.require = [].concat(config.require)
if (config.extension) config.extension = [].concat(config.extension)
if (config.exclude) config.exclude = [].concat(config.exclude)
if (config.include) config.include = [].concat(config.include)

return config
return cwd
}

// build a yargs object, omitting any settings
// that would cause the application to exit early.
Config.buildYargs = function (cwd) {
cwd = guessCWD(cwd)
return Yargs([])
async function processConfig (cwd) {
cwd = await guessCWD(cwd)
const yargs = Yargs([])
.usage('$0 [command] [options]')
.usage('$0 [options] [bin-to-instrument]')
.option('reporter', {
Expand Down Expand Up @@ -243,7 +208,6 @@ Config.buildYargs = function (cwd) {
global: false
})
.option('nycrc-path', {
default: '.nycrc',
description: 'specify a different .nycrc path',
global: false
})
Expand All @@ -269,7 +233,6 @@ Config.buildYargs = function (cwd) {
type: 'boolean',
global: false
})
.pkgConf('nyc', cwd)
.example('$0 npm test', 'instrument your tests with coverage')
.example('$0 --require @babel/register npm test', 'instrument your tests with coverage and transpile with Babel')
.example('$0 report --reporter=text-lcov', 'output lcov report after running your tests')
Expand All @@ -278,20 +241,30 @@ Config.buildYargs = function (cwd) {
.boolean('version')
.help(false)
.version(false)
}

// we add operations that would make yargs
// exit post-hoc, allowing for a multi-pass
// parsing step.
Config.addCommandsAndHelp = function (yargs) {
return yargs
const instrumenterArgs = processArgs.hideInstrumenteeArgs()

// This yargs.parse must come before any options that exit post-hoc
const childArgs = processArgs.hideInstrumenterArgs(yargs.parse(process.argv.slice(2)))
const config = await loadNycConfig(yargs.parse(instrumenterArgs))

yargs
.config(config)
.help('h')
.alias('h', 'help')
.version()
.command(require('../lib/commands/check-coverage'))
.command(require('../lib/commands/instrument'))
.command(require('../lib/commands/report'))
.command(require('../lib/commands/merge'))
.command(require('./commands/check-coverage'))
.command(require('./commands/instrument'))
.command(require('./commands/report'))
.command(require('./commands/merge'))

return {
get argv () {
return yargs.parse(instrumenterArgs)
},
childArgs,
yargs
}
}

module.exports = Config
module.exports = processConfig
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -68,6 +68,7 @@
"author": "Ben Coe <ben@npmjs.com>",
"license": "ISC",
"dependencies": {
"@istanbuljs/load-nyc-config": "^1.0.0-alpha.0",
"caching-transform": "^4.0.0",
"convert-source-map": "^1.6.0",
"cp-file": "^7.0.0",
Expand Down
39 changes: 39 additions & 0 deletions tap-snapshots/test-nyc-integration.js-TAP.test.js
Expand Up @@ -16,6 +16,21 @@ All files | 44.44 | 100 | 33.33 | 44.44 |
`

exports[`test/nyc-integration.js TAP --all instruments unknown extensions as js > stdout 1`] = `
run
------------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------------|---------|----------|---------|---------|-------------------
All files | 11.11 | 100 | 0 | 11.11 |
check-instrumented.es6 | 0 | 100 | 0 | 0 | 5,6
check-instrumented.js | 0 | 100 | 0 | 0 | 5,6
not-loaded.es6 | 0 | 100 | 100 | 0 | 1,2
not-loaded.js | 0 | 100 | 100 | 0 | 1,2
run.js | 100 | 100 | 100 | 100 |
------------------------|---------|----------|---------|---------|-------------------
`

exports[`test/nyc-integration.js TAP --all uses source-maps to exclude original sources from reports > stdout 1`] = `
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
Expand Down Expand Up @@ -838,6 +853,30 @@ exports[`test/nyc-integration.js TAP passes configuration via environment variab
]
`

exports[`test/nyc-integration.js TAP produce-source-map enabled > stdout 1`] = `
Error: Blarrh
at blah (./stack-trace.js:3:1)
----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
stack-trace.js | 100 | 100 | 100 | 100 |
----------------|---------|----------|---------|---------|-------------------
`

exports[`test/nyc-integration.js TAP produce-source-map not enabled > stdout 1`] = `
Error: Blarrh
at blah (./stack-trace.js:1:1037)
----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
stack-trace.js | 100 | 100 | 100 | 100 |
----------------|---------|----------|---------|---------|-------------------
`

exports[`test/nyc-integration.js TAP recursive run does not throw > stdout 1`] = `
`
Expand Down
15 changes: 7 additions & 8 deletions test/add-all-files.js
Expand Up @@ -7,17 +7,16 @@ const t = require('tap')
const ap = require('any-path')

const NYC = require('../self-coverage')
const configUtil = require('../self-coverage/lib/config-util')

const resetState = require('./helpers/reset-state')
const { parseArgv, resetState } = require('./helpers')

const fixtures = path.resolve(__dirname, 'fixtures')
const transpileHook = path.resolve(__dirname, 'fixtures/transpile-hook')

t.beforeEach(resetState)

t.test('outputs an empty coverage report for all files that are not excluded', async t => {
const nyc = new NYC(configUtil.buildYargs(fixtures).parse())
const nyc = new NYC(await parseArgv(fixtures))
await nyc.reset()
await nyc.addAllFiles()

Expand All @@ -32,7 +31,7 @@ t.test('outputs an empty coverage report for all files that are not excluded', a

t.test('outputs an empty coverage report for multiple configured extensions', async t => {
const cwd = path.resolve(fixtures, './conf-multiple-extensions')
const nyc = new NYC(configUtil.buildYargs(cwd).parse())
const nyc = new NYC(await parseArgv(cwd))
await nyc.reset()
await nyc.addAllFiles()

Expand Down Expand Up @@ -61,7 +60,7 @@ t.test('transpiles .js files added via addAllFiles', async t => {
'utf-8'
)

const nyc = new NYC(configUtil.buildYargs(fixtures).parse(['--require', transpileHook]))
const nyc = new NYC(await parseArgv(fixtures, ['--require', transpileHook]))
await nyc.reset()
await nyc.addAllFiles()

Expand All @@ -83,7 +82,7 @@ t.test('does not attempt to transpile files when they are excluded', async t =>
'utf-8'
)

const nyc = new NYC(configUtil.buildYargs(fixtures).parse([
const nyc = new NYC(await parseArgv(fixtures, [
`--require=${transpileHook}`,
'--extension=.do-not-transpile',
'--include=needs-transpile.do-not-transpile'
Expand All @@ -103,10 +102,10 @@ t.test('transpiles non-.js files added via addAllFiles', async t => {
'utf-8'
)

const nyc = (new NYC(configUtil.buildYargs(fixtures).parse([
const nyc = new NYC(await parseArgv(fixtures, [
`--require=${transpileHook}`,
'--extension=.whatever'
])))
]))

await nyc.reset()
await nyc.addAllFiles()
Expand Down
5 changes: 2 additions & 3 deletions test/cache.js
Expand Up @@ -7,16 +7,15 @@ const t = require('tap')
const rimraf = promisify(require('rimraf'))

const NYC = require('../self-coverage')
const configUtil = require('../self-coverage/lib/config-util')

const { resetState, runNYC } = require('./helpers')
const { parseArgv, resetState, runNYC } = require('./helpers')

const fixtures = path.resolve(__dirname, './fixtures')

t.beforeEach(resetState)

async function cacheTest (t, script) {
const nyc = new NYC(configUtil.buildYargs(fixtures).parse())
const nyc = new NYC(await parseArgv(fixtures))
await rimraf(nyc.cacheDirectory)

const { status } = await runNYC({
Expand Down
11 changes: 6 additions & 5 deletions test/config.js
Expand Up @@ -5,22 +5,23 @@ const path = require('path')
const { test } = require('tap')

const NYC = require('../self-coverage')
const configUtil = require('../self-coverage/lib/config-util')

const { parseArgv } = require('./helpers')

test("loads 'exclude' patterns from package.json#nyc", async t => {
const nyc = new NYC(configUtil.buildYargs(path.resolve(__dirname, './fixtures')).parse())
const nyc = new NYC(await parseArgv(path.resolve(__dirname, './fixtures')))

t.strictEqual(nyc.exclude.exclude.length, 8)
})

test("loads 'extension' patterns from package.json#nyc", async t => {
const nyc = new NYC(configUtil.buildYargs(path.resolve(__dirname, './fixtures/conf-multiple-extensions')).parse())
const nyc = new NYC(await parseArgv(path.resolve(__dirname, './fixtures/conf-multiple-extensions')))

t.strictEqual(nyc.extensions.length, 3)
})

test("ignores 'include' option if it's falsy or []", async t => {
const nyc1 = new NYC(configUtil.buildYargs(path.resolve(__dirname, './fixtures/conf-empty')).parse())
const nyc1 = new NYC(await parseArgv(path.resolve(__dirname, './fixtures/conf-empty')))

t.strictEqual(nyc1.exclude.include, false)

Expand All @@ -32,7 +33,7 @@ test("ignores 'include' option if it's falsy or []", async t => {
})

test("ignores 'exclude' option if it's falsy", async t => {
const nyc = new NYC(configUtil.buildYargs(path.resolve(__dirname, './fixtures/conf-empty')).parse())
const nyc = new NYC(await parseArgv(path.resolve(__dirname, './fixtures/conf-empty')))

t.strictEqual(nyc.exclude.exclude.length, 15)
})
Expand Down

0 comments on commit 408c1cb

Please sign in to comment.