Skip to content

Commit

Permalink
feat(manager): add renovate config presets manager
Browse files Browse the repository at this point in the history
  • Loading branch information
risu729 committed Nov 23, 2024
1 parent 021db4b commit 6c16839
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/modules/manager/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import * as preCommit from './pre-commit';
import * as pub from './pub';
import * as puppet from './puppet';
import * as pyenv from './pyenv';
import * as renovateConfigPresets from './renovate-config-presets';

Check failure on line 85 in lib/modules/manager/api.ts

View workflow job for this annotation

GitHub Actions / lint-eslint

Dependency cycle via ./extract:6=>../../../config/presets:3=>../massage:15=>./options:3=>../../modules/manager:1

Check warning on line 85 in lib/modules/manager/api.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/api.ts#L85

Added line #L85 was not covered by tests
import * as rubyVersion from './ruby-version';
import * as runtimeVersion from './runtime-version';
import * as sbt from './sbt';
Expand Down Expand Up @@ -188,6 +189,7 @@ api.set('pre-commit', preCommit);
api.set('pub', pub);
api.set('puppet', puppet);
api.set('pyenv', pyenv);
api.set('renovate-config-presets', renovateConfigPresets);

Check warning on line 192 in lib/modules/manager/api.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/api.ts#L192

Added line #L192 was not covered by tests
api.set('ruby-version', rubyVersion);
api.set('runtime-version', runtimeVersion);
api.set('sbt', sbt);
Expand Down
233 changes: 233 additions & 0 deletions lib/modules/manager/renovate-config-presets/extract.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { codeBlock } from 'common-tags';
import { extractPackageFile } from '.';

const noPresets = codeBlock`
{
"draftPR": true
}
`;

const builtInPresets = codeBlock`
{
"extends": ["config:recommended", ":label(test)", "helpers:pinGitHubActionDigests"]
}
`;

const unsupportedPresets = codeBlock`
{
"extends": [
"fastcore",
"http://my.server/users/me/repos/renovate-presets/raw/default.json",
"local>renovate/presets",
"local>renovate/presets2#1.2.3"
]
}
`;

const presetsWithoutVersions = codeBlock`
{
"extends": [
"github>abc/foo",
"gitlab>abc/bar:xyz",
"gitea>cde/foo//path/xyz"
]
}
`;

const githubPresets = codeBlock`
{
"extends": [
"github>abc/foo#1.2.3",
"github>abc/bar:xyz#1.2.3",
"github>cde/foo//path/xyz#1.2.3",
"github>cde/bar:xyz/sub#1.2.3"
]
}
`;

const gitlabPresets = codeBlock`
{
"extends": [
"gitlab>abc/foo#1.2.3",
"gitlab>abc/bar:xyz#1.2.3",
"gitlab>cde/foo//path/xyz#1.2.3",
"gitlab>cde/bar:xyz/sub#1.2.3"
]
}
`;

const giteaPresets = codeBlock`
{
"extends": [
"gitea>abc/foo#1.2.3",
"gitea>abc/bar:xyz#1.2.3",
"gitea>cde/foo//path/xyz#1.2.3",
"gitea>cde/bar:xyz/sub#1.2.3"
]
}
`;

const json5Config = codeBlock`
{
// comments are permitted
"extends": [
"github>abc/foo#1.2.3",
],
}
`;

