Skip to content

Commit 6f04e3a

Browse files
authored
Merge pull request webpack#5967 from webpack/lint/schema
add linting for schemas
2 parents d8b28cd + 00a9808 commit 6f04e3a

6 files changed

Lines changed: 570 additions & 99 deletions

File tree

lib/WebpackOptionsValidationError.js

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,21 @@ const getSchemaPartText = (schemaPart, additionalPath) => {
3535
while(schemaPart.$ref) schemaPart = getSchemaPart(schemaPart.$ref);
3636
let schemaText = WebpackOptionsValidationError.formatSchema(schemaPart);
3737
if(schemaPart.description)
38-
schemaText += `\n${schemaPart.description}`;
38+
schemaText += `\n-> ${schemaPart.description}`;
3939
return schemaText;
4040
};
4141

42+
const getSchemaPartDescription = schemaPart => {
43+
while(schemaPart.$ref) schemaPart = getSchemaPart(schemaPart.$ref);
44+
if(schemaPart.description)
45+
return `\n-> ${schemaPart.description}`;
46+
return "";
47+
};
48+
49+
const filterChildren = children => {
50+
return children.filter(err => err.keyword !== "anyOf" && err.keyword !== "allOf" && err.keyword !== "oneOf");
51+
};
52+
4253
const indent = (str, prefix, firstLine) => {
4354
if(firstLine) {
4455
return prefix + str.replace(/\n(?!$)/g, "\n" + prefix);
@@ -143,8 +154,16 @@ class WebpackOptionsValidationError extends WebpackError {
143154
return baseMessage;
144155
} else if(err.keyword === "oneOf" || err.keyword === "anyOf") {
145156
if(err.children && err.children.length > 0) {
157+
if(err.schema.length === 1) {
158+
const lastChild = err.children[err.children.length - 1];
159+
const remainingChildren = err.children.slice(0, err.children.length - 1);
160+
return WebpackOptionsValidationError.formatValidationError(Object.assign({}, lastChild, {
161+
children: remainingChildren,
162+
parentSchema: Object.assign({}, err.parentSchema, lastChild.parentSchema)
163+
}));
164+
}
146165
return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}\n` +
147-
`Details:\n${err.children.map(err => " * " + indent(WebpackOptionsValidationError.formatValidationError(err), " ", false)).join("\n")}`;
166+
`Details:\n${filterChildren(err.children).map(err => " * " + indent(WebpackOptionsValidationError.formatValidationError(err), " ", false)).join("\n")}`;
148167
}
149168
return `${dataPath} should be one of these:\n${getSchemaPartText(err.parentSchema)}`;
150169

@@ -158,29 +177,33 @@ class WebpackOptionsValidationError extends WebpackError {
158177
} else if(err.keyword === "type") {
159178
switch(err.params.type) {
160179
case "object":
161-
return `${dataPath} should be an object.`;
180+
return `${dataPath} should be an object.${getSchemaPartDescription(err.parentSchema)}`;
162181
case "string":
163-
return `${dataPath} should be a string.`;
182+
return `${dataPath} should be a string.${getSchemaPartDescription(err.parentSchema)}`;
164183
case "boolean":
165-
return `${dataPath} should be a boolean.`;
184+
return `${dataPath} should be a boolean.${getSchemaPartDescription(err.parentSchema)}`;
166185
case "number":
167-
return `${dataPath} should be a number.`;
186+
return `${dataPath} should be a number.${getSchemaPartDescription(err.parentSchema)}`;
168187
case "array":
169188
return `${dataPath} should be an array:\n${getSchemaPartText(err.parentSchema)}`;
170189
}
171190
return `${dataPath} should be ${err.params.type}:\n${getSchemaPartText(err.parentSchema)}`;
172191
} else if(err.keyword === "instanceof") {
173-
return `${dataPath} should be an instance of ${getSchemaPartText(err.parentSchema)}.`;
192+
return `${dataPath} should be an instance of ${getSchemaPartText(err.parentSchema)}`;
174193
} else if(err.keyword === "required") {
175194
const missingProperty = err.params.missingProperty.replace(/^\./, "");
176195
return `${dataPath} misses the property '${missingProperty}'.\n${getSchemaPartText(err.parentSchema, ["properties", missingProperty])}`;
177-
} else if(err.keyword === "minLength" || err.keyword === "minItems") {
196+
} else if(err.keyword === "minimum") {
197+
return `${dataPath} ${err.message}.${getSchemaPartDescription(err.parentSchema)}`;
198+
} else if(err.keyword === "uniqueItems") {
199+
return `${dataPath} should not contain the item '${err.data[err.params.i]}' twice.${getSchemaPartDescription(err.parentSchema)}`;
200+
} else if(err.keyword === "minLength" || err.keyword === "minItems" || err.keyword === "minProperties") {
178201
if(err.params.limit === 1)
179-
return `${dataPath} should not be empty.`;
202+
return `${dataPath} should not be empty.${getSchemaPartDescription(err.parentSchema)}`;
180203
else
181-
return `${dataPath} ${err.message}`;
204+
return `${dataPath} ${err.message}${getSchemaPartDescription(err.parentSchema)}`;
182205
} else if(err.keyword === "absolutePath") {
183-
const baseMessage = `${dataPath}: ${err.message}`;
206+
const baseMessage = `${dataPath}: ${err.message}${getSchemaPartDescription(err.parentSchema)}`;
184207
if(dataPath === "configuration.output.filename") {
185208
return `${baseMessage}\n` +
186209
"Please use output.path to specify absolute path and output.filename for the file name.";

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"express": "~4.13.1",
4444
"extract-text-webpack-plugin": "^3.0.0",
4545
"file-loader": "^0.11.2",
46+
"glob": "^7.1.2",
4647
"i18n-webpack-plugin": "^1.0.0",
4748
"istanbul": "^0.4.5",
4849
"jade": "^1.11.0",
@@ -103,10 +104,11 @@
103104
"circleci:lint": "npm run lint-files && npm run nsp",
104105
"build:examples": "cd examples && node buildAll.js",
105106
"pretest": "npm run lint-files",
106-
"lint-files": "npm run lint && npm run beautify-lint",
107+
"lint-files": "npm run lint && npm run beautify-lint && npm run schema-lint",
107108
"lint": "eslint lib bin hot buildin \"test/**/webpack.config.js\" \"test/binCases/**/test.js\" \"examples/**/webpack.config.js\"",
108109
"fix": "npm run lint -- --fix",
109110
"beautify-lint": "beautify-lint \"lib/**/*.js\" \"hot/**/*.js\" \"bin/**/*.js\" \"benchmark/*.js\" \"test/*.js\"",
111+
"schema-lint": "mocha test/*.lint.js --opts test/lint-mocha.opts",
110112
"nsp": "nsp check --output summary",
111113
"benchmark": "mocha --max-old-space-size=4096 --harmony --trace-deprecation test/*.benchmark.js -R spec",
112114
"cover": "npm run cover:init && npm run cover:all && npm run cover:report",

0 commit comments

Comments
 (0)