coffee-coverage
Version:
Istanbul and JSCoverage-style instrumentation for CoffeeScript files.
155 lines (141 loc) • 5.92 kB
JavaScript
// Generated by CoffeeScript 2.3.2
(function() {
//!/usr/bin/env coffee
// Implements functionality for the CLI command
var CoverageInstrumentor, DEFAULT_INSTRUMENTOR, INSTRUMENTORS, _, executableName, fs, mkdirs, parseArgs, path, stripLeadingDotOrSlash, version;
fs = require('fs');
path = require('path');
_ = require('lodash');
({CoverageInstrumentor, version} = require('./index'));
({INSTRUMENTORS} = require('./coffeeCoverage'));
({stripLeadingDotOrSlash, mkdirs} = require('./utils/helpers'));
DEFAULT_INSTRUMENTOR = 'jscoverage';
executableName = path.basename(process.argv[1]);
parseArgs = function(args) {
var ArgumentParser, coverageVarDefault, excludeDefault, options, parser;
ArgumentParser = require('argparse').ArgumentParser;
parser = new ArgumentParser({
version: version,
addHelp: true,
description: "Compiles CoffeeScript into JavaScript with JSCoverage-compatible instrumentation for code coverage."
});
parser.addArgument(['--verbose'], {
help: "Verbose output",
nargs: 0
});
parser.addArgument(['-b', '--bare'], {
help: "compile without a top-level function wrapper",
metavar: "bare",
nargs: 0
});
coverageVarDefault = '_$jscoverage';
parser.addArgument(['-c', '--coverageVar'], {
help: `Set the name to use in the instrumented code for the coverage variable. Defaults to\n'${coverageVarDefault}'.`,
metavar: "name",
defaultValue: coverageVarDefault
});
parser.addArgument(['-t', '--inst'], {
help: `Set the type of instrumentation to generate. Valid options are:\n${Object.keys(INSTRUMENTORS).map(function(t) {
if (t === DEFAULT_INSTRUMENTOR) {
return `${t} (default)`;
} else {
return t;
}
}).join(', ')}`,
metavar: "type",
defaultValue: DEFAULT_INSTRUMENTOR
});
excludeDefault = "node_modules,.git";
parser.addArgument(['-e', '--exclude'], {
help: `Comma delimited set of file names to exclude. Any file or directory which is in\nthis list will be ignored. Note that this field is case sensitive. Defaults to\n'${excludeDefault}'.`,
metavar: "filenames",
defaultValue: excludeDefault
});
parser.addArgument(['-i', '--initfile'], {
help: "Write all global initialization out to 'file'.",
metavar: "file"
});
parser.addArgument(['--path'], {
help: "Specify how to show the path for each filename in the instrumented output. If\n'pathtype' is 'relative', then the relative path will be written to each file. If\n'pathtype' is 'abbr', then we replace each directory in the path with its first letter.\nThe default is 'none' which will write only the filename with no path.",
metavar: "pathtype",
choices: ['none', 'abbr', 'relative'],
defaultValue: "none"
});
parser.addArgument(['--basePath'], {
help: "Specify the basePath for your project.",
metavar: "basePath"
});
parser.addArgument(["src"], {
help: "A file or directory to instrument. If this is a directory, then all .coffee " + "files in this directory and all subdirectories will be instrumented."
});
parser.addArgument(["dest"], {
help: "If src is a file then this must be a file to write the compiled JS code to. " + "If src is a directory, then this must be a directory. This file or directory " + "will be created if it does not exist."
});
options = parser.parseArgs(args);
if (!options.inst in INSTRUMENTORS) {
parser.printUsage();
console.error(`${executableName}: error: Invalid coverage type ${options.inst}.\nMust be one of ${Object.keys(INSTRUMENTORS).join(', ')}`);
process.exit(1);
}
// Split exclude into an array.
if (options.exclude) {
options.exclude = options.exclude.split(",");
} else {
options.exclude = [];
}
return options;
};
exports.main = function(args) {
var coverageInstrumentor, err, options, ref, result;
try {
options = parseArgs(args.slice(2));
if (options.bare) {
options.bare = true;
}
coverageInstrumentor = new CoverageInstrumentor({
bare: options.bare,
instrumentor: options.inst
});
if (options.verbose) {
coverageInstrumentor.on("instrumentingDirectory", function(sourceDir, outDir) {
return console.log(`Instrumenting directory: ${stripLeadingDotOrSlash(sourceDir)} to ${stripLeadingDotOrSlash(outDir)}`);
});
coverageInstrumentor.on("instrumentingFile", function(sourceFile, outFile) {
return console.log(` ${stripLeadingDotOrSlash(sourceFile)} to ${stripLeadingDotOrSlash(outFile)}`);
});
coverageInstrumentor.on("skip", function(file) {
return console.log(` Skipping: ${stripLeadingDotOrSlash(file)}`);
});
}
// Change initFile into a output stream
if (options.initfile) {
mkdirs(path.dirname(options.initfile));
options.initFileStream = fs.createWriteStream(options.initfile);
}
if (options.basePath == null) {
options.basePath = process.cwd();
}
options.basePath = path.resolve(options.basePath);
result = coverageInstrumentor.instrument(options.src, options.dest, options);
if ((ref = options.initFileStream) != null) {
ref.end();
}
if (!result) {
return console.error(`${options.src} does not exist.`);
} else {
return console.log(`Instrumented ${result.lines} lines.`);
}
} catch (error) {
err = error;
if (err.constructor.name === "CoverageError") {
console.error(`Error: ${err.message}`);
return process.exit(1);
} else {
throw err;
}
}
};
if (require.main === module) {
exports.main(process.argv);
}
}).call(this);