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: add delete option to instrument command #1005

Merged
merged 13 commits into from Mar 12, 2019
Merged
17 changes: 17 additions & 0 deletions lib/commands/instrument.js
@@ -1,4 +1,6 @@
const NYC = require('../../index.js')
const path = require('path')
const rimraf = require('rimraf')

exports.command = 'instrument <input> [output]'

Expand Down Expand Up @@ -51,6 +53,11 @@ exports.builder = function (yargs) {
type: 'boolean',
description: 'tell the instrumenter to treat files as ES Modules'
})
.option('delete', {
describe: 'should the output folder be deleted before instrumenting files?',
default: false,
type: 'boolean'
})
.example('$0 instrument ./lib ./output', 'instrument all .js files in ./lib with coverage and output in ./output')
}

Expand All @@ -72,6 +79,16 @@ exports.handler = function (argv) {
exitOnError: argv.exitOnError
})

if (argv.delete && argv.output && argv.output.length !== 0) {
const relPath = path.relative(process.cwd(), path.resolve(argv.output))
if (relPath !== '' && !relPath.startsWith('..')) {
rimraf.sync(argv.output)
} else {
console.error(`nyc instrument failed: attempt to delete '${process.cwd()}'`)
process.exit(1)
}
}

nyc.instrumentAllFiles(argv.input, argv.output, function (err) {
if (err) {
console.error(err.message)
Expand Down
90 changes: 87 additions & 3 deletions test/nyc-integration.js
Expand Up @@ -11,6 +11,7 @@ const fs = require('fs')
const glob = require('glob')
const isWindows = require('is-windows')()
const rimraf = require('rimraf')
const makeDir = require('make-dir')
const spawn = require('child_process').spawn
const si = require('strip-indent')

Expand Down Expand Up @@ -622,6 +623,10 @@ describe('the nyc cli', function () {
})

describe('output folder specified', function () {
afterEach(function () {
rimraf.sync(path.resolve(fixturesCLI, 'output'))
})

it('allows a single file to be instrumented', function (done) {
var args = [bin, 'instrument', './half-covered.js', './output']

Expand All @@ -635,7 +640,6 @@ describe('the nyc cli', function () {
var files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.length.should.equal(1)
files.should.include('half-covered.js')
rimraf.sync(path.resolve(fixturesCLI, 'output'))
done()
})
})
Expand All @@ -653,7 +657,6 @@ describe('the nyc cli', function () {
var files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.should.include('env.js')
files.should.include('es6.js')
rimraf.sync(path.resolve(fixturesCLI, 'output'))
done()
})
})
Expand All @@ -670,7 +673,6 @@ describe('the nyc cli', function () {
code.should.equal(0)
var files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.should.include('index.js')
rimraf.sync(path.resolve(fixturesCLI, 'output'))
done()
})
})
Expand Down Expand Up @@ -721,6 +723,88 @@ describe('the nyc cli', function () {
})
})
})

describe('delete', function () {
beforeEach(function () {
makeDir.sync(path.resolve(fixturesCLI, 'output', 'removed-by-clean'))
})

it('cleans the output directory if `--delete` is specified', function (done) {
const args = [bin, 'instrument', '--delete', 'true', './', './output']

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

proc.on('close', function (code) {
code.should.equal(0)
const subdirExists = fs.existsSync(path.resolve(fixturesCLI, './output/subdir/input-dir'))
subdirExists.should.equal(true)
const files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.should.not.include('removed-by-clean')
done()
})
})

it('does not clean the output directory by default', function (done) {
const args = [bin, 'instrument', './', './output']

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

proc.on('close', function (code) {
code.should.equal(0)
const subdirExists = fs.existsSync(path.resolve(fixturesCLI, './output/subdir/input-dir'))
subdirExists.should.equal(true)
const files = fs.readdirSync(path.resolve(fixturesCLI, './output'))
files.should.include('removed-by-clean')
done()
})
})

it('aborts if trying to clean process.cwd()', function (done) {
const args = [bin, 'instrument', '--delete', './', './']

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

let stderr = ''
proc.stderr.on('data', function (chunk) {
stderr += chunk
})

proc.on('close', function (code) {
code.should.equal(1)
stderr.should.include('nyc instrument failed: attempt to delete')
done()
})
})

it('aborts if trying to clean outside working directory', function (done) {
const args = [bin, 'instrument', '--delete', './', '../']

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

let stderr = ''
proc.stderr.on('data', function (chunk) {
stderr += chunk
})

proc.on('close', function (code) {
code.should.equal(1)
stderr.should.include('nyc instrument failed: attempt to delete')
done()
})
})
})
})
})

Expand Down