UNPKG

9.11 kBJavaScriptView Raw
1
2/*
3CoffeeLint
4
5Copyright (c) 2011 Matthew Perpick.
6CoffeeLint is freely distributable under the MIT license.
7 */
8
9(function() {
10 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;
11
12 resolve = require('resolve').sync;
13
14 path = require('path');
15
16 fs = require('fs');
17
18 os = require('os');
19
20 glob = require('glob');
21
22 optimist = require('optimist');
23
24 ignore = require('ignore');
25
26 stripComments = require('strip-json-comments');
27
28 thisdir = path.dirname(fs.realpathSync(__filename));
29
30 coffeelint = require(path.join(thisdir, 'coffeelint'));
31
32 configfinder = require(path.join(thisdir, 'configfinder'));
33
34 ruleLoader = require(path.join(thisdir, 'ruleLoader'));
35
36 Cache = require(path.join(thisdir, 'cache'));
37
38 CoffeeScript = require('coffee-script');
39
40 CoffeeScript.register();
41
42 log = function() {
43 return console.log.apply(console, arguments);
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 read = function(path) {
59 var realPath;
60 realPath = fs.realpathSync(path);
61 return fs.readFileSync(realPath).toString();
62 };
63
64 getAllExtention = function(extension) {
65 if (extension != null) {
66 extension = ['coffee'].concat(extension != null ? extension.split(',') : void 0);
67 return "@(" + (extension.join('|')) + ")";
68 } else {
69 return 'coffee';
70 }
71 };
72
73 findCoffeeScripts = function(paths, extension) {
74 var allExtention, files, i, len, p;
75 files = [];
76 allExtention = getAllExtention(extension);
77 for (i = 0, len = paths.length; i < len; i++) {
78 p = paths[i];
79 if (fs.statSync(p).isDirectory()) {
80 files = files.concat(glob.sync(p + "/**/*." + allExtention));
81 } else {
82 files.push(p);
83 }
84 }
85 return files;
86 };
87
88 lintFiles = function(files, config) {
89 var errorReport, file, fileConfig, i, len, literate, source;
90 errorReport = new coffeelint.getErrorReport();
91 for (i = 0, len = files.length; i < len; i++) {
92 file = files[i];
93 source = read(file);
94 literate = CoffeeScript.helpers.isLiterate(file);
95 fileConfig = config ? config : getFallbackConfig(file);
96 errorReport.lint(file, source, fileConfig, literate);
97 }
98 return errorReport;
99 };
100
101 lintSource = function(source, config, literate) {
102 var errorReport;
103 if (literate == null) {
104 literate = false;
105 }
106 errorReport = new coffeelint.getErrorReport();
107 config || (config = getFallbackConfig());
108 errorReport.lint('stdin', source, config, literate);
109 return errorReport;
110 };
111
112 readConfigFile = function(path) {
113 var text;
114 text = read(path);
115 try {
116 jsonIndentation = text.split('\n')[1].match(/^\s+/)[0].length;
117 } catch (undefined) {}
118 return JSON.parse(stripComments(text));
119 };
120
121 loadConfig = function(options) {
122 var config;
123 config = null;
124 if (!options.argv.noconfig) {
125 if (options.argv.f) {
126 config = readConfigFile(options.argv.f);
127 if (config.coffeelintConfig) {
128 config = config.coffeelintConfig;
129 }
130 }
131 }
132 return config;
133 };
134
135 getFallbackConfig = function(filename) {
136 if (filename == null) {
137 filename = null;
138 }
139 if (!options.argv.noconfig) {
140 return configfinder.getConfig(filename);
141 }
142 };
143
144 deprecatedReporter = function(errorReport, reporter) {
145 var base;
146 if ((base = errorReport.paths)['coffeelint_fake_file.coffee'] == null) {
147 base['coffeelint_fake_file.coffee'] = [];
148 }
149 errorReport.paths['coffeelint_fake_file.coffee'].push({
150 'level': 'warn',
151 'rule': 'commandline',
152 'message': "parameter --" + reporter + " is deprecated. Use --reporter " + reporter + " instead",
153 'lineNumber': 0
154 });
155 return reporter;
156 };
157
158 coreReporters = {
159 "default": require(path.join(thisdir, 'reporters', 'default')),
160 csv: require(path.join(thisdir, 'reporters', 'csv')),
161 jslint: require(path.join(thisdir, 'reporters', 'jslint')),
162 checkstyle: require(path.join(thisdir, 'reporters', 'checkstyle')),
163 raw: require(path.join(thisdir, 'reporters', 'raw'))
164 };
165
166 reportAndExit = function(errorReport, options) {
167 var SelectedReporter, base, colorize, ref, reporter, strReporter;
168 strReporter = options.argv.jslint ? deprecatedReporter(errorReport, 'jslint') : options.argv.csv ? deprecatedReporter(errorReport, 'csv') : options.argv.checkstyle ? deprecatedReporter(errorReport, 'checkstyle') : options.argv.reporter;
169 if (strReporter == null) {
170 strReporter = 'default';
171 }
172 SelectedReporter = (ref = coreReporters[strReporter]) != null ? ref : (function() {
173 var error, reporterPath;
174 try {
175 reporterPath = resolve(strReporter, {
176 basedir: process.cwd()
177 });
178 } catch (error) {
179 reporterPath = strReporter;
180 }
181 return require(reporterPath);
182 })();
183 if ((base = options.argv).color == null) {
184 base.color = options.argv.nocolor ? 'never' : 'auto';
185 }
186 colorize = (function() {
187 switch (options.argv.color) {
188 case 'always':
189 return true;
190 case 'never':
191 return false;
192 default:
193 return process.stdout.isTTY;
194 }
195 })();
196 reporter = new SelectedReporter(errorReport, {
197 colorize: colorize,
198 quiet: options.argv.q
199 });
200 reporter.publish();
201 return process.on('exit', function() {
202 return process.exit(errorReport.getExitCode());
203 });
204 };
205
206 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');
207
208 if (options.argv.v) {
209 log(coffeelint.VERSION);
210 process.exit(0);
211 } else if (options.argv.h) {
212 options.showHelp();
213 process.exit(0);
214 } else if (options.argv.trimconfig) {
215 userConfig = (ref = loadConfig(options)) != null ? ref : getFallbackConfig();
216 logConfig(coffeelint.trimConfig(userConfig));
217 } else if (options.argv.makeconfig) {
218 logConfig(coffeelint.getRules());
219 } else if (options.argv._.length < 1 && !options.argv.s) {
220 options.showHelp();
221 process.exit(1);
222 } else {
223 if (options.argv.cache) {
224 coffeelint.setCache(new Cache(path.join(os.tmpdir(), 'coffeelint')));
225 }
226 config = loadConfig(options);
227 if (options.argv.rules) {
228 ruleLoader.loadRule(coffeelint, options.argv.rules);
229 }
230 if (options.argv.s) {
231 data = '';
232 stdin = process.openStdin();
233 stdin.on('data', function(buffer) {
234 if (buffer) {
235 return data += buffer.toString();
236 }
237 });
238 stdin.on('end', function() {
239 var errorReport;
240 errorReport = lintSource(data, config, options.argv.literate);
241 return reportAndExit(errorReport, options);
242 });
243 } else {
244 paths = options.argv._;
245 scripts = findCoffeeScripts(paths, options.argv.ext);
246 scripts = ignore().addIgnoreFile('.coffeelintignore').filter(scripts);
247 errorReport = lintFiles(scripts, config, options.argv.literate);
248 reportAndExit(errorReport, options);
249 }
250 }
251
252}).call(this);