mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 15:01:49 +00:00
feat(manager/bazel): recognize Bazel rules that begin with an underscore (#24496)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
This commit is contained in:
+6
-2
@@ -154,14 +154,18 @@ Renovate ignores [`multiple_version_override`](https://bazel.build/rules/lib/glo
|
||||
|
||||
## Legacy `WORKSPACE` files
|
||||
|
||||
Renovate extracts dependencies from:
|
||||
Renovate extracts dependencies from the following repository rules:
|
||||
|
||||
- `container_pull`
|
||||
- `oci_pull`
|
||||
- `git_repository`
|
||||
- `go_repository`
|
||||
- `maven_install`
|
||||
- `http_archive` or `http_file` declarations
|
||||
- `http_archive`
|
||||
- `http_file`
|
||||
|
||||
It also recognizes when these repository rule names are prefixed with an
|
||||
underscore. For example, `_http_archive` is treated the same as `http_archive`.
|
||||
|
||||
### `git_repository`
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive = "http_archive")
|
||||
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
||||
|
||||
http_archive(
|
||||
_http_archive(
|
||||
name = "GBDeviceInfo",
|
||||
url = "https://github.com/lmirosevic/GBDeviceInfo/archive/6.3.0.tar.gz",
|
||||
sha256 = "d7666275dff039407ea467c3083b83e24934101777c8b55b6b1b3b7e9a9e220b",
|
||||
strip_prefix = "GBDeviceInfo-6.3.0/GBDeviceInfo"
|
||||
)
|
||||
|
||||
http_archive(
|
||||
_http_archive(
|
||||
name = "com_github_nelhage_rules_boost",
|
||||
url = "https://github.com/nelhage/rules_boost/archive/135d46b4c9423ee7d494c78a21ff621bc73c12f3.tar.gz",
|
||||
sha256 = "3651f5dda0f7296e4cecafacc7f9d1f274be0fd64e30bebd74e28ffba28fe77f",
|
||||
@@ -17,14 +17,14 @@ http_archive(
|
||||
load("@com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
|
||||
boost_deps()
|
||||
|
||||
http_archive(
|
||||
_http_archive(
|
||||
name = "GBDeviceInfo-zip",
|
||||
url = "https://github.com/lmirosevic/GBDeviceInfo/archive/6.3.0.zip",
|
||||
sha256 = "4ef4320c4880fd64cfb7f42132f4b02fa626bccf1ba3e1a71dfbfcb50735f141",
|
||||
strip_prefix = "GBDeviceInfo-6.3.0/GBDeviceInfo"
|
||||
)
|
||||
|
||||
http_archive(
|
||||
_http_archive(
|
||||
name = "com_github_nelhage_rules_boost-zip",
|
||||
url = "https://github.com/nelhage/rules_boost/archive/135d46b4c9423ee7d494c78a21ff621bc73c12f3.zip",
|
||||
sha256 = "de8aac034cabe4a9ba5f7a33b9523862bf76c245a6c554c0e737f591bb7c7aeb",
|
||||
@@ -32,7 +32,7 @@ http_archive(
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
_http_archive,
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
|
||||
url = "https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
|
||||
|
||||
@@ -276,6 +276,61 @@ describe('modules/manager/bazel/artifacts', () => {
|
||||
expect(res).toBeNull();
|
||||
});
|
||||
|
||||
it('errors for _http_archive without urls', async () => {
|
||||
const input = codeBlock`
|
||||
_http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
|
||||
strip_prefix = "bazel-skylib-0.5.0",
|
||||
)
|
||||
`;
|
||||
|
||||
const upgrade = {
|
||||
depName: 'bazel_skylib',
|
||||
depType: 'http_archive',
|
||||
repo: 'bazelbuild/bazel-skylib',
|
||||
managerData: { idx: 0 },
|
||||
currentValue: '0.5.0',
|
||||
newValue: '0.6.2',
|
||||
};
|
||||
const res = await updateArtifacts(
|
||||
partial<UpdateArtifact>({
|
||||
packageFileName: 'WORKSPACE',
|
||||
updatedDeps: [upgrade],
|
||||
newPackageFileContent: input,
|
||||
})
|
||||
);
|
||||
expect(res).toBeNull();
|
||||
});
|
||||
|
||||
it('errors for maybe(_http_archive) without urls', async () => {
|
||||
const input = codeBlock`
|
||||
maybe(
|
||||
_http_archive,
|
||||
name = "bazel_skylib",
|
||||
sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f",
|
||||
strip_prefix = "bazel-skylib-0.5.0",
|
||||
)
|
||||
`;
|
||||
|
||||
const upgrade = {
|
||||
depName: 'bazel_skylib',
|
||||
depType: 'http_archive',
|
||||
repo: 'bazelbuild/bazel-skylib',
|
||||
managerData: { idx: 0 },
|
||||
currentValue: '0.5.0',
|
||||
newValue: '0.6.2',
|
||||
};
|
||||
const res = await updateArtifacts(
|
||||
partial<UpdateArtifact>({
|
||||
packageFileName: 'WORKSPACE',
|
||||
updatedDeps: [upgrade],
|
||||
newPackageFileContent: input,
|
||||
})
|
||||
);
|
||||
expect(res).toBeNull();
|
||||
});
|
||||
|
||||
it('updates http_archive with urls array', async () => {
|
||||
const inputHash =
|
||||
'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
|
||||
@@ -410,6 +465,140 @@ describe('modules/manager/bazel/artifacts', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('updates _http_archive with urls array', async () => {
|
||||
const inputHash =
|
||||
'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
|
||||
const input = codeBlock`
|
||||
_http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "${inputHash}",
|
||||
strip_prefix = "bazel-skylib-0.5.0",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
],
|
||||
)
|
||||
`;
|
||||
|
||||
const currentValue = '0.5.0';
|
||||
const newValue = '0.6.2';
|
||||
const upgrade = {
|
||||
depName: 'bazel_skylib',
|
||||
depType: 'http_archive',
|
||||
repo: 'bazelbuild/bazel-skylib',
|
||||
managerData: { idx: 0 },
|
||||
currentValue,
|
||||
newValue,
|
||||
};
|
||||
|
||||
const tarContent = Buffer.from('foo');
|
||||
const outputHash = crypto
|
||||
.createHash('sha256')
|
||||
.update(tarContent)
|
||||
.digest('hex');
|
||||
|
||||
const output = input
|
||||
.replace(currentValue, newValue)
|
||||
.replace(currentValue, newValue)
|
||||
.replace(currentValue, newValue)
|
||||
.replace(inputHash, outputHash);
|
||||
|
||||
httpMock
|
||||
.scope('https://github.com')
|
||||
.get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
|
||||
.reply(200, tarContent);
|
||||
|
||||
httpMock
|
||||
.scope('https://mirror.bazel.build')
|
||||
.get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
|
||||
.reply(200, tarContent);
|
||||
|
||||
const res = await updateArtifacts(
|
||||
partial<UpdateArtifact>({
|
||||
packageFileName: 'WORKSPACE',
|
||||
updatedDeps: [upgrade],
|
||||
newPackageFileContent: input,
|
||||
})
|
||||
);
|
||||
|
||||
expect(res).toEqual([
|
||||
{
|
||||
file: {
|
||||
contents: output,
|
||||
path: 'WORKSPACE',
|
||||
type: 'addition',
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('updates maybe(_http_archive) with urls array', async () => {
|
||||
const inputHash =
|
||||
'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f';
|
||||
const input = codeBlock`
|
||||
maybe(
|
||||
_http_archive,
|
||||
name = "bazel_skylib",
|
||||
sha256 = "${inputHash}",
|
||||
strip_prefix = "bazel-skylib-0.5.0",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz",
|
||||
],
|
||||
)
|
||||
`;
|
||||
|
||||
const currentValue = '0.5.0';
|
||||
const newValue = '0.6.2';
|
||||
const upgrade = {
|
||||
depName: 'bazel_skylib',
|
||||
depType: 'http_archive',
|
||||
repo: 'bazelbuild/bazel-skylib',
|
||||
managerData: { idx: 0 },
|
||||
currentValue,
|
||||
newValue,
|
||||
};
|
||||
|
||||
const tarContent = Buffer.from('foo');
|
||||
const outputHash = crypto
|
||||
.createHash('sha256')
|
||||
.update(tarContent)
|
||||
.digest('hex');
|
||||
|
||||
const output = input
|
||||
.replace(currentValue, newValue)
|
||||
.replace(currentValue, newValue)
|
||||
.replace(currentValue, newValue)
|
||||
.replace(inputHash, outputHash);
|
||||
|
||||
httpMock
|
||||
.scope('https://github.com')
|
||||
.get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
|
||||
.reply(200, tarContent);
|
||||
httpMock
|
||||
.scope('https://mirror.bazel.build')
|
||||
.get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz')
|
||||
.reply(200, tarContent);
|
||||
|
||||
const res = await updateArtifacts(
|
||||
partial<UpdateArtifact>({
|
||||
packageFileName: 'WORKSPACE',
|
||||
updatedDeps: [upgrade],
|
||||
newPackageFileContent: input,
|
||||
})
|
||||
);
|
||||
|
||||
expect(res).toEqual([
|
||||
{
|
||||
file: {
|
||||
contents: output,
|
||||
path: 'WORKSPACE',
|
||||
type: 'addition',
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('updates one http_archive alongside others', async () => {
|
||||
const inputHash =
|
||||
'5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064';
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { PackageDependency, PackageFileContent } from '../types';
|
||||
import { parse } from './parser';
|
||||
import { extractDepsFromFragment } from './rules';
|
||||
import { dockerRules } from './rules/docker';
|
||||
import { gitRules } from './rules/git';
|
||||
import { goRules } from './rules/go';
|
||||
import { ociRules } from './rules/oci';
|
||||
import type { RecordFragment } from './types';
|
||||
|
||||
export function extractPackageFile(
|
||||
@@ -19,15 +23,11 @@ export function extractPackageFile(
|
||||
for (const dep of extractDepsFromFragment(fragment)) {
|
||||
dep.managerData = { idx };
|
||||
|
||||
// Selectively provide `replaceString` in order
|
||||
// to auto-replace functionality work correctly.
|
||||
// Selectively provide `replaceString` in order to make auto-replace
|
||||
// functionality work correctly.
|
||||
const rules = [...dockerRules, ...ociRules, ...gitRules, ...goRules];
|
||||
const replaceString = fragment.value;
|
||||
if (
|
||||
replaceString.startsWith('container_pull') ||
|
||||
replaceString.startsWith('oci_pull') ||
|
||||
replaceString.startsWith('git_repository') ||
|
||||
replaceString.startsWith('go_repository')
|
||||
) {
|
||||
if (rules.some((rule) => replaceString.startsWith(rule))) {
|
||||
if (dep.currentValue && dep.currentDigest) {
|
||||
dep.replaceString = replaceString;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ describe('modules/manager/bazel/parser', () => {
|
||||
const input = codeBlock`
|
||||
go_repository(name = "foo")
|
||||
maybe(go_repository, name = "bar", deps = ["baz", "qux"])
|
||||
_go_repository(name = "quux")
|
||||
maybe(_go_repository, name = "corge", deps = ["grault", "garply"])
|
||||
`;
|
||||
|
||||
const res = parse(input);
|
||||
@@ -39,10 +41,40 @@ describe('modules/manager/bazel/parser', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'record',
|
||||
value: '_go_repository(name = "quux")',
|
||||
offset: 86,
|
||||
children: {
|
||||
rule: { type: 'string', value: '_go_repository', offset: 86 },
|
||||
name: { type: 'string', value: 'quux', offset: 109 },
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'record',
|
||||
value:
|
||||
'maybe(_go_repository, name = "corge", deps = ["grault", "garply"])',
|
||||
offset: 116,
|
||||
children: {
|
||||
rule: { type: 'string', value: '_go_repository', offset: 122 },
|
||||
name: { type: 'string', value: 'corge', offset: 146 },
|
||||
deps: {
|
||||
type: 'array',
|
||||
value: '["grault", "garply"]',
|
||||
offset: 161,
|
||||
children: [
|
||||
{ type: 'string', value: 'grault', offset: 163 },
|
||||
{ type: 'string', value: 'garply', offset: 173 },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(res?.map(extract)).toMatchObject([
|
||||
{ rule: 'go_repository', name: 'foo' },
|
||||
{ rule: 'go_repository', name: 'bar', deps: ['baz', 'qux'] },
|
||||
{ rule: '_go_repository', name: 'quux' },
|
||||
{ rule: '_go_repository', name: 'corge', deps: ['grault', 'garply'] },
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ function ruleNameHandler(ctx: Ctx, { value, offset }: lexer.Token): Ctx {
|
||||
/**
|
||||
* Matches regular rules:
|
||||
* - `git_repository(...)`
|
||||
* - `go_repository(...)`
|
||||
* - `_go_repository(...)`
|
||||
*/
|
||||
const regularRule = q
|
||||
.sym<Ctx>(supportedRulesRegex, (ctx, token) =>
|
||||
@@ -272,7 +272,7 @@ const regularRule = q
|
||||
/**
|
||||
* Matches "maybe"-form rules:
|
||||
* - `maybe(git_repository, ...)`
|
||||
* - `maybe(go_repository, ...)`
|
||||
* - `maybe(_go_repository, ...)`
|
||||
*/
|
||||
const maybeRule = q
|
||||
.sym<Ctx>('maybe', recordStartHandler)
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DockerDatasource } from '../../../datasource/docker';
|
||||
import { id as dockerVersioning } from '../../../versioning/docker';
|
||||
import type { PackageDependency } from '../../types';
|
||||
|
||||
export const dockerRules = ['container_pull'] as const;
|
||||
export const dockerRules = ['container_pull', '_container_pull'] as const;
|
||||
|
||||
export const DockerTarget = z
|
||||
.object({
|
||||
|
||||
@@ -17,7 +17,7 @@ function githubPackageName(input: string): string | undefined {
|
||||
return parseGithubUrl(input)?.match(githubUrlRegex)?.groups?.packageName;
|
||||
}
|
||||
|
||||
export const gitRules = ['git_repository'] as const;
|
||||
export const gitRules = ['git_repository', '_git_repository'] as const;
|
||||
|
||||
export const GitTarget = z
|
||||
.object({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { regEx } from '../../../../util/regex';
|
||||
import { GoDatasource } from '../../../datasource/go';
|
||||
import type { PackageDependency } from '../../types';
|
||||
|
||||
export const goRules = ['go_repository'] as const;
|
||||
export const goRules = ['go_repository', '_go_repository'] as const;
|
||||
|
||||
export const GoTarget = z
|
||||
.object({
|
||||
|
||||
@@ -119,7 +119,12 @@ export function parseArchiveUrl(
|
||||
return null;
|
||||
}
|
||||
|
||||
export const httpRules = ['http_archive', 'http_file'] as const;
|
||||
export const httpRules = [
|
||||
'http_archive',
|
||||
'_http_archive',
|
||||
'http_file',
|
||||
'_http_file',
|
||||
] as const;
|
||||
|
||||
export const HttpTarget = z
|
||||
.object({
|
||||
|
||||
@@ -30,7 +30,7 @@ const supportedRules = [
|
||||
...httpRules,
|
||||
...mavenRules,
|
||||
];
|
||||
export const supportedRulesRegex = regEx(`^${supportedRules.join('|')}$`);
|
||||
export const supportedRulesRegex = regEx(`^(?:${supportedRules.join('|')})$`);
|
||||
|
||||
export function extractDepsFromFragmentData(
|
||||
fragmentData: FragmentData
|
||||
|
||||
@@ -4,7 +4,7 @@ import { MavenDatasource } from '../../../datasource/maven';
|
||||
import { id as versioning } from '../../../versioning/gradle';
|
||||
import type { PackageDependency } from '../../types';
|
||||
|
||||
export const mavenRules = ['maven_install'] as const;
|
||||
export const mavenRules = ['maven_install', '_maven_install'] as const;
|
||||
|
||||
const ArtifactSpec = z.union([
|
||||
z.object({
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DockerDatasource } from '../../../datasource/docker';
|
||||
import { id as dockerVersioning } from '../../../versioning/docker';
|
||||
import type { PackageDependency } from '../../types';
|
||||
|
||||
export const ociRules = ['oci_pull'] as const;
|
||||
export const ociRules = ['oci_pull', '_oci_pull'] as const;
|
||||
|
||||
export const OciTarget = z
|
||||
.object({
|
||||
|
||||
Reference in New Issue
Block a user