191 lines
6.7 KiB
JavaScript
191 lines
6.7 KiB
JavaScript
/**
|
|
* require a consistent order of module dependencies
|
|
*
|
|
* Module dependencies should be sorted in a logical manner.
|
|
* This rule provides two ways to sort modules, grouped or ungrouped.
|
|
* In grouped mode the modules should be grouped in the order: standard modules - third party modules - custom modules.
|
|
* The modules should be sorted alphabetically within its group.
|
|
* A prefix can be specified to determine which prefix the custom modules have.
|
|
* Without grouped set to `false` all dependencies combined should be sorted alphabetically.
|
|
* ('module-dependency-order', [2, {grouped: true, prefix: "app"}])
|
|
*
|
|
* @version 0.12.0
|
|
* @category conventions
|
|
* @sinceAngularVersion 1.x
|
|
*/
|
|
'use strict';
|
|
|
|
var utils = require('./utils/utils');
|
|
|
|
module.exports = {
|
|
meta: {
|
|
docs: {
|
|
url: 'https://github.com/Gillespie59/eslint-plugin-angular/blob/master/docs/rules/module-dependency-order.md'
|
|
},
|
|
schema: [{
|
|
type: 'object',
|
|
properties: {
|
|
grouped: {
|
|
type: 'boolean'
|
|
},
|
|
prefix: {
|
|
type: ['string', 'null']
|
|
}
|
|
}
|
|
}]
|
|
},
|
|
create: function(context) {
|
|
var options = context.options[0] || {};
|
|
var groupedMode = options.grouped !== false;
|
|
var moduleRegex;
|
|
if (groupedMode) {
|
|
moduleRegex = utils.convertPrefixToRegex(options.prefix);
|
|
}
|
|
|
|
var standard = [
|
|
// Libraries in the angular.js repository
|
|
'ng',
|
|
'ngAnimate',
|
|
'ngAria',
|
|
'ngCookies',
|
|
'ngLocale',
|
|
'ngMessageFormat',
|
|
'ngMessages',
|
|
'ngMock',
|
|
'ngResource',
|
|
'ngRoute',
|
|
'ngSanitize',
|
|
'ngTouch',
|
|
|
|
// Libraries maintained by the angular team, but in another repository
|
|
'ngMaterial',
|
|
'ngNewRouter'
|
|
];
|
|
|
|
function checkLiteral(node) {
|
|
if (node && node.type !== 'Literal' && node.type !== 'Identifier') {
|
|
context.report(node, 'Unexpected non-literal or identifier value' + node.type);
|
|
return false;
|
|
}
|
|
if (!node) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function checkCombined(deps) {
|
|
var lastCorrect;
|
|
deps.elements.forEach(function(node) {
|
|
if (!checkLiteral(node)) {
|
|
return;
|
|
}
|
|
var value = node.value || node.name;
|
|
if (lastCorrect === undefined || lastCorrect.localeCompare(value) < 0) {
|
|
lastCorrect = value;
|
|
} else {
|
|
context.report(node, '{{current}} should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function isStandardModule(value) {
|
|
return standard.indexOf(value) !== -1;
|
|
}
|
|
|
|
function isCustomModule(value) {
|
|
return moduleRegex && moduleRegex.test(value);
|
|
}
|
|
|
|
function checkGrouped(deps) {
|
|
var lastCorrect;
|
|
var group = 'standard';
|
|
deps.elements.forEach(function loop(node) {
|
|
if (!checkLiteral(node)) {
|
|
return;
|
|
}
|
|
var value = node.value || node.name;
|
|
if (lastCorrect === undefined) {
|
|
lastCorrect = value;
|
|
if (isCustomModule(value)) {
|
|
group = 'custom';
|
|
} else if (standard.indexOf(value) === -1) {
|
|
group = 'third party';
|
|
}
|
|
return;
|
|
}
|
|
if (group === 'standard') {
|
|
if (isStandardModule(value)) {
|
|
if (lastCorrect.localeCompare(value) > 0) {
|
|
context.report(node, '{{current}} should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
} else {
|
|
lastCorrect = value;
|
|
}
|
|
} else {
|
|
if (isCustomModule(value)) {
|
|
group = 'custom';
|
|
} else {
|
|
group = 'third party';
|
|
}
|
|
lastCorrect = value;
|
|
}
|
|
}
|
|
if (group === 'third party') {
|
|
if (isStandardModule(value)) {
|
|
context.report(node, '{{current}} is a standard module and should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
} else if (isCustomModule(value)) {
|
|
group = 'custom';
|
|
lastCorrect = value;
|
|
} else if (lastCorrect.localeCompare(value) > 0) {
|
|
context.report(node, '{{current}} should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
} else {
|
|
lastCorrect = value;
|
|
}
|
|
}
|
|
if (group === 'custom') {
|
|
if (isStandardModule(value)) {
|
|
context.report(node, '{{current}} is a standard module and should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
} else if (!isCustomModule(value)) {
|
|
context.report(node, '{{current}} is a third party module and should be sorted before {{last}}', {
|
|
current: value,
|
|
last: lastCorrect
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return {
|
|
CallExpression: function(node) {
|
|
if (!utils.isAngularModuleDeclaration(node)) {
|
|
return;
|
|
}
|
|
var deps = node.arguments[1];
|
|
if (deps.type !== 'ArrayExpression') {
|
|
context.report(deps, 'Dependencies should be a literal array');
|
|
return;
|
|
}
|
|
if (groupedMode) {
|
|
checkGrouped(deps);
|
|
} else {
|
|
checkCombined(deps);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
};
|