-
Notifications
You must be signed in to change notification settings - Fork 3
/
utils.js
117 lines (104 loc) · 3.96 KB
/
utils.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
/**
* Shared lib between rule and tests
*/
const _ = require("lodash"),
fs = require("fs"),
findRoot = require("find-root"),
path = require("path");
const COULD_NOT_FIND = `Missing notice header`;
const REPORT_AND_SKIP = `Found a header comment which did not have a notice header, skipping fix and reporting`;
const OUTSIDE_TOLERANCE = `Found a header comment which was too different from the required notice header (similarity={{ similarity }})`;
const DEFAULT_MESSAGE_CONFIG = {
whenFailedToMatch: COULD_NOT_FIND,
reportAndSkip: REPORT_AND_SKIP,
whenOutsideTolerance: OUTSIDE_TOLERANCE
};
const ESCAPE = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
const YEAR_REGEXP = /20\d{2}/;
const NON_MATCHING_HEADER_ACTIONS = ["prepend", "replace", "report"];
function escapeRegExp(str) {
return String(str).replace(ESCAPE, "\\$&");
}
function stringifyRegexp(regexp) {
return regexp instanceof RegExp ? regexp.source : String(regexp);
}
function regexpizeTemplate({ template, varRegexps }) {
const allRegexpVars = Object.assign({}, { YEAR: YEAR_REGEXP }, varRegexps);
const allPatternVars = _.mapValues(allRegexpVars, stringifyRegexp);
return new RegExp(_.template(escapeRegExp(template))(allPatternVars));
}
function resolveTemplate({ templateFile, template, fileName }) {
if (template) return template;
//No template file, so move foward and disable --fix
if (!templateFile) return null;
//Naively look for the templateFile first
if (fs.existsSync(templateFile)) {
return fs.readFileSync(templateFile, "utf8");
}
if (!fs.existsSync(fileName)) {
throw new Error(`Could not find the file name ${fileName}. This is necessary to find the root`);
}
const root = findRoot(fileName);
const rootTemplateFile = path.join(root, templateFile);
if (fs.existsSync(rootTemplateFile)) {
return fs.readFileSync(rootTemplateFile, "utf8");
}
const absRootTemplateFile = path.resolve(rootTemplateFile);
if (fs.existsSync(absRootTemplateFile)) {
return fs.readFileSync(absRootTemplateFile, "utf8");
}
throw new Error(`Can't find templateFile @ ${absRootTemplateFile}`);
}
function resolveOptions(
{
mustMatch,
templateFile,
template,
templateVars,
chars,
onNonMatchingHeader,
varRegexps,
nonMatchingTolerance,
messages
},
fileName
) {
onNonMatchingHeader = onNonMatchingHeader || "prepend";
templateVars = templateVars || {};
varRegexps = varRegexps || {};
chars = chars || 1000;
nonMatchingTolerance = nonMatchingTolerance || null;
messages = Object.assign({}, DEFAULT_MESSAGE_CONFIG, messages || {});
let mustMatchTemplate = false;
if (!mustMatch) {
mustMatchTemplate = true;
} else if (!(mustMatch instanceof RegExp)) {
mustMatch = new RegExp(mustMatch);
}
template = resolveTemplate({ templateFile, template, fileName });
if(typeof template === 'string'){
template = template.replace(/\r\n/g, "\n");
}
const YEAR = new Date().getFullYear();
const allVars = Object.assign({}, { YEAR }, templateVars);
if (mustMatchTemplate && template) {
//create mustMatch from varRegexps and template
mustMatch = regexpizeTemplate({ template, varRegexps });
} else if (!template && mustMatchTemplate) {
throw new Error("Either mustMatch, template, or templateFile must be set");
}
const resolvedTemplate = _.template(template)(allVars).replace(/\r\n/g, "\n");
return { resolvedTemplate, mustMatch, chars, onNonMatchingHeader, nonMatchingTolerance, messages };
}
function createFixer({ resolvedTemplate, hasHeaderComment, topNode, onNonMatchingHeader }) {
if (!resolvedTemplate) {
return undefined;
}
if (!hasHeaderComment || (hasHeaderComment && onNonMatchingHeader === "prepend")) {
return fixer => fixer.insertTextBeforeRange([0, 0], resolvedTemplate);
}
if (hasHeaderComment && onNonMatchingHeader === "replace") {
return fixer => fixer.replaceText(topNode, resolvedTemplate);
}
}
module.exports = { createFixer, regexpizeTemplate, COULD_NOT_FIND, REPORT_AND_SKIP, resolveOptions };