describe('modules/manager/renovate-config-presets/extract', () => {
describe('extractPackageFile()', () => {
it('returns null for empty file', () => {
expect(extractPackageFile('', '')).toBeNull();
});

it('returns null for invalid file', () => {
expect(extractPackageFile('this-is-not-json', '')).toBeNull();
});

it('returns null for a config file without presets', () => {
expect(extractPackageFile(noPresets, '')).toBeNull();
});

it('returns null for a config file only contains built-in presets', () => {
expect(extractPackageFile(builtInPresets, '')).toBeNull();
});

it('provides skipReason for unsupported preset sources', () => {
expect(extractPackageFile(unsupportedPresets, '')).toEqual({
deps: [
{
depName: 'renovate-config-fastcore',
skipReason: 'unsupported-datasource',
},
{
depName:
'http://my.server/users/me/repos/renovate-presets/raw/default.json',
skipReason: 'unsupported-datasource',
},
{
depName: 'renovate/presets',
skipReason: 'unsupported-datasource',
},
{
depName: 'renovate/presets2',
skipReason: 'unsupported-datasource',
},
],
});
});

it('provides skipReason for presets without versions', () => {
expect(extractPackageFile(presetsWithoutVersions, '')).toEqual({
deps: [
{
depName: 'abc/foo',
skipReason: 'unspecified-version',
},
{
depName: 'abc/bar',
skipReason: 'unspecified-version',
},
{
depName: 'cde/foo',
skipReason: 'unspecified-version',
},
],
});
});

it('extracts from a config file with GitHub hosted presets', () => {
expect(extractPackageFile(githubPresets, '')).toEqual({
deps: [
{
datasource: 'github-tags',
depName: 'abc/foo',
currentValue: '1.2.3',
},
{
datasource: 'github-tags',
depName: 'abc/bar',
currentValue: '1.2.3',
},
{
datasource: 'github-tags',
depName: 'cde/foo',
currentValue: '1.2.3',
},
{
datasource: 'github-tags',
depName: 'cde/bar',
currentValue: '1.2.3',
},
],
});
});

it('extracts from a config file with GitLab hosted presets', () => {
expect(extractPackageFile(gitlabPresets, '')).toEqual({
deps: [
{
datasource: 'gitlab-tags',
depName: 'abc/foo',
currentValue: '1.2.3',
},
{
datasource: 'gitlab-tags',
depName: 'abc/bar',
currentValue: '1.2.3',
},
{
datasource: 'gitlab-tags',
depName: 'cde/foo',
currentValue: '1.2.3',
},
{
datasource: 'gitlab-tags',
depName: 'cde/bar',
currentValue: '1.2.3',
},
],
});
});

it('extracts from a config file with Gitea hosted presets', () => {
expect(extractPackageFile(giteaPresets, '')).toEqual({
deps: [
{
datasource: 'gitea-tags',
depName: 'abc/foo',
currentValue: '1.2.3',
},
{
datasource: 'gitea-tags',
depName: 'abc/bar',
currentValue: '1.2.3',
},
{
datasource: 'gitea-tags',
depName: 'cde/foo',
currentValue: '1.2.3',
},
{
datasource: 'gitea-tags',
depName: 'cde/bar',
currentValue: '1.2.3',
},
],
});
});

it('supports JSON5', () => {
expect(extractPackageFile(json5Config, '')).toEqual({
deps: [
{
datasource: 'github-tags',
depName: 'abc/foo',
currentValue: '1.2.3',
},
],
});
});
});
});
82 changes: 82 additions & 0 deletions lib/modules/manager/renovate-config-presets/extract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import is from '@sindresorhus/is';
import JSON5 from 'json5';
import { parsePreset } from '../../../config/presets';

Check failure on line 3 in lib/modules/manager/renovate-config-presets/extract.ts

View workflow job for this annotation

GitHub Actions / lint-eslint

Dependency cycle via ../massage:15=>./options:3=>../../modules/manager:1=>./api:2=>./renovate-config-presets:85

Check warning on line 3 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L1-L3

Added lines #L1 - L3 were not covered by tests
import type { RenovateConfig } from '../../../config/types';
import { logger } from '../../../logger';
import { GiteaTagsDatasource } from '../../datasource/gitea-tags';
import { GithubTagsDatasource } from '../../datasource/github-tags';
import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';

Check warning on line 8 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L5-L8

Added lines #L5 - L8 were not covered by tests
import type { PackageDependency, PackageFileContent } from '../types';

const supportedPresetSources: {
source: string;
datasource: string;
}[] = [

Check warning on line 14 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L14

Added line #L14 was not covered by tests
{
source: 'github',
datasource: GithubTagsDatasource.id,
},
{
source: 'gitlab',
datasource: GitlabTagsDatasource.id,
},
{
source: 'gitea',
datasource: GiteaTagsDatasource.id,
},
];

