Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat: instrument --complete-copy implementation (#1056)
With a few caveats:
* This will dereference symlinks as it copies them, in some cases this could be a problem i.e. `node_modules/.bin`
* This will not copy across empty directories
  • Loading branch information
AndrewFinlay authored and coreyfarrell committed Apr 9, 2019
1 parent c88a852 commit 2eb13c6
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 19 deletions.
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 @@ -155,7 +157,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 @@ -193,7 +195,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)

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 @@ -203,12 +213,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

0 comments on commit 2eb13c6

Please sign in to comment.