diff --git a/lib/modules/manager/bazel/__fixtures__/WORKSPACE1 b/lib/modules/manager/bazel/__fixtures__/WORKSPACE1 index cc9884dd2a6d7c30d69f81d35a3d86e8debc9f2a..8d3b35bfb95a8b52d47368481147b09c25829ec8 100644 --- a/lib/modules/manager/bazel/__fixtures__/WORKSPACE1 +++ b/lib/modules/manager/bazel/__fixtures__/WORKSPACE1 @@ -55,6 +55,14 @@ http_archive( ], ) +http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = [ + "https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz" + ], +) + local_repository( name = "angular", path = "node_modules/@angular/bazel", diff --git a/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap index 976e5dc5fcec561d2d8e5c9a156f5955ad7414a3..630f88a3c46c85e2719d92aac9a620dda9c274fd 100644 --- a/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap @@ -269,6 +269,22 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty }, "packageName": "bazelbuild/bazel-toolchains", }, + { + "currentValue": "5.5.3", + "datasource": "github-releases", + "depName": "rules_nodejs", + "depType": "http_archive", + "managerData": { + "def": "http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = [ + "https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz" + ], +)", + }, + "packageName": "bazelbuild/rules_nodejs", + }, { "currentValue": "0.0.3", "datasource": "github-releases", @@ -454,3 +470,37 @@ exports[`modules/manager/bazel/extract extractPackageFile() handle comments and }, ] `; + +exports[`modules/manager/bazel/extract extractPackageFile() sequential http_archive 1`] = ` +[ + { + "currentValue": "v1.1.2", + "datasource": "github-tags", + "depName": "aspect_rules_js", + "depType": "http_archive", + "managerData": { + "def": "http_archive( + name = "aspect_rules_js", + sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", + strip_prefix = "rules_js-1.1.2", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", + )", + }, + "packageName": "aspect-build/rules_js", + }, + { + "currentValue": "5.5.3", + "datasource": "github-releases", + "depName": "rules_nodejs", + "depType": "http_archive", + "managerData": { + "def": "http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz"], + )", + }, + "packageName": "bazelbuild/rules_nodejs", + }, +] +`; diff --git a/lib/modules/manager/bazel/common.spec.ts b/lib/modules/manager/bazel/common.spec.ts index 3a3ce999b87d9a9665bb22485c2e2f9c4dca9f88..161c11ca4e252750afca1a444a59103319e51d40 100644 --- a/lib/modules/manager/bazel/common.spec.ts +++ b/lib/modules/manager/bazel/common.spec.ts @@ -16,6 +16,7 @@ describe('modules/manager/bazel/common', () => { expect(parseArchiveUrl('https://example.com/')).toBeNull(); expect(parseArchiveUrl('https://github.com/foo/bar')).toBeNull(); + // Archive of a commit. expect( parseArchiveUrl( 'https://github.com/foo/bar/archive/abcdef0123abcdef0123abcdef0123abcdef0123.tar.gz' @@ -26,6 +27,7 @@ describe('modules/manager/bazel/common', () => { currentValue: 'abcdef0123abcdef0123abcdef0123abcdef0123', }); + // Archive of a release expect( parseArchiveUrl( 'https://github.com/foo/bar/releases/download/1.2.3/foobar-1.2.3.tar.gz' @@ -35,6 +37,17 @@ describe('modules/manager/bazel/common', () => { repo: 'foo/bar', currentValue: '1.2.3', }); + + // Archive of a tag. + expect( + parseArchiveUrl( + 'https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz' + ) + ).toEqual({ + datasource: 'github-tags', + repo: 'aspect-build/rules_js', + currentValue: 'v1.1.2', + }); }); test('gitDependency', () => { @@ -235,6 +248,24 @@ describe('modules/manager/bazel/common', () => { depType: 'http_archive', packageName: 'foo/bar', }); + + expect( + httpDependency({ + rule: 'http_archive', + name: 'aspect_rules_js', + sha256: + 'db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598', + urls: [ + 'https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz', + ], + }) + ).toEqual({ + currentValue: 'v1.1.2', + datasource: 'github-tags', + depName: 'aspect_rules_js', + depType: 'http_archive', + packageName: 'aspect-build/rules_js', + }); }); test('dockerDependency', () => { @@ -261,26 +292,50 @@ describe('modules/manager/bazel/common', () => { }); }); - test('extractDepFromTarget', () => { - expect(extractDepFromTarget({ rule: 'foo', name: 'bar' })).toBeNull(); + describe('extractDepFromTarget', () => { + it('returns null and warns for unknown rule type', () => { + expect(extractDepFromTarget({ rule: 'foo', name: 'bar' })).toBeNull(); - expect( - extractDepFromTarget({ - rule: 'git_repository', - name: 'foo_bar', - tag: '1.2.3', - remote: 'https://github.com/foo/bar', - }) - ).toEqual({ - datasource: 'github-releases', - depType: 'git_repository', - depName: 'foo_bar', - packageName: 'foo/bar', - currentValue: '1.2.3', + expect(logger.logger.warn).toHaveBeenCalledWith( + 'Bazel dependency extractor function not found for foo' + ); + }); + + it('extracts from git_repository', () => { + expect( + extractDepFromTarget({ + rule: 'git_repository', + name: 'foo_bar', + tag: '1.2.3', + remote: 'https://github.com/foo/bar', + }) + ).toEqual({ + datasource: 'github-releases', + depType: 'git_repository', + depName: 'foo_bar', + packageName: 'foo/bar', + currentValue: '1.2.3', + }); }); - expect(logger.logger.warn).toHaveBeenCalledWith( - 'Bazel dependency extractor function not found for foo' - ); + it('extracts from http_archive', () => { + expect( + extractDepFromTarget({ + rule: 'http_archive', + name: 'rules_nodejs', + sha256: + '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064', + urls: [ + 'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz', + ], + }) + ).toEqual({ + datasource: 'github-releases', + depType: 'http_archive', + depName: 'rules_nodejs', + packageName: 'bazelbuild/rules_nodejs', + currentValue: '5.5.3', + }); + }); }); }); diff --git a/lib/modules/manager/bazel/common.ts b/lib/modules/manager/bazel/common.ts index 15279eb82a9a60bfe1b45466406253e3b99254cb..3767b5f057083c0cba6308f2a77c3389bf1918dc 100644 --- a/lib/modules/manager/bazel/common.ts +++ b/lib/modules/manager/bazel/common.ts @@ -29,10 +29,19 @@ export function parseArchiveUrl( if (path[2] === 'releases' && path[3] === 'download') { datasource = GithubReleasesDatasource.id; currentValue = path[4]; - } - if (path[2] === 'archive') { + } else if ( + path[2] === 'archive' && + path[3] === 'refs' && + path[4] === 'tags' + ) { + datasource = GithubTagsDatasource.id; + currentValue = path[5]; + } else if (path[2] === 'archive') { datasource = GithubTagsDatasource.id; currentValue = path[3]; + } + + if (currentValue) { // Strip archive extension to get hash or tag. // Tolerates formats produced by Git(Hub|Lab) and allowed by http_archive // Note: Order matters in suffix list to strip, e.g. .tar.gz. @@ -41,8 +50,7 @@ export function parseArchiveUrl( currentValue = currentValue.slice(0, -extension.length); } } - } - if (currentValue) { + return { datasource, repo, currentValue }; } return null; diff --git a/lib/modules/manager/bazel/extract.spec.ts b/lib/modules/manager/bazel/extract.spec.ts index 3846e6e28dcf90908b1d158f752c6cd7978cb0c0..5ca136e32a63899ace5709c5c0d513ba593aeb81 100644 --- a/lib/modules/manager/bazel/extract.spec.ts +++ b/lib/modules/manager/bazel/extract.spec.ts @@ -17,7 +17,7 @@ describe('modules/manager/bazel/extract', () => { it('extracts multiple types of dependencies', () => { const res = extractPackageFile(Fixtures.get('WORKSPACE1')); - expect(res?.deps).toHaveLength(17); + expect(res?.deps).toHaveLength(18); expect(res?.deps).toMatchSnapshot(); }); @@ -133,5 +133,29 @@ go_repository( ); expect(gitlabRemote?.deps[0].skipReason).toBe('unsupported-remote'); }); + + it('sequential http_archive', () => { + // Sequential http_archive + // See https://github.com/aspect-build/rules_swc/commit/d4989f9dfed781dc0226421fb9373b45052e7bc8 + const res = extractPackageFile( + ` + http_archive( + name = "aspect_rules_js", + sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", + strip_prefix = "rules_js-1.1.2", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", + ) + + http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz"], + ) + ` + ); + + expect(res?.deps).toHaveLength(2); + expect(res?.deps).toMatchSnapshot(); + }); }); }); diff --git a/lib/modules/manager/bazel/parser.spec.ts b/lib/modules/manager/bazel/parser.spec.ts index 9d2e78236b7def89f9641d0cb1b6ef20576e2cd6..ad08a3ec12ca5b420e407d0f9be3d605fc6600c3 100644 --- a/lib/modules/manager/bazel/parser.spec.ts +++ b/lib/modules/manager/bazel/parser.spec.ts @@ -110,4 +110,69 @@ describe('modules/manager/bazel/parser', () => { ], }); }); + + it('parses http_archive', () => { + const input = `http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + url = "https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz", + )`; + + const res = parse(input); + expect(res).toEqual({ + meta: [ + { data: { length: 12, offset: 32 }, path: [0, 'name'] }, + { data: { length: 64, offset: 67 }, path: [0, 'sha256'] }, + { data: { length: 97, offset: 151 }, path: [0, 'url'] }, + { data: { length: 256, offset: 0 }, path: [0] }, + ], + targets: [ + { + sha256: + '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064', + url: 'https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz', + name: 'rules_nodejs', + rule: 'http_archive', + }, + ], + }); + }); + + it('parses http_archive with prefixes and multiple urls', () => { + const input = `http_archive( + name = "bazel_toolchains", + sha256 = "4b1468b254a572dbe134cc1fd7c6eab1618a72acd339749ea343bd8f55c3b7eb", + strip_prefix = "bazel-toolchains-d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz", + ], + )`; + + const res = parse(input); + expect(res).toEqual({ + meta: [ + { data: { length: 16, offset: 30 }, path: [0, 'name'] }, + { data: { length: 64, offset: 67 }, path: [0, 'sha256'] }, + { data: { length: 57, offset: 158 }, path: [0, 'strip_prefix'] }, + { data: { length: 121, offset: 248 }, path: [0, 'urls', 0] }, + { data: { length: 102, offset: 385 }, path: [0, 'urls', 1] }, + { data: { length: 506, offset: 0 }, path: [0] }, + ], + targets: [ + { + sha256: + '4b1468b254a572dbe134cc1fd7c6eab1618a72acd339749ea343bd8f55c3b7eb', + urls: [ + 'https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz', + 'https://github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz', + ], + strip_prefix: + 'bazel-toolchains-d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4', + name: 'bazel_toolchains', + rule: 'http_archive', + }, + ], + }); + }); });