UNPKG

4.39 kBJavaScriptView Raw
1/**
2 * Command line implementation for JSCS.
3 *
4 * See documentation on exit codes in - https://github.com/jscs-dev/node-jscs/wiki/Exit-codes
5 *
6 * Common usage case is:
7 *
8 * ./node_modules/.bin/jscs file1 dir1 file2 dir2
9 */
10
11var Vow = require('vow');
12var exit = require('exit');
13
14var Checker = require('./checker');
15var configFile = require('./cli-config');
16var ConfigGenerator = require('./config/generator');
17
18module.exports = function cli(program) {
19 var reporter;
20 var config;
21 var checkerPromise;
22 var defer = Vow.defer();
23 var promise = defer.promise();
24 var checker = new Checker();
25 var args = program.args;
26 var returnArgs = {
27 checker: checker,
28 reporter: program.reporter,
29 promise: promise
30 };
31
32 function handleMaxErrors() {
33 if (checker.maxErrorsExceeded()) {
34 console.error('Too many errors... Increase `maxErrors` configuration option value to see more.');
35 }
36 }
37
38 promise.always(function(status) {
39 exit(status.valueOf());
40 });
41
42 try {
43 config = configFile.load(program.config);
44 } catch (e) {
45 console.error('Config source is corrupted -', e.toString());
46 defer.reject(5);
47
48 return returnArgs;
49 }
50
51 /**
52 * Trying to load config.
53 * Custom config path can be specified using '-c' option.
54 */
55 if (!config && !program.preset && !program.autoConfigure) {
56 if (program.config) {
57 console.error('Configuration source', program.config, 'was not found.');
58 } else {
59 console.error('No configuration found. Add a .jscsrc file to your project root or use the -c option.');
60 }
61
62 defer.reject(4);
63
64 return returnArgs;
65 }
66
67 if (!args.length && process.stdin.isTTY && typeof program.autoConfigure !== 'string') {
68 console.error('No input files specified. Try option --help for usage information.');
69 defer.reject(3);
70
71 return returnArgs;
72 }
73
74 reporter = configFile.getReporter(program.reporter, program.colors);
75
76 returnArgs.reporter = reporter.path;
77
78 if (!reporter.writer) {
79 console.error('Reporter "%s" does not exist.', program.reporter);
80 returnArgs.reporter = reporter.path;
81 defer.reject(6);
82
83 return returnArgs;
84 }
85
86 if (!config) {
87 config = {};
88 }
89
90 // To run autoconfigure over all errors in the path
91 if (program.autoConfigure) {
92 program.maxErrors = Infinity;
93 }
94
95 checker.getConfiguration().overrideFromCLI(program);
96 checker.getConfiguration().registerDefaultRules();
97
98 try {
99 checker.configure(config);
100 } catch (e) {
101 console.error(e.message);
102 defer.reject(1);
103
104 return returnArgs;
105 }
106 if (program.autoConfigure) {
107 var generator = new ConfigGenerator();
108
109 generator
110 .generate(program.autoConfigure)
111 .then(function() {
112 defer.resolve(0);
113 }, function(error) {
114 console.error('Configuration generation failed due to ', error);
115 defer.reject(7);
116 });
117
118 return returnArgs;
119 }
120
121 // Handle usage like 'cat myfile.js | jscs' or 'jscs -''
122 var usedDash = args[args.length - 1] === '-';
123 if (!args.length || usedDash) {
124 // So the dash doesn't register as a file
125 if (usedDash) { args.length--; }
126
127 if (program.fix) {
128 return {
129 promise: checker.fixStdin().then(function(result) {
130 process.stdout.write(result.output);
131 }),
132 checker: checker
133 };
134 }
135
136 checkerPromise = checker.checkStdin().then(function(errors) {
137 return [errors];
138 });
139 }
140
141 // Processing specified files and dirs.
142 if (args.length) {
143 checkerPromise = Vow.all(args.map(checker.execute, checker)).then(function(results) {
144 return [].concat.apply([], results);
145 });
146 }
147
148 checkerPromise.then(function(errorsCollection) {
149 reporter.writer(errorsCollection);
150 handleMaxErrors();
151
152 errorsCollection.forEach(function(errors) {
153 if (!errors.isEmpty()) {
154 defer.reject(2);
155 }
156 });
157
158 defer.resolve(0);
159 }).fail(function(e) {
160 console.error(e.stack);
161 defer.reject(1);
162 });
163
164 return returnArgs;
165};