Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: instrument --complete-copy implementation #1056

Merged
merged 6 commits into from Apr 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 13 additions & 9 deletions index.js
Expand Up @@ -3,9 +3,10 @@
/* global __coverage__ */

const cachingTransform = require('caching-transform')
const util = require('util')
const cpFile = require('cp-file')
const findCacheDir = require('find-cache-dir')
const fs = require('fs')
const glob = require('glob')
const Hash = require('./lib/hash')
const libCoverage = require('istanbul-lib-coverage')
const libHook = require('istanbul-lib-hook')
Expand All @@ -19,6 +20,7 @@ const resolveFrom = require('resolve-from')
const rimraf = require('rimraf')
const SourceMaps = require('./lib/source-maps')
const testExclude = require('test-exclude')
const util = require('util')
const uuid = require('uuid/v4')

const debugLog = util.debuglog('nyc')
Expand Down Expand Up @@ -156,7 +158,7 @@ NYC.prototype.addAllFiles = function () {
this._loadAdditionalModules()

this.fakeRequire = true
this.walkAllFiles(this.cwd, relFile => {
this.exclude.globSync(this.cwd).forEach(relFile => {
const filename = path.resolve(this.cwd, relFile)
this.addFile(filename)
const coverage = coverageFinder()
Expand Down Expand Up @@ -194,7 +196,15 @@ NYC.prototype.instrumentAllFiles = function (input, output, cb) {
const stats = fs.lstatSync(input)
if (stats.isDirectory()) {
inputDir = input
this.walkAllFiles(input, visitor)

const filesToInstrument = this.exclude.globSync(input)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instrumentAllFiles is getting to be a pretty large method. I'd be tempted to potentially move this logic into lib/instrument and split it into a couple helper methods.


if (this.config.completeCopy && output) {
const globOptions = { dot: true, nodir: true, ignore: ['**/.git', '**/.git/**', path.join(output, '**')] }
glob.sync(path.resolve(input, '**'), globOptions)
.forEach(src => cpFile.sync(src, path.join(output, path.relative(input, src))))
}
filesToInstrument.forEach(visitor)
} else {
visitor(input)
}
Expand All @@ -204,12 +214,6 @@ NYC.prototype.instrumentAllFiles = function (input, output, cb) {
cb()
}

NYC.prototype.walkAllFiles = function (dir, visitor) {
this.exclude.globSync(dir).forEach(relFile => {
visitor(relFile)
})
}

NYC.prototype._transform = function (code, filename) {
const extname = path.extname(filename).toLowerCase()
const transform = this.transforms[extname] || (() => null)
Expand Down
5 changes: 5 additions & 0 deletions lib/commands/instrument.js
Expand Up @@ -75,6 +75,11 @@ exports.builder = function (yargs) {
default: false,
type: 'boolean'
})
.option('complete-copy', {
describe: 'should nyc copy all files from input to output as well as instrumented files?',
default: false,
type: 'boolean'
})
.example('$0 instrument ./lib ./output', 'instrument all .js files in ./lib with coverage and output in ./output')
}

Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -69,9 +69,11 @@
"archy": "^1.0.0",
"caching-transform": "^3.0.2",
"convert-source-map": "^1.6.0",
"cp-file": "^6.2.0",
"find-cache-dir": "^2.1.0",
"find-up": "^3.0.0",
"foreground-child": "^1.5.6",
"glob": "^7.1.3",
"istanbul-lib-coverage": "^2.0.4",
"istanbul-lib-hook": "^2.0.5",
"istanbul-lib-instrument": "^3.1.2",
Expand All @@ -93,7 +95,6 @@
"any-path": "^1.3.0",
"chai": "^4.2.0",
"coveralls": "^3.0.3",
"glob": "^7.1.3",
"is-windows": "^1.0.2",
"lodash": "^4.17.11",
"newline-regex": "^0.2.1",
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/cli/.instrument-nycrc
@@ -1,5 +1,6 @@
{
"exclude": [
"**/exclude-me/**"
]
],
"complete-copy": true
}
50 changes: 42 additions & 8 deletions test/nyc-integration.js
Expand Up @@ -689,6 +689,31 @@ describe('the nyc cli', function () {
files.should.include('ignore.js')
files.should.not.include('package.json')
files.should.not.include('node_modules')
const includeTarget = path.resolve(fixturesCLI, 'output', 'ignore.js')
fs.readFileSync(includeTarget, 'utf8')
.should.match(/var cov_/)
done()
})
})

it('copies all files from <input> to <output> as well as those that have been instrumented', function (done) {
const args = [bin, 'instrument', '--complete-copy', './nyc-config-js', './output']

const proc = spawn(process.execPath, args, {
cwd: fixturesCLI,
env: env
})

proc.on('close', function (code) {
code.should.equal(0)
const files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.should.include('index.js')
files.should.include('ignore.js')
files.should.include('package.json')
files.should.include('node_modules')
const includeTarget = path.resolve(fixturesCLI, 'output', 'ignore.js')
fs.readFileSync(includeTarget, 'utf8')
.should.match(/var cov_/)
done()
})
})
Expand Down Expand Up @@ -738,19 +763,22 @@ describe('the nyc cli', function () {
code.should.equal(0)
const files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.length.should.not.equal(0)
files.should.not.include('exclude-me')
files.should.not.include('node_modules')
files.should.include('exclude-me')
files.should.include('node_modules')
files.should.include('index.js')
files.should.include('bad.js')
const includeTarget = path.resolve(fixturesCLI, 'output', 'index.js')
fs.readFileSync(includeTarget, 'utf8')
.should.match(/var cov_/)
const excludeTarget = path.resolve(fixturesCLI, 'output', 'exclude-me', 'index.js')
fs.readFileSync(excludeTarget, 'utf8')
.should.not.match(/var cov_/)
done()
})
})

