-
Notifications
You must be signed in to change notification settings - Fork 9
/
index.js
120 lines (93 loc) · 2.93 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'use strict';
const path = require('path');
const pathExists = require('path-exists');
const yaml = require('js-yaml');
const Environment = require('./lib/environment');
const context = require('./lib/context');
const config = require('./lib/config');
const rules = require('./lib/rules');
const Fixer = require('./lib/fixer');
const FileSystem = require('./lib/fs/filesystem');
const ruleUtil = require('./lib/utils/rule');
const defaultConfig = require('./config');
const merge = (options, config) => {
const opts = Object.assign({}, options);
opts.inherit = opts.inherit === undefined ? config.inherit || true : opts.inherit;
const inherit = opts.inherit ? defaultConfig : {};
opts.rules = Object.assign({}, inherit.rules, config.rules, opts.rules);
opts.plugins = [].concat(inherit.plugins || [], config.plugins || [], opts.plugins || []);
delete config.rules;
delete config.plugins;
delete config.inherit;
return Object.assign(opts, config);
};
const lint = (input, opts) => {
if (typeof input !== 'string') {
return Promise.reject(new TypeError('No input provided.'));
}
opts = Object.assign({
cwd: process.cwd(),
plugins: [],
inherit: undefined,
ignores: []
}, opts);
const filePath = path.resolve(opts.cwd, input);
if (!pathExists.sync(filePath)) {
return Promise.reject(new Error(`Path ${input} does not exist.`));
}
// Create a new environment
const env = new Environment(filePath, opts);
const validations = [];
if (!env.isValid()) {
console.warn('No `package.json` found');
return Promise.resolve(validations);
}
return config.load(env)
.then(config => {
opts = merge(opts, config);
return env.load(opts);
})
.then(() => {
const ruleList = rules.parse(opts.rules);
const ruleIds = Object.keys(ruleList);
return Promise.all(ruleIds.map(ruleId => {
const mod = ruleUtil.resolve(ruleId, opts);
const rule = ruleList[ruleId];
// Create a rule context
const ctx = context.create(env, rule.slice(1));
// Execute the rule
return Promise.resolve()
.then(() => mod(ctx))
.then(() => {
ctx.reports.forEach(report => {
validations.push(Object.assign(report, {
ruleId,
severity: rule[0]
}));
});
});
}));
})
.then(() => validations);
};
exports.lint = lint;
exports.fix = (input, opts) => {
const fs = new FileSystem();
const fixer = new Fixer();
return lint(input, opts)
.then(validations => fixer.fixAll(validations.filter(x => x.fix)))
.then(() => {
// Write all the files
const promises = [];
for (const fd of fixer.files) {
let content = fd.contents;
if (fd.ext === '.json') {
content = JSON.stringify(fd.contents, undefined, fd.indent) + fd.lastchar;
} else if (fd.ext === '.yaml' || fd.ext === '.yml') {
content = yaml.safeDump(fd.contents, {indent: fd.indent.length});
}
promises.push(fs.writeFile(fd.file, content, 'utf8'));
}
return Promise.all(promises);
});
};