UNPKG

7.34 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const commander = require("commander");
4const log4js_1 = require("log4js");
5const core_1 = require("@stryker-mutator/api/core");
6const initializer_1 = require("./initializer");
7const LogConfigurator_1 = require("./logging/LogConfigurator");
8const Stryker_1 = require("./Stryker");
9const OptionsValidator_1 = require("./config/OptionsValidator");
10const errors_1 = require("./errors");
11/**
12 * Interpret a command line argument and add it to an object.
13 * @param object The object to assign the value to.
14 * @param key The property name under which the value needs to be stored.
15 */
16function deepOption(object, key) {
17 return (value) => {
18 object[key] = value;
19 return undefined;
20 };
21}
22function list(val) {
23 return val.split(',');
24}
25function parseBoolean(val) {
26 const v = val.toLocaleLowerCase();
27 return v !== 'false' && v !== '0';
28}
29class StrykerCli {
30 constructor(argv, program = new commander.Command(), runMutationTest = async (options) => new Stryker_1.default(options).runMutationTest(), log = log4js_1.getLogger(StrykerCli.name)) {
31 this.argv = argv;
32 this.program = program;
33 this.runMutationTest = runMutationTest;
34 this.log = log;
35 this.command = '';
36 this.strykerConfig = null;
37 }
38 run() {
39 const dashboard = {};
40 const defaultValues = OptionsValidator_1.defaultOptions();
41 this.program
42 .version(require('../package.json').version)
43 .usage('<command> [options] [configFile]')
44 .description(`Possible commands:
45 run: Run mutation testing
46 init: Initialize Stryker for your project
47
48 Optional location to a JSON or JavaScript config file as the last argument. If it's a JavaScript file, that file should export the config directly.`)
49 .arguments('<command> [configFile]')
50 .action((cmd, config) => {
51 this.command = cmd;
52 this.strykerConfig = config;
53 })
54 .option('-f, --files <allFiles>', `A comma separated list of globbing expression used for selecting all files needed to run the tests. For a more detailed way of selecting input files, please use a configFile.
55 Example: node_modules/a-lib/**/*.js,src/**/*.js,!src/index.js,a.js,test/**/*.js`, list)
56 .option('-m, --mutate <filesToMutate>', `A comma separated list of globbing expression used for selecting the files that should be mutated.
57 Example: src/**/*.js,a.js`, list)
58 .option('--coverageAnalysis <perTest|all|off>', `The coverage analysis strategy you want to use. Default value: "${defaultValues.coverageAnalysis}"`)
59 .option('--testFramework <name>', 'The name of the test framework you want to use.')
60 .option('--testRunner <name>', 'The name of the test runner you want to use')
61 .option('--mutator <name>', 'The name of the mutant generator you want to use')
62 .option('--transpilers <listOfTranspilers>', 'A comma separated list of transpilers to use.', list)
63 .option('--reporters <name>', 'A comma separated list of the names of the reporter(s) you want to use', list)
64 .option('--plugins <listOfPlugins>', 'A list of plugins you want stryker to load (`require`).', list)
65 .option('--timeoutMS <number>', 'Tweak the absolute timeout used to wait for a test runner to complete', parseInt)
66 .option('--timeoutFactor <number>', 'Tweak the standard deviation relative to the normal test run of a mutated test', parseFloat)
67 .option('--maxConcurrentTestRunners <n>', 'Set the number of max concurrent test runner to spawn (default: cpuCount)', parseInt)
68 .option('--logLevel <level>', `Set the log level for the console. Possible values: fatal, error, warn, info, debug, trace, all and off. Default is "${defaultValues.logLevel}"`)
69 .option('--fileLogLevel <level>', `Set the log4js log level for the "stryker.log" file. Possible values: fatal, error, warn, info, debug, trace, all and off. Default is "${defaultValues.fileLogLevel}"`)
70 .option('--allowConsoleColors <true/false>', 'Indicates whether or not Stryker should use colors in console.', parseBoolean)
71 .option('--dashboard.project <name>', 'Indicates which project name to use if the "dashboard" reporter is enabled. Defaults to the git url configured in the environment of your CI server.', deepOption(dashboard, 'project'))
72 .option('--dashboard.version <version>', 'Indicates which version to use if the "dashboard" reporter is enabled. Defaults to the branch name or tag name configured in the environment of your CI server.', deepOption(dashboard, 'version'))
73 .option('--dashboard.module <name>', 'Indicates which module name to use if the "dashboard" reporter is enabled.', deepOption(dashboard, 'module'))
74 .option('--dashboard.baseUrl <url>', `Indicates which baseUrl to use when reporting to the stryker dashboard. Default: "${defaultValues.dashboard.baseUrl}"`, deepOption(dashboard, 'baseUrl'))
75 .option(`--dashboard.reportType <${core_1.ALL_REPORT_TYPES.join('|')}>`, `Send a full report (inc. source code and mutant results) or only the mutation score. Default: ${defaultValues.dashboard.reportType}`, deepOption(dashboard, 'reportType'))
76 .option('--tempDirName <name>', 'Set the name of the directory that is used by Stryker as a working directory. This directory will be cleaned after a successful run')
77 .parse(this.argv);
78 // Earliest opportunity to configure the log level based on the logLevel argument
79 const options = this.program.opts();
80 LogConfigurator_1.default.configureMainProcess(options.logLevel);
81 // Cleanup commander state
82 delete options.version;
83 Object.keys(options)
84 .filter((key) => key.startsWith('dashboard.'))
85 .forEach((key) => delete options[key]);
86 if (this.strykerConfig) {
87 options.configFile = this.strykerConfig;
88 }
89 if (Object.keys(dashboard).length > 0) {
90 options.dashboard = dashboard;
91 }
92 const commands = {
93 init: () => initializer_1.initializerFactory().initialize(),
94 run: () => this.runMutationTest(options),
95 };
96 if (Object.keys(commands).includes(this.command)) {
97 commands[this.command]().catch((err) => {
98 const error = errors_1.retrieveCause(err);
99 if (error instanceof errors_1.ConfigError) {
100 this.log.error(error.message);
101 }
102 else {
103 this.log.error('an error occurred', err);
104 if (!this.log.isTraceEnabled()) {
105 this.log.info('Trouble figuring out what went wrong? Try `npx stryker run --fileLogLevel trace --logLevel debug` to get some more info.');
106 }
107 }
108 process.exitCode = 1;
109 });
110 }
111 else {
112 this.log.error('Unknown command: "%s", supported commands: [%s], or use `stryker --help`.', this.command, Object.keys(commands));
113 }
114 }
115}
116exports.default = StrykerCli;
117//# sourceMappingURL=StrykerCli.js.map
\No newline at end of file