Skip to content

Commit

Permalink
add "archiveType" source.json property to set the http_archive's "typ…
Browse files Browse the repository at this point in the history
…e" value.

Closes #17789.

PiperOrigin-RevId: 517408668
Change-Id: I7f89db0d2587cde3ff9d77c8657d162981cf32dc
  • Loading branch information
jjjhhhlll authored and Copybara-Service committed Mar 17, 2023
1 parent b217dd7 commit c7695ce
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 11 deletions.
6 changes: 5 additions & 1 deletion site/en/external/registry.md
Expand Up @@ -60,6 +60,10 @@ An index registry must follow the format below:
patch file names, and the values are the integrity checksum of
the patch files
* `patch_strip`: Same as the `--strip` argument of Unix `patch`.
* `archive_type`: The archive type of the downloaded file (Same as `type` on `http_archive`).
By default, the archive type is determined from the file extension of the URL. If the file has
no extension, you can explicitly specify one of the following: `"zip"`, `"jar"`, `"war"`, `"aar"`,
`"tar"`, `"tar.gz"`, `"tgz"`, `"tar.xz"`, `"txz"`, `"tar.zst"`, `"tzst"`, `tar.bz2`, `"ar"`, or `"deb"`.
* The type can be changed to use a local path, representing a
`local_repository` repo, with these fields:
* `type`: `local_path`
Expand Down Expand Up @@ -109,4 +113,4 @@ branch of the `my-org` fork, you would set
`--registry=https://raw.githubusercontent.com/my-org/bazel-central-registry/main/`.

Using the `--registry` flag stops the Bazel Central Registry from being used by
default, but you can add it back by adding `--registry=https://bcr.bazel.build`.
default, but you can add it back by adding `--registry=https://bcr.bazel.build`.
Expand Up @@ -15,6 +15,7 @@

package com.google.devtools.build.lib.bazel.bzlmod;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
Expand Down Expand Up @@ -85,6 +86,14 @@ public ArchiveRepoSpecBuilder setRemotePatchStrip(int remotePatchStrip) {
return this;
}

@CanIgnoreReturnValue
public ArchiveRepoSpecBuilder setArchiveType(String archiveType) {
if (!Strings.isNullOrEmpty(archiveType)) {
attrBuilder.put("type", archiveType);
}
return this;
}

