1 | module.exports.lintText = lintText
|
2 | module.exports.lintFiles = lintFiles
|
3 |
|
4 | var dezalgo = require('dezalgo')
|
5 | var eslint = require('eslint')
|
6 | var findRoot = require('find-root')
|
7 | var fs = require('fs')
|
8 | var glob = require('glob')
|
9 | var parallel = require('run-parallel')
|
10 | var path = require('path')
|
11 | var uniq = require('uniq')
|
12 |
|
13 | var DEFAULT_PATTERNS = [
|
14 | '**/*.js',
|
15 | '**/*.jsx'
|
16 | ]
|
17 |
|
18 | var DEFAULT_IGNORE_PATTERNS = [
|
19 | 'coverage/**',
|
20 | 'node_modules/**',
|
21 | '**/*.min.js',
|
22 | '**/bundle.js'
|
23 | ]
|
24 |
|
25 | var ESLINT_CONFIG = {
|
26 | baseConfig: require(path.join(__dirname, 'rc', '.eslintrc.json')),
|
27 | useEslintrc: true
|
28 | }
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | function lintText (text, opts, cb) {
|
40 | if (typeof opts === 'function') {
|
41 | cb = opts
|
42 | opts = {}
|
43 | }
|
44 | opts = parseOpts(opts)
|
45 | cb = dezalgo(cb)
|
46 |
|
47 | var result
|
48 | try {
|
49 | result = new eslint.CLIEngine(ESLINT_CONFIG).executeOnText(text)
|
50 | } catch (err) {
|
51 | return cb(err)
|
52 | }
|
53 | return cb(null, result)
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | function lintFiles (files, opts, cb) {
|
66 | if (typeof opts === 'function') {
|
67 | cb = opts
|
68 | opts = {}
|
69 | }
|
70 | opts = parseOpts(opts)
|
71 | cb = dezalgo(cb)
|
72 |
|
73 | if (typeof files === 'string') files = [ files ]
|
74 | if (files.length === 0) files = DEFAULT_PATTERNS
|
75 |
|
76 |
|
77 | parallel(files.map(function (pattern) {
|
78 | return function (cb) {
|
79 | glob(pattern, {
|
80 | cwd: opts.cwd,
|
81 | ignore: opts.ignore,
|
82 | nodir: true
|
83 | }, cb)
|
84 | }
|
85 | }), function (err, results) {
|
86 | if (err) return cb(err)
|
87 |
|
88 |
|
89 | var files = results.reduce(function (files, result) {
|
90 | result.forEach(function (file) {
|
91 | files.push(path.join(opts.cwd, file))
|
92 | })
|
93 | return files
|
94 | }, [])
|
95 |
|
96 |
|
97 | files = uniq(files)
|
98 |
|
99 |
|
100 | if (opts.ignoreMatcher) {
|
101 | files = files.filter(function (file) {
|
102 | return !opts.ignoreMatcher.shouldIgnore(file)
|
103 | })
|
104 | }
|
105 |
|
106 |
|
107 | if (opts._onFiles) opts._onFiles(files)
|
108 |
|
109 | var result
|
110 | try {
|
111 | result = new eslint.CLIEngine(ESLINT_CONFIG).executeOnFiles(files)
|
112 | } catch (err) {
|
113 | return cb(err)
|
114 | }
|
115 | return cb(null, result)
|
116 | })
|
117 | }
|
118 |
|
119 | function parseOpts (opts) {
|
120 | if (!opts) opts = {}
|
121 |
|
122 | if (!opts.cwd) opts.cwd = process.cwd()
|
123 |
|
124 |
|
125 | var ignore = (opts.ignore || []).concat(DEFAULT_IGNORE_PATTERNS)
|
126 |
|
127 | var root
|
128 | try {
|
129 | root = findRoot(opts.cwd)
|
130 | } catch (e) {}
|
131 |
|
132 | if (root) {
|
133 |
|
134 | try {
|
135 | var packageOpts = require(path.join(root, 'package.json')).standard
|
136 | if (packageOpts) ignore = ignore.concat(packageOpts.ignore)
|
137 | } catch (e) {}
|
138 |
|
139 |
|
140 | try {
|
141 | var gitignore = fs.readFileSync(path.join(root, '.gitignore'), 'utf8')
|
142 | ignore = ignore.concat(gitignore.split(/\r?\n|\r/).filter(nonEmpty))
|
143 | } catch (e) {}
|
144 | }
|
145 |
|
146 |
|
147 | ignore = ignore.map(function (pattern) {
|
148 | return pattern.indexOf('./') === 0 ? pattern.slice(2) : pattern
|
149 | })
|
150 |
|
151 |
|
152 | opts.ignore = []
|
153 | ignore.forEach(function (pattern) {
|
154 | opts.ignore.push(pattern)
|
155 | opts.ignore.push(pattern + '/**')
|
156 | })
|
157 |
|
158 | return opts
|
159 | }
|
160 |
|
161 | function nonEmpty (line) {
|
162 | return line.trim() !== '' && line[0] !== '#'
|
163 | }
|