mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-12 06:56:24 +00:00
feat!: merge matchPaths and matchFiles into matchFileNames (#22406)
Closes #22395 BREAKING CHANGE: matchPaths and matchFiles are now combined into matchFileNames, supporting exact match and glob-only
This commit is contained in:
parent
033d776ab0
commit
e3d5f7df92
23 changed files with 118 additions and 170 deletions
|
@ -1872,28 +1872,28 @@ Example:
|
||||||
|
|
||||||
The above rule will group together the `neutrino` package and any package matching `@neutrino/*`.
|
The above rule will group together the `neutrino` package and any package matching `@neutrino/*`.
|
||||||
|
|
||||||
Path rules are convenient to use if you wish to apply configuration rules to certain package files using patterns.
|
File name matches are convenient to use if you wish to apply configuration rules to certain package or lock files using patterns.
|
||||||
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:
|
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
|
```json
|
||||||
{
|
{
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"matchPaths": ["examples/**"],
|
"matchFileNames": ["examples/**"],
|
||||||
"extends": [":semanticCommitTypeAll(chore)"]
|
"extends": [":semanticCommitTypeAll(chore)"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchPaths` with a `minimatch` pattern or use [`matchFiles`](#matchfiles) with an exact match.
|
If you wish to limit Renovate to apply configuration rules to certain files in the root repository directory, you have to use `matchFileNames` with a `minimatch` pattern (which can include an exact file name match).
|
||||||
For example you have multiple `package.json` and want to use `dependencyDashboardApproval` only on the root `package.json`:
|
For example you have multiple `package.json` and want to use `dependencyDashboardApproval` only on the root `package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"matchFiles": ["package.json"],
|
"matchFileNames": ["package.json"],
|
||||||
"dependencyDashboardApproval": true
|
"dependencyDashboardApproval": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -2188,23 +2188,50 @@ Use the syntax `!/ /` like this:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### matchFiles
|
### matchFileNames
|
||||||
|
|
||||||
Renovate will compare `matchFiles` for an exact match against the dependency's package file or lock file.
|
Renovate will compare `matchFileNames` glob matching against the dependency's package file or lock file.
|
||||||
|
|
||||||
For example the following would match `package.json` but not `package/frontend/package.json`:
|
The following example matches `package.json` but _not_ `package/frontend/package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"matchFiles": ["package.json"]
|
"matchFileNames": ["package.json"],
|
||||||
|
"labels": ["npm"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Use [`matchPaths`](#matchpaths) instead if you need more flexible matching.
|
The following example matches any `package.json`, including files like `backend/package.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"description": "Group dependencies from package.json files",
|
||||||
|
"matchFileNames": ["**/package.json"],
|
||||||
|
"groupName": "All package.json changes"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example matches any file in directories starting with `app/`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"description": "Group all dependencies from the app directory",
|
||||||
|
"matchFileNames": ["app/**"],
|
||||||
|
"groupName": "App dependencies"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### matchDepNames
|
### matchDepNames
|
||||||
|
|
||||||
|
@ -2264,38 +2291,6 @@ See also `excludePackagePrefixes`.
|
||||||
|
|
||||||
Like the earlier `matchPackagePatterns` example, the above will configure `rangeStrategy` to `replace` for any package starting with `angular`.
|
Like the earlier `matchPackagePatterns` example, the above will configure `rangeStrategy` to `replace` for any package starting with `angular`.
|
||||||
|
|
||||||
### matchPaths
|
|
||||||
|
|
||||||
Renovate finds the file(s) listed in `matchPaths` with a `minimatch` glob pattern.
|
|
||||||
|
|
||||||
For example the following matches any `package.json`, including files like `backend/package.json`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"description": "Group dependencies from package.json files",
|
|
||||||
"matchPaths": ["**/package.json"],
|
|
||||||
"groupName": "All package.json changes"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The following matches any file in directories starting with `app/`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"description": "Group all dependencies from the app directory",
|
|
||||||
"matchPaths": ["app/**"],
|
|
||||||
"groupName": "App dependencies"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### matchSourceUrlPrefixes
|
### matchSourceUrlPrefixes
|
||||||
|
|
||||||
Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org:
|
Here's an example of where you use this to group together all packages from the `renovatebot` GitHub org:
|
||||||
|
|
|
@ -164,7 +164,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`
|
||||||
"extends": [
|
"extends": [
|
||||||
"node",
|
"node",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"node/**",
|
"node/**",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -211,7 +211,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`
|
||||||
"extends": [
|
"extends": [
|
||||||
"foo",
|
"foo",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"examples/**",
|
"examples/**",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -293,7 +293,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack
|
||||||
"matchDepTypes": [
|
"matchDepTypes": [
|
||||||
"devDependencies",
|
"devDependencies",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"package.json",
|
"package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "pin",
|
"rangeStrategy": "pin",
|
||||||
|
@ -302,7 +302,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates more pack
|
||||||
"matchDepTypes": [
|
"matchDepTypes": [
|
||||||
"dependencies",
|
"dependencies",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"package.json",
|
"package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "pin",
|
"rangeStrategy": "pin",
|
||||||
|
@ -332,13 +332,13 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi
|
||||||
],
|
],
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
{
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"backend/package.json",
|
"backend/package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "replace",
|
"rangeStrategy": "replace",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"frontend/package.json",
|
"frontend/package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "pin",
|
"rangeStrategy": "pin",
|
||||||
|
@ -347,7 +347,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi
|
||||||
"matchDepTypes": [
|
"matchDepTypes": [
|
||||||
"devDependencies",
|
"devDependencies",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"other/package.json",
|
"other/package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "pin",
|
"rangeStrategy": "pin",
|
||||||
|
@ -356,7 +356,7 @@ exports[`config/migration migrateConfig(config, parentConfig) migrates packageFi
|
||||||
"matchDepTypes": [
|
"matchDepTypes": [
|
||||||
"dependencies",
|
"dependencies",
|
||||||
],
|
],
|
||||||
"matchPaths": [
|
"matchFileNames": [
|
||||||
"other/package.json",
|
"other/package.json",
|
||||||
],
|
],
|
||||||
"rangeStrategy": "pin",
|
"rangeStrategy": "pin",
|
||||||
|
|
|
@ -568,13 +568,41 @@ describe('config/migration', () => {
|
||||||
matchManagers: ['dockerfile'],
|
matchManagers: ['dockerfile'],
|
||||||
matchPackageNames: ['foo'],
|
matchPackageNames: ['foo'],
|
||||||
matchPackagePatterns: ['^bar'],
|
matchPackagePatterns: ['^bar'],
|
||||||
matchPaths: ['package.json'],
|
matchFileNames: ['package.json'],
|
||||||
matchSourceUrlPrefixes: ['https://github.com/lodash'],
|
matchSourceUrlPrefixes: ['https://github.com/lodash'],
|
||||||
matchUpdateTypes: ['major'],
|
matchUpdateTypes: ['major'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('migrates in order of precedence', () => {
|
||||||
|
const config: TestRenovateConfig = {
|
||||||
|
packageRules: [
|
||||||
|
{
|
||||||
|
matchFiles: ['matchFiles'],
|
||||||
|
matchPaths: ['matchPaths'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matchPaths: ['matchPaths'],
|
||||||
|
matchFiles: ['matchFiles'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const { isMigrated, migratedConfig } =
|
||||||
|
configMigration.migrateConfig(config);
|
||||||
|
expect(isMigrated).toBeTrue();
|
||||||
|
expect(migratedConfig).toEqual({
|
||||||
|
packageRules: [
|
||||||
|
{
|
||||||
|
matchFileNames: ['matchPaths'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matchFileNames: ['matchFiles'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('it migrates nested packageRules', () => {
|
it('it migrates nested packageRules', () => {
|
||||||
|
|
|
@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-major-migration', () => {
|
||||||
{
|
{
|
||||||
automergeMajor: 'some-value',
|
automergeMajor: 'some-value',
|
||||||
major: {
|
major: {
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
major: {
|
major: {
|
||||||
automerge: true,
|
automerge: true,
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-minor-migration', () => {
|
||||||
{
|
{
|
||||||
automergeMinor: 'some-value',
|
automergeMinor: 'some-value',
|
||||||
minor: {
|
minor: {
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
minor: {
|
minor: {
|
||||||
automerge: true,
|
automerge: true,
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,13 +19,13 @@ describe('config/migrations/custom/automerge-patch-migration', () => {
|
||||||
{
|
{
|
||||||
automergePatch: 'some-value',
|
automergePatch: 'some-value',
|
||||||
patch: {
|
patch: {
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
patch: {
|
patch: {
|
||||||
automerge: true,
|
automerge: true,
|
||||||
matchFiles: ['test'],
|
matchFileNames: ['test'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe('config/migrations/custom/package-rules-migration', () => {
|
||||||
{
|
{
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
matchPaths: [],
|
matchFileNames: [],
|
||||||
packgageRules: {
|
packgageRules: {
|
||||||
languages: ['javascript'],
|
languages: ['javascript'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,9 @@ import type { PackageRule } from '../../types';
|
||||||
import { AbstractMigration } from '../base/abstract-migration';
|
import { AbstractMigration } from '../base/abstract-migration';
|
||||||
|
|
||||||
export const renameMap = {
|
export const renameMap = {
|
||||||
paths: 'matchPaths',
|
matchFiles: 'matchFileNames',
|
||||||
|
matchPaths: 'matchFileNames',
|
||||||
|
paths: 'matchFileNames',
|
||||||
languages: 'matchLanguages',
|
languages: 'matchLanguages',
|
||||||
baseBranchList: 'matchBaseBranches',
|
baseBranchList: 'matchBaseBranches',
|
||||||
managers: 'matchManagers',
|
managers: 'matchManagers',
|
||||||
|
|
|
@ -1321,7 +1321,7 @@ const options: RenovateOptions[] = [
|
||||||
env: false,
|
env: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'matchFiles',
|
name: 'matchFileNames',
|
||||||
description:
|
description:
|
||||||
'List of strings to do an exact match against package and lock files with full path. Only works inside a `packageRules` object.',
|
'List of strings to do an exact match against package and lock files with full path. Only works inside a `packageRules` object.',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
|
@ -1331,17 +1331,6 @@ const options: RenovateOptions[] = [
|
||||||
cli: false,
|
cli: false,
|
||||||
env: false,
|
env: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'matchPaths',
|
|
||||||
description:
|
|
||||||
'List of glob patterns to match against package files. Only works inside a `packageRules` object.',
|
|
||||||
type: 'array',
|
|
||||||
subType: 'string',
|
|
||||||
stage: 'repository',
|
|
||||||
parent: 'packageRules',
|
|
||||||
cli: false,
|
|
||||||
env: false,
|
|
||||||
},
|
|
||||||
// Version behaviour
|
// Version behaviour
|
||||||
{
|
{
|
||||||
name: 'allowedVersions',
|
name: 'allowedVersions',
|
||||||
|
|
|
@ -372,7 +372,7 @@ export const presets: Record<string, Preset> = {
|
||||||
'Use semanticCommitType `{{arg0}}` for all package files matching path `{{arg1}}`.',
|
'Use semanticCommitType `{{arg0}}` for all package files matching path `{{arg1}}`.',
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
matchPaths: ['{{arg0}}'],
|
matchFileNames: ['{{arg0}}'],
|
||||||
semanticCommitType: '{{arg1}}',
|
semanticCommitType: '{{arg1}}',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -318,8 +318,7 @@ export interface PackageRule
|
||||||
Record<string, unknown> {
|
Record<string, unknown> {
|
||||||
description?: string | string[];
|
description?: string | string[];
|
||||||
isVulnerabilityAlert?: boolean;
|
isVulnerabilityAlert?: boolean;
|
||||||
matchFiles?: string[];
|
matchFileNames?: string[];
|
||||||
matchPaths?: string[];
|
|
||||||
matchLanguages?: string[];
|
matchLanguages?: string[];
|
||||||
matchBaseBranches?: string[];
|
matchBaseBranches?: string[];
|
||||||
matchManagers?: string | string[];
|
matchManagers?: string | string[];
|
||||||
|
@ -464,6 +463,7 @@ export type RenovateOptions =
|
||||||
export interface PackageRuleInputConfig extends Record<string, unknown> {
|
export interface PackageRuleInputConfig extends Record<string, unknown> {
|
||||||
versioning?: string;
|
versioning?: string;
|
||||||
packageFile?: string;
|
packageFile?: string;
|
||||||
|
lockFiles?: string[];
|
||||||
depType?: string;
|
depType?: string;
|
||||||
depTypes?: string[];
|
depTypes?: string[];
|
||||||
depName?: string;
|
depName?: string;
|
||||||
|
|
|
@ -302,8 +302,7 @@ export async function validateConfig(
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectors = [
|
const selectors = [
|
||||||
'matchFiles',
|
'matchFileNames',
|
||||||
'matchPaths',
|
|
||||||
'matchLanguages',
|
'matchLanguages',
|
||||||
'matchBaseBranches',
|
'matchBaseBranches',
|
||||||
'matchManagers',
|
'matchManagers',
|
||||||
|
|
|
@ -64,7 +64,7 @@ export async function extractPackageFile(
|
||||||
const error = new Error(CONFIG_VALIDATION);
|
const error = new Error(CONFIG_VALIDATION);
|
||||||
error.validationSource = packageFile;
|
error.validationSource = packageFile;
|
||||||
error.validationError =
|
error.validationError =
|
||||||
'Nested package.json must not contain renovate configuration. Please use `packageRules` with `matchPaths` in your main config instead.';
|
'Nested package.json must not contain Renovate configuration. Please use `packageRules` with `matchFileNames` in your main config instead.';
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
const packageJsonName = packageJson.name;
|
const packageJsonName = packageJson.name;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { FilesMatcher } from './files';
|
import { FileNamesMatcher } from './files';
|
||||||
|
|
||||||
describe('util/package-rules/files', () => {
|
describe('util/package-rules/files', () => {
|
||||||
const fileMatcher = new FilesMatcher();
|
const fileMatcher = new FileNamesMatcher();
|
||||||
|
|
||||||
describe('match', () => {
|
describe('match', () => {
|
||||||
it('should return false if packageFile is not defined', () => {
|
it('should return false if packageFile is not defined', () => {
|
||||||
|
@ -10,7 +10,7 @@ describe('util/package-rules/files', () => {
|
||||||
packageFile: undefined,
|
packageFile: undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchFiles: ['frontend/package.json'],
|
matchFileNames: ['frontend/package.json'],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
expect(result).toBeFalse();
|
expect(result).toBeFalse();
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
import is from '@sindresorhus/is';
|
import is from '@sindresorhus/is';
|
||||||
|
import { minimatch } from 'minimatch';
|
||||||
import type { PackageRule, PackageRuleInputConfig } from '../../config/types';
|
import type { PackageRule, PackageRuleInputConfig } from '../../config/types';
|
||||||
import { Matcher } from './base';
|
import { Matcher } from './base';
|
||||||
|
|
||||||
export class FilesMatcher extends Matcher {
|
export class FileNamesMatcher extends Matcher {
|
||||||
override matches(
|
override matches(
|
||||||
{ packageFile, lockFiles }: PackageRuleInputConfig,
|
{ packageFile, lockFiles }: PackageRuleInputConfig,
|
||||||
{ matchFiles }: PackageRule
|
{ matchFileNames }: PackageRule
|
||||||
): boolean | null {
|
): boolean | null {
|
||||||
if (is.undefined(matchFiles)) {
|
if (is.undefined(matchFileNames)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (is.undefined(packageFile)) {
|
if (is.undefined(packageFile)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return matchFiles.some(
|
return matchFileNames.some(
|
||||||
(fileName) =>
|
(matchFileName) =>
|
||||||
packageFile === fileName ||
|
minimatch(packageFile, matchFileName, { dot: true }) ||
|
||||||
(is.array(lockFiles) && lockFiles?.includes(fileName))
|
(is.array(lockFiles) &&
|
||||||
|
lockFiles.some((lockFile) =>
|
||||||
|
minimatch(lockFile, matchFileName, { dot: true })
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -930,7 +930,7 @@ describe('util/package-rules/index', () => {
|
||||||
packageFile: 'examples/foo/package.json',
|
packageFile: 'examples/foo/package.json',
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
matchFiles: ['package.json'],
|
matchFileNames: ['package.json'],
|
||||||
x: 1,
|
x: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -954,7 +954,7 @@ describe('util/package-rules/index', () => {
|
||||||
lockFiles: ['yarn.lock'],
|
lockFiles: ['yarn.lock'],
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
matchFiles: ['yarn.lock'],
|
matchFileNames: ['yarn.lock'],
|
||||||
x: 1,
|
x: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -968,7 +968,7 @@ describe('util/package-rules/index', () => {
|
||||||
packageFile: 'examples/foo/package.json',
|
packageFile: 'examples/foo/package.json',
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
matchPaths: ['examples/**', 'lib/'],
|
matchFileNames: ['examples/**', 'lib/'],
|
||||||
x: 1,
|
x: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -5,14 +5,13 @@ import { DatasourcesMatcher } from './datasources';
|
||||||
import { DepNameMatcher } from './dep-names';
|
import { DepNameMatcher } from './dep-names';
|
||||||
import { DepPatternsMatcher } from './dep-patterns';
|
import { DepPatternsMatcher } from './dep-patterns';
|
||||||
import { DepTypesMatcher } from './dep-types';
|
import { DepTypesMatcher } from './dep-types';
|
||||||
import { FilesMatcher } from './files';
|
import { FileNamesMatcher } from './files';
|
||||||
import { LanguagesMatcher } from './languages';
|
import { LanguagesMatcher } from './languages';
|
||||||
import { ManagersMatcher } from './managers';
|
import { ManagersMatcher } from './managers';
|
||||||
import { MergeConfidenceMatcher } from './merge-confidence';
|
import { MergeConfidenceMatcher } from './merge-confidence';
|
||||||
import { PackageNameMatcher } from './package-names';
|
import { PackageNameMatcher } from './package-names';
|
||||||
import { PackagePatternsMatcher } from './package-patterns';
|
import { PackagePatternsMatcher } from './package-patterns';
|
||||||
import { PackagePrefixesMatcher } from './package-prefixes';
|
import { PackagePrefixesMatcher } from './package-prefixes';
|
||||||
import { PathsMatcher } from './paths';
|
|
||||||
import { SourceUrlPrefixesMatcher } from './sourceurl-prefixes';
|
import { SourceUrlPrefixesMatcher } from './sourceurl-prefixes';
|
||||||
import { SourceUrlsMatcher } from './sourceurls';
|
import { SourceUrlsMatcher } from './sourceurls';
|
||||||
import type { MatcherApi } from './types';
|
import type { MatcherApi } from './types';
|
||||||
|
@ -29,8 +28,7 @@ matchers.push([
|
||||||
new PackagePatternsMatcher(),
|
new PackagePatternsMatcher(),
|
||||||
new PackagePrefixesMatcher(),
|
new PackagePrefixesMatcher(),
|
||||||
]);
|
]);
|
||||||
matchers.push([new FilesMatcher()]);
|
matchers.push([new FileNamesMatcher()]);
|
||||||
matchers.push([new PathsMatcher()]);
|
|
||||||
matchers.push([new DepTypesMatcher()]);
|
matchers.push([new DepTypesMatcher()]);
|
||||||
matchers.push([new LanguagesMatcher()]);
|
matchers.push([new LanguagesMatcher()]);
|
||||||
matchers.push([new BaseBranchesMatcher()]);
|
matchers.push([new BaseBranchesMatcher()]);
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
import { logger } from '../../logger';
|
|
||||||
import { PathsMatcher } from './paths';
|
|
||||||
|
|
||||||
describe('util/package-rules/paths', () => {
|
|
||||||
const pathsMatcher = new PathsMatcher();
|
|
||||||
|
|
||||||
describe('match', () => {
|
|
||||||
it('should return false if packageFile is not defined', () => {
|
|
||||||
const result = pathsMatcher.matches(
|
|
||||||
{
|
|
||||||
packageFile: undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
matchPaths: ['opentelemetry/http'],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result).toBeFalse();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return false on partial match only', () => {
|
|
||||||
const result = pathsMatcher.matches(
|
|
||||||
{
|
|
||||||
packageFile: 'opentelemetry/http/package.json',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
matchPaths: ['opentelemetry/http'],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result).toBeFalse();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return true and not log warning on partial and glob match', () => {
|
|
||||||
const result = pathsMatcher.matches(
|
|
||||||
{
|
|
||||||
packageFile: 'package.json',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
matchPaths: ['package.json'],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
expect(result).toBeTrue();
|
|
||||||
expect(logger.warn).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,22 +0,0 @@
|
||||||
import is from '@sindresorhus/is';
|
|
||||||
import { minimatch } from 'minimatch';
|
|
||||||
import type { PackageRule, PackageRuleInputConfig } from '../../config/types';
|
|
||||||
import { Matcher } from './base';
|
|
||||||
|
|
||||||
export class PathsMatcher extends Matcher {
|
|
||||||
override matches(
|
|
||||||
{ packageFile }: PackageRuleInputConfig,
|
|
||||||
{ matchPaths }: PackageRule
|
|
||||||
): boolean | null {
|
|
||||||
if (is.undefined(matchPaths)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (is.undefined(packageFile)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return matchPaths.some((rulePath) =>
|
|
||||||
minimatch(packageFile, rulePath, { dot: true })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur
|
||||||
"matchDatasources": [
|
"matchDatasources": [
|
||||||
"npm",
|
"npm",
|
||||||
],
|
],
|
||||||
"matchFiles": [
|
"matchFileNames": [
|
||||||
"backend/package-lock.json",
|
"backend/package-lock.json",
|
||||||
],
|
],
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
|
@ -31,7 +31,7 @@ exports[`workers/repository/init/vulnerability detectVulnerabilityAlerts() retur
|
||||||
"matchDatasources": [
|
"matchDatasources": [
|
||||||
"go",
|
"go",
|
||||||
],
|
],
|
||||||
"matchFiles": [
|
"matchFileNames": [
|
||||||
"go.mod",
|
"go.mod",
|
||||||
],
|
],
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
|
@ -61,7 +61,7 @@ go",
|
||||||
"matchDatasources": [
|
"matchDatasources": [
|
||||||
"github-tags",
|
"github-tags",
|
||||||
],
|
],
|
||||||
"matchFiles": [
|
"matchFileNames": [
|
||||||
".github/workflows/build.yaml",
|
".github/workflows/build.yaml",
|
||||||
],
|
],
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
|
@ -91,7 +91,7 @@ actions",
|
||||||
"matchDatasources": [
|
"matchDatasources": [
|
||||||
"pypi",
|
"pypi",
|
||||||
],
|
],
|
||||||
"matchFiles": [
|
"matchFileNames": [
|
||||||
"requirements.txt",
|
"requirements.txt",
|
||||||
],
|
],
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
|
@ -136,7 +136,7 @@ Ansible before versions 2.1.4, 2.2.1 is vulnerable to an improper input validati
|
||||||
"matchDatasources": [
|
"matchDatasources": [
|
||||||
"maven",
|
"maven",
|
||||||
],
|
],
|
||||||
"matchFiles": [
|
"matchFileNames": [
|
||||||
"pom.xml",
|
"pom.xml",
|
||||||
],
|
],
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
|
|
|
@ -328,7 +328,7 @@ describe('workers/repository/init/vulnerability', () => {
|
||||||
const res = await detectVulnerabilityAlerts(config);
|
const res = await detectVulnerabilityAlerts(config);
|
||||||
expect(res.packageRules).toMatchSnapshot();
|
expect(res.packageRules).toMatchSnapshot();
|
||||||
expect(res.packageRules).toHaveLength(5);
|
expect(res.packageRules).toHaveLength(5);
|
||||||
expect(res.packageRules?.[1]?.matchFiles?.[0]).toBe('go.mod');
|
expect(res.packageRules?.[1]?.matchFileNames?.[0]).toBe('go.mod');
|
||||||
expect(res.packageRules?.[2]?.matchCurrentVersion).toBe('1.8.2');
|
expect(res.packageRules?.[2]?.matchCurrentVersion).toBe('1.8.2');
|
||||||
expect(res.remediations).toMatchSnapshot({
|
expect(res.remediations).toMatchSnapshot({
|
||||||
'backend/package-lock.json': [
|
'backend/package-lock.json': [
|
||||||
|
|
|
@ -208,7 +208,7 @@ export async function detectVulnerabilityAlerts(
|
||||||
datasource === PypiDatasource.id
|
datasource === PypiDatasource.id
|
||||||
? `==${val.firstPatchedVersion!}`
|
? `==${val.firstPatchedVersion!}`
|
||||||
: val.firstPatchedVersion;
|
: val.firstPatchedVersion;
|
||||||
const matchFiles =
|
const matchFileNames =
|
||||||
datasource === GoDatasource.id
|
datasource === GoDatasource.id
|
||||||
? [fileName.replace('go.sum', 'go.mod')]
|
? [fileName.replace('go.sum', 'go.mod')]
|
||||||
: [fileName];
|
: [fileName];
|
||||||
|
@ -216,7 +216,7 @@ export async function detectVulnerabilityAlerts(
|
||||||
matchDatasources: [datasource],
|
matchDatasources: [datasource],
|
||||||
matchPackageNames: [depName],
|
matchPackageNames: [depName],
|
||||||
matchCurrentVersion,
|
matchCurrentVersion,
|
||||||
matchFiles,
|
matchFileNames,
|
||||||
};
|
};
|
||||||
const supportedRemediationFileTypes = ['package-lock.json'];
|
const supportedRemediationFileTypes = ['package-lock.json'];
|
||||||
if (
|
if (
|
||||||
|
@ -252,7 +252,7 @@ export async function detectVulnerabilityAlerts(
|
||||||
// istanbul ignore if
|
// istanbul ignore if
|
||||||
if (
|
if (
|
||||||
config.transitiveRemediation &&
|
config.transitiveRemediation &&
|
||||||
matchRule.matchFiles?.[0] === 'package.json'
|
matchRule.matchFileNames?.[0] === 'package.json'
|
||||||
) {
|
) {
|
||||||
matchRule.force!.rangeStrategy = 'replace';
|
matchRule.force!.rangeStrategy = 'replace';
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ describe('workers/repository/updates/flatten', () => {
|
||||||
automerge: true,
|
automerge: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchPaths: ['frontend/package.json'],
|
matchFileNames: ['frontend/package.json'],
|
||||||
lockFileMaintenance: {
|
lockFileMaintenance: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue