diff --git a/lib/config/definitions.js b/lib/config/definitions.js index 44be7fcbf6c29c4bd453701257c427d915f61ea2..ac701c84ded079840886dcfd0986856095b8eff8 100644 --- a/lib/config/definitions.js +++ b/lib/config/definitions.js @@ -231,6 +231,24 @@ const options = [ stage: 'repository', default: ['**/node_modules/**', '**/bower_components/**'], }, + { + name: 'pathRules', + description: + 'Apply config on a path-based basis. Consists of a paths array plus whatever other configuration objects to apply', + type: 'list', + stage: 'repository', + cli: false, + env: false, + }, + { + name: 'paths', + description: + 'List of strings or glob patterns to match against package files. Applicable inside pathRules only', + type: 'list', + stage: 'repository', + cli: false, + env: false, + }, { name: 'dependencies', description: 'Configuration specifically for `package.json`>`dependencies`', diff --git a/lib/manager/resolve.js b/lib/manager/resolve.js index 12e467ac5f542bd0194024f0030b7128d2326a1f..9c94b56ba3cf4e44c5a83db06ff586c1ebe27637 100644 --- a/lib/manager/resolve.js +++ b/lib/manager/resolve.js @@ -1,5 +1,6 @@ const path = require('path'); const upath = require('upath'); +const minimatch = require('minimatch'); const { migrateAndValidate } = require('../config/migrate-validate'); const presets = require('../config/presets'); @@ -163,7 +164,29 @@ async function resolvePackageFiles(config) { } logger.debug('queue'); const queue = allPackageFiles.map(p => resolvePackageFile(p)); - const packageFiles = (await Promise.all(queue)).filter(p => p !== null); + let packageFiles = (await Promise.all(queue)).filter(p => p !== null); + + logger.debug('Checking against path rules'); + packageFiles = packageFiles.map(pf => { + let packageFile = { ...pf }; + for (const pathRule of config.pathRules) { + /* eslint-disable no-loop-func */ + if ( + pathRule.paths.some( + rulePath => + packageFile.packageFile.includes(rulePath) || + minimatch(packageFile.packageFile, rulePath) + ) + ) { + logger.debug({ pathRule, packageFile }, 'Matched pathRule'); + packageFile = mergeChildConfig(packageFile, pathRule); + delete packageFile.paths; + } + /* eslint-enable */ + } + return packageFile; + }); + platform.ensureIssueClosing('Action Required: Fix Renovate Configuration'); return checkMonorepos({ ...config, packageFiles }); } diff --git a/test/manager/resolve.spec.js b/test/manager/resolve.spec.js index d6554aee48066ec660d3286e13d85eaa1427352e..7a640caef6e5261efcc512c549f97ceee9ad8d81 100644 --- a/test/manager/resolve.spec.js +++ b/test/manager/resolve.spec.js @@ -104,5 +104,23 @@ describe('manager/resolve', () => { const res = await resolvePackageFiles(config); expect(res.packageFiles).toMatchSnapshot(); }); + it('applies package rules', async () => { + config.pathRules = [ + { + paths: ['examples/**'], + prTitle: 'abcdefg', + }, + ]; + config.packageFiles = ['package.json', 'examples/a/package.json']; + platform.getFileList.mockReturnValue([ + 'package.json', + 'examples/a/package.json', + ]); + platform.getFile.mockReturnValue('{}'); + const res = await resolvePackageFiles(config); + expect(res.packageFiles).toHaveLength(2); + expect(res.packageFiles[0].prTitle).not.toEqual('abcdefg'); + expect(res.packageFiles[1].prTitle).toEqual('abcdefg'); + }); }); }); diff --git a/website/docs/_posts/2017-10-05-configuration-options.md b/website/docs/_posts/2017-10-05-configuration-options.md index a47a760b02ccbe49c4a0b3abcd7647ec007b1633..b826796848c0ab51c81495ddaa2d7efcae3323d8 100644 --- a/website/docs/_posts/2017-10-05-configuration-options.md +++ b/website/docs/_posts/2017-10-05-configuration-options.md @@ -617,6 +617,35 @@ Configuration specific for patch dependency updates. Add to this object if you wish to define rules that apply only to patch updates. See also `major` and `minor` configuration options. +## pathRules + +Apply config on a path-based basis. Consists of a `paths` array plus whatever other configuration objects to apply. + +| name | value | +| ------- | ----- | +| type | list | +| default | [] | + +Path rules are convenient to use if you wish to apply configuration rules to certain package files without needing to configure them all in the `packageFiles` array. For example, if you have an `examples` directory and you want all updates to those examples to use the `chore` prefix instead of `fix`, then you could add this configuration: + +```json + "pathRules": [ + { + "paths": ["examples/**"], + "extends": [":semanticCommitTypeAll(chore)"] + } + ] +``` + +## paths + +List of strings or glob patterns to match against package files. Applicable inside pathRules only. + +| name | value | +| ------- | ----- | +| type | list | +| default | [] | + ## peerDependencies Configuration specific for `package.json > peerDependencies`.