export function extractPackageFile(

Check warning on line 29 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L29

Added line #L29 was not covered by tests
content: string,
packageFile: string,
): PackageFileContent | null {
logger.trace(`renovate-config-presets.extractPackageFile(${packageFile})`);

Check warning on line 33 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L33

Added line #L33 was not covered by tests
let config: RenovateConfig;
try {
config = JSON5.parse<RenovateConfig>(content);

Check warning on line 36 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L35-L36

Added lines #L35 - L36 were not covered by tests
} catch {
logger.debug({ packageFile }, 'Invalid JSON5');
return null;

Check warning on line 39 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L38-L39

Added lines #L38 - L39 were not covered by tests
}

const deps: PackageDependency[] = [];

Check warning on line 42 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L42

Added line #L42 was not covered by tests

for (const preset of config.extends ?? []) {
const parsedPreset = parsePreset(preset);

Check warning on line 45 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L45

Added line #L45 was not covered by tests
if (
!supportedPresetSources.some(
(source) => source.source === parsedPreset.presetSource,

Check warning on line 48 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L48

Added line #L48 was not covered by tests
)
) {
if (parsedPreset.presetSource !== 'internal') {
deps.push({

Check warning on line 52 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L52

Added line #L52 was not covered by tests
depName: parsedPreset.repo,
skipReason: 'unsupported-datasource',
});
}
continue;

Check warning on line 57 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L57

Added line #L57 was not covered by tests
}

if (is.nullOrUndefined(parsedPreset.tag)) {
deps.push({

Check warning on line 61 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L61

Added line #L61 was not covered by tests
depName: parsedPreset.repo,
skipReason: 'unspecified-version',
});
continue;

Check warning on line 65 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L65

Added line #L65 was not covered by tests
}

const datasource = supportedPresetSources.find(
(source) => source.source === parsedPreset.presetSource,

Check warning on line 69 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L68-L69

Added lines #L68 - L69 were not covered by tests
)?.datasource;
if (!datasource) {
throw new Error(`Datasource not found for ${parsedPreset.presetSource}`);

Check warning on line 72 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L72

Added line #L72 was not covered by tests
}
deps.push({

Check warning on line 74 in lib/modules/manager/renovate-config-presets/extract.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/extract.ts#L74

Added line #L74 was not covered by tests
depName: parsedPreset.repo,
datasource,
currentValue: parsedPreset.tag,
});
}

return is.nonEmptyArray(deps) ? { deps } : null;
}
20 changes: 20 additions & 0 deletions lib/modules/manager/renovate-config-presets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { configFileNames } from '../../../config/app-strings';
import { GiteaTagsDatasource } from '../../datasource/gitea-tags';
import { GithubTagsDatasource } from '../../datasource/github-tags';
import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';

Check warning on line 4 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L1-L4

Added lines #L1 - L4 were not covered by tests

export { extractPackageFile } from './extract';

Check failure on line 6 in lib/modules/manager/renovate-config-presets/index.ts

View workflow job for this annotation

GitHub Actions / lint-eslint

Dependency cycle via ../../../config/presets:3=>../massage:15=>./options:3=>../../modules/manager:1=>./api:2

Check warning on line 6 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L6

Added line #L6 was not covered by tests

export const url = 'https://docs.renovatebot.com/config-presets/';

Check warning on line 8 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L8

Added line #L8 was not covered by tests

export const defaultConfig = {

Check warning on line 10 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L10

Added line #L10 was not covered by tests
fileMatch: configFileNames
.filter((name) => name !== 'package.json')
.map((name) => `^${name.replaceAll('.', '\\.')}$`),

Check warning on line 13 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L12-L13

Added lines #L12 - L13 were not covered by tests
};

export const supportedDatasources = [

Check warning on line 16 in lib/modules/manager/renovate-config-presets/index.ts

View check run for this annotation

Codecov / codecov/patch

lib/modules/manager/renovate-config-presets/index.ts#L16

Added line #L16 was not covered by tests
GithubTagsDatasource.id,
GitlabTagsDatasource.id,
GiteaTagsDatasource.id,
];
7 changes: 7 additions & 0 deletions lib/modules/manager/renovate-config-presets/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Unsupported Config

- [Local presets](https://docs.renovatebot.com/config-presets/#local-presets)
- [HTTP URLs presets](https://docs.renovatebot.com/config-presets/#fetching-presets-from-an-http-server)
- [`package.json` file config](https://docs.renovatebot.com/configuration-options/) (deprecated)
- [`npm` hosted presets](https://docs.renovatebot.com/config-presets/#npm-hosted-presets) (deprecated)
- `package.json` hosted presets (deprecated)

0 comments on commit 6c16839

Please sign in to comment.