Skip to content

Commit

Permalink
feat(package-rules): add DepNamePrefix matcher (#28542)
Browse files Browse the repository at this point in the history
Co-authored-by: Rhys Arkins <rhys@arkins.net>
  • Loading branch information
yinm and rarkins committed Apr 20, 2024
1 parent 99c99f0 commit 7b66b9f
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -2510,6 +2510,8 @@ Invalid if used outside of a `packageRule`.

### excludeDepPatterns

### excludeDepPrefixes

### excludePackageNames

**Important**: Do not mix this up with the option `ignoreDeps`.
Expand Down Expand Up @@ -2830,6 +2832,8 @@ It is recommended that you avoid using "negative" globs, like `**/!(package.json

### matchDepPatterns

### matchDepPrefixes

### matchNewValue

This option is matched against the `newValue` field of a dependency.
Expand Down
28 changes: 28 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1375,6 +1375,34 @@ const options: RenovateOptions[] = [
cli: false,
env: false,
},
{
name: 'matchDepPrefixes',
description:
'Dep names prefixes to match. Valid only within a `packageRules` object.',
type: 'array',
subType: 'string',
allowString: true,
stage: 'package',
parents: ['packageRules'],
mergeable: true,
cli: false,
env: false,
advancedUse: true,
},
{
name: 'excludeDepPrefixes',
description:
'Dep names prefixes to exclude. Valid only within a `packageRules` object.',
type: 'array',
subType: 'string',
allowString: true,
stage: 'package',
parents: ['packageRules'],
mergeable: true,
cli: false,
env: false,
advancedUse: true,
},
{
name: 'matchPackagePatterns',
description:
Expand Down
2 changes: 2 additions & 0 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ export interface PackageRule
description?: string | string[];
excludeDepNames?: string[];
excludeDepPatterns?: string[];
excludeDepPrefixes?: string[];
excludePackageNames?: string[];
excludePackagePatterns?: string[];
excludePackagePrefixes?: string[];
Expand All @@ -367,6 +368,7 @@ export interface PackageRule
matchDatasources?: string[];
matchDepNames?: string[];
matchDepPatterns?: string[];
matchDepPrefixes?: string[];
matchDepTypes?: string[];
matchFileNames?: string[];
matchManagers?: string[];
Expand Down
2 changes: 2 additions & 0 deletions lib/config/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,13 @@ export async function validateConfig(
'matchDepTypes',
'matchDepNames',
'matchDepPatterns',
'matchDepPrefixes',
'matchPackageNames',
'matchPackagePatterns',
'matchPackagePrefixes',
'excludeDepNames',
'excludeDepPatterns',
'excludeDepPrefixes',
'excludePackageNames',
'excludePackagePatterns',
'excludePackagePrefixes',
Expand Down
105 changes: 105 additions & 0 deletions lib/util/package-rules/dep-prefixes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { DepPrefixesMatcher } from './dep-prefixes';

describe('util/package-rules/dep-prefixes', () => {
const depPrefixesMatcher = new DepPrefixesMatcher();

describe('match', () => {
it('should return null if matchDepPrefixes is not defined', () => {
const result = depPrefixesMatcher.matches(
{
depName: 'abc1',
},
{
matchDepPrefixes: undefined,
},
);
expect(result).toBeNull();
});

it('should return false if depName is not defined', () => {
const result = depPrefixesMatcher.matches(
{
depName: undefined,
},
{
matchDepPrefixes: ['@opentelemetry'],
},
);
expect(result).toBeFalse();
});

it('should return true if depName matched', () => {
const result = depPrefixesMatcher.matches(
{
depName: 'abc1',
},
{
matchDepPrefixes: ['abc'],
},
);
expect(result).toBeTrue();
});

it('should return false if depName does not match', () => {
const result = depPrefixesMatcher.matches(
{
depName: 'abc1',
},
{
matchDepPrefixes: ['def'],
},
);
expect(result).toBeFalse();
});
});

describe('exclude', () => {
it('should return null if excludeDepPrefixes is not defined', () => {
const result = depPrefixesMatcher.excludes(
{
depName: 'abc1',
},
{
excludeDepPrefixes: undefined,
},
);
expect(result).toBeNull();
});

it('should return false if depName is not defined', () => {
const result = depPrefixesMatcher.excludes(
{
depName: undefined,
},
{
excludeDepPrefixes: ['@opentelemetry'],
},
);
expect(result).toBeFalse();
});

it('should return true if depName matched', () => {
const result = depPrefixesMatcher.excludes(
{
depName: 'abc1',
},
{
excludeDepPrefixes: ['abc'],
},
);
expect(result).toBeTrue();
});

it('should return false if depName does not match', () => {
const result = depPrefixesMatcher.excludes(
{
depName: 'abc1',
},
{
excludeDepPrefixes: ['def'],
},
);
expect(result).toBeFalse();
});
});
});
35 changes: 35 additions & 0 deletions lib/util/package-rules/dep-prefixes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import is from '@sindresorhus/is';
import type { PackageRule, PackageRuleInputConfig } from '../../config/types';
import { Matcher } from './base';

export class DepPrefixesMatcher extends Matcher {
override matches(
{ depName }: PackageRuleInputConfig,
{ matchDepPrefixes }: PackageRule,
): boolean | null {
if (is.undefined(matchDepPrefixes)) {
return null;
}

if (is.undefined(depName)) {
return false;
}

return matchDepPrefixes.some((prefix) => depName.startsWith(prefix));
}

override excludes(
{ depName }: PackageRuleInputConfig,
{ excludeDepPrefixes }: PackageRule,
): boolean | null {
if (is.undefined(excludeDepPrefixes)) {
return null;
}

if (is.undefined(depName)) {
return false;
}

return excludeDepPrefixes.some((prefix) => depName.startsWith(prefix));
}
}
48 changes: 48 additions & 0 deletions lib/util/package-rules/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1230,4 +1230,52 @@ describe('util/package-rules/index', () => {
expect(res1.x).toBeUndefined();
expect(res2.x).toBe(1);
});

it('matches matchDepPrefixes(depName)', () => {
const config: TestConfig = {
packageRules: [
{
matchDepPrefixes: ['abc'],
x: 1,
},
],
};

const res1 = applyPackageRules({
...config,
depName: 'abc1',
});
const res2 = applyPackageRules({
...config,
depName: 'def1',
});
applyPackageRules(config); // coverage

expect(res1.x).toBe(1);
expect(res2.x).toBeUndefined();
});

it('matches excludeDepPrefixes(depName)', () => {
const config: TestConfig = {
packageRules: [
{
excludeDepPrefixes: ['abc'],
x: 1,
},
],
};

const res1 = applyPackageRules({
...config,
depName: 'abc1',
});
const res2 = applyPackageRules({
...config,
depName: 'def1',
});
applyPackageRules(config); // coverage

expect(res1.x).toBeUndefined();
expect(res2.x).toBe(1);
});
});
2 changes: 2 additions & 0 deletions lib/util/package-rules/matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CurrentVersionMatcher } from './current-version';
import { DatasourcesMatcher } from './datasources';
import { DepNameMatcher } from './dep-names';
import { DepPatternsMatcher } from './dep-patterns';
import { DepPrefixesMatcher } from './dep-prefixes';
import { DepTypesMatcher } from './dep-types';
import { FileNamesMatcher } from './files';
import { ManagersMatcher } from './managers';
Expand All @@ -32,6 +33,7 @@ matchers.push([new MergeConfidenceMatcher()]);
matchers.push([
new DepNameMatcher(),
new DepPatternsMatcher(),
new DepPrefixesMatcher(),
new PackageNameMatcher(),
new PackagePatternsMatcher(),
new PackagePrefixesMatcher(),
Expand Down

0 comments on commit 7b66b9f

Please sign in to comment.