public RepoSpec build() {
return RepoSpec.builder()
.setBzlFile("@bazel_tools//tools/build_defs/repo:http.bzl")
Expand Down
Expand Up @@ -110,6 +110,7 @@ private static class SourceJson {
Map<String, String> patches;
int patchStrip;
String path;
String archiveType;
}

/**
Expand Down Expand Up @@ -244,6 +245,7 @@ private RepoSpec createArchiveRepoSpec(
.setStripPrefix(Strings.nullToEmpty(sourceJson.get().stripPrefix))
.setRemotePatches(remotePatches.buildOrThrow())
.setRemotePatchStrip(sourceJson.get().patchStrip)
.setArchiveType(sourceJson.get().archiveType)
.build();
}

Expand Down
Expand Up @@ -290,4 +290,33 @@ public void testGetYankedVersion() throws Exception {
Version.parse("1.0"),
"red-pill 1.0 is yanked due to CVE-2000-101, please upgrade to 2.0"));
}

@Test
public void testArchiveWithExplicitType() throws Exception {
server.serve(
"/modules/archive_type/1.0/source.json",
"{",
" \"url\": \"https://mysite.com/thing?format=zip\",",
" \"integrity\": \"sha256-blah\",",
" \"archive_type\": \"zip\"",
"}");
server.start();

Registry registry = registryFactory.getRegistryWithUrl(server.getUrl());
assertThat(
registry.getRepoSpec(
createModuleKey("archive_type", "1.0"),
RepositoryName.create("archive_type_repo"),
reporter))
.isEqualTo(
new ArchiveRepoSpecBuilder()
.setRepoName("archive_type_repo")
.setUrls(ImmutableList.of("https://mysite.com/thing?format=zip"))
.setIntegrity("sha256-blah")
.setStripPrefix("")
.setArchiveType("zip")
.setRemotePatches(ImmutableMap.of())
.setRemotePatchStrip(0)
.build());
}
}
34 changes: 34 additions & 0 deletions src/test/py/bazel/bzlmod/bazel_module_test.py
Expand Up @@ -1007,6 +1007,40 @@ def testWorkspaceItselfCanSeeRootModuleMappings(self):
_, _, stderr = self.RunBazel(['build', ':a'], allow_failure=False)
self.assertIn('I LUV U!', '\n'.join(stderr))

def testArchiveWithArchiveType(self):
# make the archive without the .zip extension
self.main_registry.createCcModule(
'aaa', '1.2', archive_pattern='%s.%s', archive_type='zip'
)

self.ScratchFile(
'MODULE.bazel',
[
'bazel_dep(name = "aaa", version = "1.2")',
],
)
self.ScratchFile(
'BUILD',
[
'cc_binary(',
' name = "main",',
' srcs = ["main.cc"],',
' deps = ["@aaa//:lib_aaa"],',
')',
],
)
self.ScratchFile(
'main.cc',
[
'#include "aaa.h"',
'int main() {',
' hello_aaa("main function");',
'}',
],
)
_, stdout, _ = self.RunBazel(['run', '//:main'], allow_failure=False)
self.assertIn('main function => aaa@1.2', stdout)


if __name__ == '__main__':
unittest.main()
40 changes: 30 additions & 10 deletions src/test/py/bazel/bzlmod/test_utils.py
Expand Up @@ -63,6 +63,7 @@ def __init__(self, name, version):
self.module_dot_bazel = None
self.patches = []
self.patch_strip = 0
self.archive_type = None

def set_source(self, archive_url, strip_prefix=None):
self.archive_url = archive_url
Expand All @@ -78,6 +79,10 @@ def set_patches(self, patches, patch_strip):
self.patch_strip = patch_strip
return self

def set_archive_type(self, archive_type):
self.archive_type = archive_type
return self


class BazelRegistry:
"""A class to help create a Bazel module project from scatch and add it into the registry."""
Expand Down Expand Up @@ -186,9 +191,9 @@ def calc_repo_name_str(dep):
])
return src_dir

def createArchive(self, name, version, src_dir):
def createArchive(self, name, version, src_dir, filename_pattern='%s.%s.zip'):
"""Create an archive with a given source directory."""
zip_path = self.archives.joinpath('%s.%s.zip' % (name, version))
zip_path = self.archives.joinpath(filename_pattern % (name, version))
zip_obj = zipfile.ZipFile(str(zip_path), 'w')
for foldername, _, filenames in os.walk(str(src_dir)):
for filename in filenames:
Expand Down Expand Up @@ -225,24 +230,39 @@ def addModule(self, module):
source['patches'][patch.name] = integrity(read(patch))
shutil.copy(str(patch), str(patch_dir))

if module.archive_type:
source['archive_type'] = module.archive_type

with module_dir.joinpath('source.json').open('w') as f:
json.dump(source, f, indent=4, sort_keys=True)

def createCcModule(self,
name,
version,
deps=None,
repo_names=None,
patches=None,
patch_strip=0):
def createCcModule(
self,
name,
version,
deps=None,
repo_names=None,
patches=None,
patch_strip=0,
archive_pattern=None,
archive_type=None,
):
"""Generate a cc project and add it as a module into the registry."""
src_dir = self.generateCcSource(name, version, deps, repo_names)
archive = self.createArchive(name, version, src_dir)
if archive_pattern:
archive = self.createArchive(
name, version, src_dir, filename_pattern=archive_pattern
)
else:
archive = self.createArchive(name, version, src_dir)
module = Module(name, version)
module.set_source(archive.resolve().as_uri())
module.set_module_dot_bazel(src_dir.joinpath('MODULE.bazel'))
if patches:
module.set_patches(patches, patch_strip)
if archive_type:
module.set_archive_type(archive_type)

self.addModule(module)
return self

Expand Down

0 comments on commit c7695ce

Please sign in to comment.