1 | (function() {
|
2 | |
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | var Cache, CoffeeScript, coffeelint, config, configfinder, coreReporters, data, deprecatedReporter, errorReport, findCoffeeScripts, fs, getAllExtention, getFallbackConfig, glob, ignore, jsonIndentation, lintFiles, lintSource, loadConfig, log, logConfig, optimist, options, os, path, paths, read, readConfigFile, ref, reportAndExit, resolve, ruleLoader, scripts, stdin, stripComments, thisdir, userConfig;
|
9 |
|
10 | resolve = require('resolve').sync;
|
11 |
|
12 | path = require('path');
|
13 |
|
14 | fs = require('fs');
|
15 |
|
16 | os = require('os');
|
17 |
|
18 | glob = require('glob');
|
19 |
|
20 | optimist = require('optimist');
|
21 |
|
22 | ignore = require('ignore');
|
23 |
|
24 | stripComments = require('strip-json-comments');
|
25 |
|
26 | thisdir = path.dirname(fs.realpathSync(__filename));
|
27 |
|
28 | coffeelint = require(path.join(thisdir, 'coffeelint'));
|
29 |
|
30 | configfinder = require(path.join(thisdir, 'configfinder'));
|
31 |
|
32 | ruleLoader = require(path.join(thisdir, 'ruleLoader'));
|
33 |
|
34 | Cache = require(path.join(thisdir, 'cache'));
|
35 |
|
36 | CoffeeScript = require('coffeescript');
|
37 |
|
38 | CoffeeScript.register();
|
39 |
|
40 | log = function() {
|
41 |
|
42 | return console.log(...arguments);
|
43 | };
|
44 |
|
45 |
|
46 | jsonIndentation = 2;
|
47 |
|
48 | logConfig = function(config) {
|
49 | var filter;
|
50 | filter = function(k, v) {
|
51 | if (k !== 'message' && k !== 'description' && k !== 'name') {
|
52 | return v;
|
53 | }
|
54 | };
|
55 | return log(JSON.stringify(config, filter, jsonIndentation));
|
56 | };
|
57 |
|
58 |
|
59 | read = function(path) {
|
60 | var realPath;
|
61 | realPath = fs.realpathSync(path);
|
62 | return fs.readFileSync(realPath).toString();
|
63 | };
|
64 |
|
65 |
|
66 | getAllExtention = function(extension) {
|
67 | if (extension != null) {
|
68 | extension = ['coffee'].concat(extension != null ? extension.split(',') : void 0);
|
69 | return `@(${extension.join('|')})`;
|
70 | } else {
|
71 | return 'coffee';
|
72 | }
|
73 | };
|
74 |
|
75 |
|
76 | findCoffeeScripts = function(paths, extension) {
|
77 | var allExtention, files, i, len, p;
|
78 | files = [];
|
79 | allExtention = getAllExtention(extension);
|
80 | for (i = 0, len = paths.length; i < len; i++) {
|
81 | p = paths[i];
|
82 | if (fs.statSync(p).isDirectory()) {
|
83 |
|
84 | files = files.concat(glob.sync(`${p}/**/*.${allExtention}`));
|
85 | } else {
|
86 | files.push(p);
|
87 | }
|
88 | }
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | return files.map(function(p) {
|
95 | return path.join(p);
|
96 | });
|
97 | };
|
98 |
|
99 |
|
100 | lintFiles = function(files, config) {
|
101 | var errorReport, file, fileConfig, i, len, literate, source;
|
102 | errorReport = new coffeelint.getErrorReport();
|
103 | for (i = 0, len = files.length; i < len; i++) {
|
104 | file = files[i];
|
105 | source = read(file);
|
106 | literate = CoffeeScript.helpers.isLiterate(file);
|
107 | fileConfig = config ? config : getFallbackConfig(file);
|
108 | errorReport.lint(file, source, fileConfig, literate);
|
109 | }
|
110 | return errorReport;
|
111 | };
|
112 |
|
113 |
|
114 | lintSource = function(source, config, literate = false) {
|
115 | var errorReport;
|
116 | errorReport = new coffeelint.getErrorReport();
|
117 | config || (config = getFallbackConfig());
|
118 | errorReport.lint('stdin', source, config, literate);
|
119 | return errorReport;
|
120 | };
|
121 |
|
122 |
|
123 | readConfigFile = function(path) {
|
124 | var text;
|
125 | text = read(path);
|
126 | try {
|
127 | jsonIndentation = text.split('\n')[1].match(/^\s+/)[0].length;
|
128 | } catch (error) {}
|
129 | return JSON.parse(stripComments(text));
|
130 | };
|
131 |
|
132 | loadConfig = function(options) {
|
133 | var config;
|
134 | config = null;
|
135 | if (!options.argv.noconfig) {
|
136 | if (options.argv.f) {
|
137 | config = readConfigFile(options.argv.f);
|
138 |
|
139 | if (config.coffeelintConfig) {
|
140 | config = config.coffeelintConfig;
|
141 | }
|
142 | }
|
143 | }
|
144 | return config;
|
145 | };
|
146 |
|
147 |
|
148 |
|
149 |
|
150 | getFallbackConfig = function(filename = null) {
|
151 | if (!options.argv.noconfig) {
|
152 | return configfinder.getConfig(filename);
|
153 | }
|
154 | };
|
155 |
|
156 |
|
157 |
|
158 | deprecatedReporter = function(errorReport, reporter) {
|
159 | var base;
|
160 | if ((base = errorReport.paths)['coffeelint_fake_file.coffee'] == null) {
|
161 | base['coffeelint_fake_file.coffee'] = [];
|
162 | }
|
163 | errorReport.paths['coffeelint_fake_file.coffee'].push({
|
164 | 'level': 'warn',
|
165 | 'rule': 'commandline',
|
166 | 'message': `parameter --${reporter} is deprecated. Use --reporter ${reporter} instead`,
|
167 | 'lineNumber': 0
|
168 | });
|
169 | return reporter;
|
170 | };
|
171 |
|
172 | coreReporters = {
|
173 | default: require(path.join(thisdir, 'reporters', 'default')),
|
174 | csv: require(path.join(thisdir, 'reporters', 'csv')),
|
175 | jslint: require(path.join(thisdir, 'reporters', 'jslint')),
|
176 | checkstyle: require(path.join(thisdir, 'reporters', 'checkstyle')),
|
177 | raw: require(path.join(thisdir, 'reporters', 'raw'))
|
178 | };
|
179 |
|
180 |
|
181 | reportAndExit = function(errorReport, options) {
|
182 | var SelectedReporter, base, colorize, ref, reporter, strReporter;
|
183 | strReporter = options.argv.jslint ? deprecatedReporter(errorReport, 'jslint') : options.argv.csv ? deprecatedReporter(errorReport, 'csv') : options.argv.checkstyle ? deprecatedReporter(errorReport, 'checkstyle') : options.argv.reporter;
|
184 | if (strReporter == null) {
|
185 | strReporter = 'default';
|
186 | }
|
187 | SelectedReporter = (ref = coreReporters[strReporter]) != null ? ref : (function() {
|
188 | var reporterPath;
|
189 | try {
|
190 | reporterPath = resolve(strReporter, {
|
191 | basedir: process.cwd(),
|
192 | extensions: ['.js', '.coffee', '.litcoffee', '.coffee.md']
|
193 | });
|
194 | } catch (error) {
|
195 | reporterPath = strReporter;
|
196 | }
|
197 | return require(reporterPath);
|
198 | })();
|
199 | if ((base = options.argv).color == null) {
|
200 | base.color = options.argv.nocolor ? 'never' : 'auto';
|
201 | }
|
202 | colorize = (function() {
|
203 | switch (options.argv.color) {
|
204 | case 'always':
|
205 | return true;
|
206 | case 'never':
|
207 | return false;
|
208 | default:
|
209 | return process.stdout.isTTY;
|
210 | }
|
211 | })();
|
212 | reporter = new SelectedReporter(errorReport, {
|
213 | colorize: colorize,
|
214 | quiet: options.argv.q
|
215 | });
|
216 | reporter.publish();
|
217 | return process.on('exit', function() {
|
218 | return process.exit(errorReport.getExitCode());
|
219 | });
|
220 | };
|
221 |
|
222 |
|
223 | options = optimist.usage('Usage: coffeelint [options] source [...]').alias('f', 'file').alias('h', 'help').alias('v', 'version').alias('s', 'stdin').alias('q', 'quiet').alias('c', 'cache').describe('f', 'Specify a custom configuration file.').describe('rules', 'Specify a custom rule or directory of rules.').describe('makeconfig', 'Prints a default config file').describe('trimconfig', 'Compares your config with the default and prints a minimal configuration').describe('noconfig', 'Ignores any config file.').describe('h', 'Print help information.').describe('v', 'Print current version number.').describe('r', '(not used, but left for backward compatibility)').describe('reporter', 'built in reporter (default, csv, jslint, checkstyle, raw), or module, or path to reporter file.').describe('csv', '[deprecated] use --reporter csv').describe('jslint', '[deprecated] use --reporter jslint').describe('nocolor', '[deprecated] use --color=never').describe('checkstyle', '[deprecated] use --reporter checkstyle').describe('color=<when>', 'When to colorize the output. <when> can be one of always, never , or auto.').describe('s', 'Lint the source from stdin').describe('q', 'Only print errors.').describe('literate', 'Used with --stdin to process as Literate CoffeeScript').describe('c', 'Cache linting results').describe('ext', 'Specify an additional file extension, separated by comma.').boolean('csv').boolean('jslint').boolean('checkstyle').boolean('nocolor').boolean('noconfig').boolean('makeconfig').boolean('trimconfig').boolean('literate').boolean('r').boolean('s').boolean('q', 'Print errors only.').boolean('c');
|
224 |
|
225 | if (options.argv.v) {
|
226 | log(coffeelint.VERSION);
|
227 | process.exit(0);
|
228 | } else if (options.argv.h) {
|
229 | options.showHelp();
|
230 | process.exit(0);
|
231 | } else if (options.argv.trimconfig) {
|
232 | userConfig = (ref = loadConfig(options)) != null ? ref : getFallbackConfig();
|
233 | logConfig(coffeelint.trimConfig(userConfig));
|
234 | } else if (options.argv.makeconfig) {
|
235 | logConfig(coffeelint.getRules());
|
236 | } else if (options.argv._.length < 1 && !options.argv.s) {
|
237 | options.showHelp();
|
238 | process.exit(1);
|
239 | } else {
|
240 |
|
241 | if (options.argv.cache) {
|
242 | coffeelint.setCache(new Cache(path.join(os.tmpdir(), 'coffeelint')));
|
243 | }
|
244 |
|
245 | config = loadConfig(options);
|
246 | if (options.argv.rules) {
|
247 | ruleLoader.loadRule(coffeelint, options.argv.rules);
|
248 | }
|
249 | if (options.argv.s) {
|
250 |
|
251 | data = '';
|
252 | stdin = process.openStdin();
|
253 | stdin.on('data', function(buffer) {
|
254 | if (buffer) {
|
255 | return data += buffer.toString();
|
256 | }
|
257 | });
|
258 | stdin.on('end', function() {
|
259 | var errorReport;
|
260 | errorReport = lintSource(data, config, options.argv.literate);
|
261 | return reportAndExit(errorReport, options);
|
262 | });
|
263 | } else {
|
264 |
|
265 | paths = options.argv._;
|
266 | scripts = findCoffeeScripts(paths, options.argv.ext);
|
267 | if (fs.existsSync('.coffeelintignore')) {
|
268 | scripts = ignore().add(fs.readFileSync('.coffeelintignore').toString()).filter(scripts);
|
269 | }
|
270 |
|
271 | errorReport = lintFiles(scripts, config, options.argv.literate);
|
272 | reportAndExit(errorReport, options);
|
273 | }
|
274 | }
|
275 |
|
276 | }).call(this);
|