2018-05-03 12:28:14 +00:00
|
|
|
const minimatch = require('minimatch');
|
|
|
|
|
2018-06-03 16:32:38 +00:00
|
|
|
const versioning = require('../versioning');
|
2018-05-03 12:28:14 +00:00
|
|
|
const { mergeChildConfig } = require('../config');
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
applyPackageRules,
|
|
|
|
};
|
|
|
|
|
2018-05-03 12:42:27 +00:00
|
|
|
function applyPackageRules(inputConfig) {
|
|
|
|
let config = { ...inputConfig };
|
2018-06-16 07:28:11 +00:00
|
|
|
const {
|
|
|
|
versionScheme,
|
|
|
|
packageFile,
|
|
|
|
depType,
|
|
|
|
depName,
|
|
|
|
currentValue,
|
|
|
|
fromVersion,
|
2018-07-04 08:11:53 +00:00
|
|
|
updateType,
|
2018-07-25 06:58:17 +00:00
|
|
|
isBump,
|
2018-06-16 07:28:11 +00:00
|
|
|
} = config;
|
2018-05-06 10:04:48 +00:00
|
|
|
const packageRules = config.packageRules || [];
|
2018-05-03 12:41:04 +00:00
|
|
|
logger.trace(
|
2018-05-06 10:04:48 +00:00
|
|
|
{ depName, packageRules },
|
|
|
|
`Checking against ${packageRules.length} packageRules`
|
2018-05-03 12:41:04 +00:00
|
|
|
);
|
2018-05-06 10:04:48 +00:00
|
|
|
packageRules.forEach(packageRule => {
|
2018-05-03 12:28:14 +00:00
|
|
|
let {
|
|
|
|
paths,
|
|
|
|
depTypeList,
|
|
|
|
packageNames,
|
|
|
|
packagePatterns,
|
|
|
|
excludePackageNames,
|
|
|
|
excludePackagePatterns,
|
|
|
|
matchCurrentVersion,
|
2018-07-04 07:30:29 +00:00
|
|
|
updateTypes,
|
2018-05-03 12:28:14 +00:00
|
|
|
} = packageRule;
|
|
|
|
// Setting empty arrays simplifies our logic later
|
|
|
|
paths = paths || [];
|
|
|
|
depTypeList = depTypeList || [];
|
|
|
|
packageNames = packageNames || [];
|
|
|
|
packagePatterns = packagePatterns || [];
|
|
|
|
excludePackageNames = excludePackageNames || [];
|
|
|
|
excludePackagePatterns = excludePackagePatterns || [];
|
|
|
|
matchCurrentVersion = matchCurrentVersion || null;
|
2018-07-04 07:30:29 +00:00
|
|
|
updateTypes = updateTypes || [];
|
2018-05-03 12:28:14 +00:00
|
|
|
let positiveMatch = false;
|
|
|
|
let negativeMatch = false;
|
|
|
|
// Massage a positive patterns patch if an exclude one is present
|
|
|
|
if (
|
|
|
|
(excludePackageNames.length || excludePackagePatterns.length) &&
|
|
|
|
!(packageNames.length || packagePatterns.length)
|
|
|
|
) {
|
|
|
|
packagePatterns = ['.*'];
|
|
|
|
}
|
|
|
|
if (paths.length) {
|
|
|
|
const isMatch = paths.some(
|
|
|
|
rulePath =>
|
|
|
|
packageFile.includes(rulePath) || minimatch(packageFile, rulePath)
|
|
|
|
);
|
|
|
|
positiveMatch = positiveMatch || isMatch;
|
|
|
|
negativeMatch = negativeMatch || !isMatch;
|
|
|
|
}
|
|
|
|
if (depTypeList.length) {
|
|
|
|
const isMatch = depTypeList.includes(depType);
|
|
|
|
positiveMatch = positiveMatch || isMatch;
|
|
|
|
negativeMatch = negativeMatch || !isMatch;
|
|
|
|
}
|
2018-07-04 07:30:29 +00:00
|
|
|
if (updateTypes.length) {
|
2018-07-25 06:58:17 +00:00
|
|
|
const isMatch =
|
|
|
|
updateTypes.includes(updateType) ||
|
|
|
|
(isBump && updateTypes.includes('bump'));
|
2018-07-04 07:30:29 +00:00
|
|
|
positiveMatch = positiveMatch || isMatch;
|
|
|
|
negativeMatch = negativeMatch || !isMatch;
|
|
|
|
}
|
2018-05-03 12:28:14 +00:00
|
|
|
if (packageNames.length || packagePatterns.length) {
|
|
|
|
let isMatch = packageNames.includes(depName);
|
|
|
|
// name match is "or" so we check patterns if we didn't match names
|
|
|
|
if (!isMatch) {
|
|
|
|
for (const packagePattern of packagePatterns) {
|
|
|
|
const packageRegex = new RegExp(
|
|
|
|
packagePattern === '^*$' || packagePattern === '*'
|
|
|
|
? '.*'
|
|
|
|
: packagePattern
|
|
|
|
);
|
2018-09-07 08:23:40 +00:00
|
|
|
if (depName && depName.match(packageRegex)) {
|
2018-05-03 12:28:14 +00:00
|
|
|
logger.trace(`${depName} matches against ${packageRegex}`);
|
|
|
|
isMatch = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
positiveMatch = positiveMatch || isMatch;
|
|
|
|
negativeMatch = negativeMatch || !isMatch;
|
|
|
|
}
|
|
|
|
if (excludePackageNames.length) {
|
|
|
|
const isMatch = excludePackageNames.includes(depName);
|
|
|
|
negativeMatch = negativeMatch || isMatch;
|
|
|
|
positiveMatch = positiveMatch || !isMatch;
|
|
|
|
}
|
|
|
|
if (excludePackagePatterns.length) {
|
|
|
|
let isMatch = false;
|
|
|
|
for (const pattern of excludePackagePatterns) {
|
|
|
|
const packageRegex = new RegExp(
|
|
|
|
pattern === '^*$' || pattern === '*' ? '.*' : pattern
|
|
|
|
);
|
2018-09-07 08:23:40 +00:00
|
|
|
if (depName && depName.match(packageRegex)) {
|
2018-05-03 12:28:14 +00:00
|
|
|
logger.trace(`${depName} matches against ${packageRegex}`);
|
|
|
|
isMatch = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
negativeMatch = negativeMatch || isMatch;
|
|
|
|
positiveMatch = positiveMatch || !isMatch;
|
|
|
|
}
|
|
|
|
if (matchCurrentVersion) {
|
2018-06-16 07:28:11 +00:00
|
|
|
const { matches, isVersion } = versioning(versionScheme);
|
|
|
|
const compareVersion = isVersion(currentValue)
|
|
|
|
? currentValue // it's a version so we can match against it
|
|
|
|
: fromVersion; // need to match against this fromVersion, if available
|
|
|
|
if (compareVersion) {
|
|
|
|
const isMatch = matches(compareVersion, matchCurrentVersion);
|
2018-06-03 15:13:46 +00:00
|
|
|
positiveMatch = positiveMatch || isMatch;
|
|
|
|
negativeMatch = negativeMatch || !isMatch;
|
|
|
|
} else {
|
|
|
|
negativeMatch = true;
|
|
|
|
}
|
2018-05-03 12:28:14 +00:00
|
|
|
}
|
|
|
|
// This rule is considered matched if there was at least one positive match and no negative matches
|
|
|
|
if (positiveMatch && !negativeMatch) {
|
|
|
|
// Package rule config overrides any existing config
|
2018-05-03 12:42:27 +00:00
|
|
|
config = mergeChildConfig(config, packageRule);
|
|
|
|
delete config.packageNames;
|
|
|
|
delete config.packagePatterns;
|
|
|
|
delete config.excludePackageNames;
|
|
|
|
delete config.excludePackagePatterns;
|
|
|
|
delete config.depTypeList;
|
|
|
|
delete config.matchCurrentVersion;
|
2018-05-03 12:28:14 +00:00
|
|
|
}
|
|
|
|
});
|
2018-07-05 16:55:00 +00:00
|
|
|
return config;
|
2018-05-03 12:28:14 +00:00
|
|
|
}
|