it('allows a file to be excluded', function (done) {
const args = [bin, 'instrument', '--exclude', 'exclude-me/index.js', './subdir/input-dir', './output']
const args = [bin, 'instrument', '--complete-copy', '--exclude', 'exclude-me/index.js', './subdir/input-dir', './output']

const proc = spawn(process.execPath, args, {
cwd: fixturesCLI,
Expand All @@ -761,7 +789,10 @@ describe('the nyc cli', function () {
code.should.equal(0)
const files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.length.should.not.equal(0)
files.should.not.include('exclude-me')
files.should.include('exclude-me')
const excludeTarget = path.resolve(fixturesCLI, 'output', 'exclude-me', 'index.js')
fs.readFileSync(excludeTarget, 'utf8')
.should.not.match(/var cov_/)
done()
})
})
Expand All @@ -787,7 +818,7 @@ describe('the nyc cli', function () {
})

it('allows a file to be excluded from an included directory', function (done) {
const args = [bin, 'instrument', '--exclude', '**/exclude-me.js', '--include', '**/include-me/**', './subdir/input-dir', './output']
const args = [bin, 'instrument', '--complete-copy', '--exclude', '**/exclude-me.js', '--include', '**/include-me/**', './subdir/input-dir', './output']

const proc = spawn(process.execPath, args, {
cwd: fixturesCLI,
Expand All @@ -802,10 +833,13 @@ describe('the nyc cli', function () {
const includeMeFiles = fs.readdirSync(path.resolve(fixturesCLI, 'output', 'include-me'))
includeMeFiles.length.should.not.equal(0)
includeMeFiles.should.include('include-me.js')
includeMeFiles.should.not.include('exclude-me.js')
const instrumented = path.resolve(fixturesCLI, 'output', 'include-me', 'include-me.js')
fs.readFileSync(instrumented, 'utf8')
includeMeFiles.should.include('exclude-me.js')
const includeTarget = path.resolve(fixturesCLI, 'output', 'include-me', 'include-me.js')
fs.readFileSync(includeTarget, 'utf8')
.should.match(/var cov_/)
const excludeTarget = path.resolve(fixturesCLI, 'output', 'exclude-me', 'index.js')
fs.readFileSync(excludeTarget, 'utf8')
.should.not.match(/var cov_/)
done()
})
})
Expand Down