diff --git a/BUILD.bazel b/BUILD.bazel index 3cc68fcc2a1f33b38956e41ce9c385be44c04fc2..4085bac71f8154531761ee4623c97494d0640eda 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -22,5 +22,8 @@ package_info( # Just here to provide a test target so `bazel test ...` passes build_test( name = "test", - targets = [":license", ":package_info"], + targets = [ + ":license", + ":package_info", + ], ) diff --git a/CODEOWNERS b/CODEOWNERS index 0675e6ae77b1a359f083497790468183ebf2e75e..2b29d6a96e93032962731c28781b039af595f513 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,34 +1,34 @@ -* @bazel +* @matthew.clarkson -[Shell] @bazel +[Shell] @matthew.clarkson *.sh -[Batch] @bazel +[Batch] @matthew.clarkson *.bat -[Documentation] @bazel +[Documentation] @matthew.clarkson *.md -[Licensing] @bazel +[Licensing] @matthew.clarkson /LICENSE.md -[Configuration] @bazel +[Configuration] @matthew.clarkson .editorconfig -[CI] @bazel +[CI] @matthew.clarkson .gitlab-ci.yml -[Release] @bazel +[Release] @matthew.clarkson /.releaserc.yaml -[Node] @bazel +[Node] @matthew.clarkson /package.json /.npmrc -[Branding] @bazel +[Branding] @matthew.clarkson /icon.svg -[Bazel] @bazel +[Bazel] @matthew.clarkson /.bazelrc /.bazelrc.ci /.bazelignore diff --git a/MODULE.bazel b/MODULE.bazel index 0a47926f82303a4111fb9a083adad7c3576f3d8b..7594c7ab181e1409b053b0427b348ff3b3d8ec05 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -6,6 +6,7 @@ module( ) bazel_dep(name = "rules_license", version = "1.0.0") + bazel_dep(name = "bazel_skylib", version = "1.7.1", dev_dependency = True) bazel_dep(name = "toolchain_utils", version = "1.0.2", dev_dependency = True) diff --git a/download/archive/repository.bzl b/download/archive/repository.bzl index 7b384109bf1332a9eb5395621fe529c0580957f9..f79587611be82ef60b6cc1e77589ea93f2173c5b 100644 --- a/download/archive/repository.bzl +++ b/download/archive/repository.bzl @@ -3,6 +3,7 @@ load("//lib:download_and_extract.bzl", "download_and_extract", _DOWNLOAD_AND_EXT load("//lib:patch.bzl", "patch", _PATCH = "ATTRS") load("//lib:build.bzl", "build", _BUILD = "ATTRS") load("//lib:links.bzl", "links", _LINKS = "ATTRS") +load("//lib:metadata.bzl", "metadata", _METADATA = "ATTRS") load("//lib:workspace.bzl", "write") visibility("//download/...") @@ -18,7 +19,7 @@ download_archive( ``` """ -ATTRS = _COMMANDS | _DOWNLOAD_AND_EXTRACT | _PATCH | _BUILD | _LINKS | { +ATTRS = _COMMANDS | _DOWNLOAD_AND_EXTRACT | _PATCH | _BUILD | _LINKS | _METADATA | { "extension": attr.string( doc = "The extension of the archive when not available from the URL.", values = [".zip", ".tar", ".tar.gz", ".tar.bz2", ".tar.xz", ".tar.zst"], @@ -34,6 +35,8 @@ def implementation(rctx): canonical |= links(rctx) canonical |= commands(rctx) + metadata(rctx, canonical) + return write(rctx, canonical) archive = repository_rule( diff --git a/download/deb/repository.bzl b/download/deb/repository.bzl index 524f10b9029bf5199b6befbdc3adfe20683756ed..a83b977413bc9a83417071bf2db74656e55e64f2 100644 --- a/download/deb/repository.bzl +++ b/download/deb/repository.bzl @@ -3,6 +3,7 @@ load("//lib:download_and_extract.bzl", "download_and_extract", _DOWNLOAD_AND_EXT load("//lib:patch.bzl", "patch", _PATCH = "ATTRS") load("//lib:build.bzl", "build", _BUILD = "ATTRS") load("//lib:links.bzl", "links", _LINKS = "ATTRS") +load("//lib:metadata.bzl", "metadata", _METADATA = "ATTRS") load("//lib:workspace.bzl", "write") visibility("//download/...") @@ -21,7 +22,7 @@ download_deb( ``` """ -ATTRS = _COMMANDS | _DOWNLOAD_AND_EXTRACT | _PATCH | _BUILD | _LINKS +ATTRS = _COMMANDS | _DOWNLOAD_AND_EXTRACT | _PATCH | _BUILD | _LINKS | _METADATA def implementation(rctx): canonical = {a: getattr(rctx.attr, a) for a in ATTRS} | {"name": rctx.name} @@ -32,6 +33,8 @@ def implementation(rctx): canonical |= links(rctx) canonical |= commands(rctx) + metadata(rctx, canonical) + return write(rctx, canonical) deb = repository_rule( diff --git a/download/file/repository.bzl b/download/file/repository.bzl index 380fc6e5fd7e937a31ef7017c4b0e421377d8291..6efdbff1bb9363fd5e1be2f813d1b0ce5a0391c9 100644 --- a/download/file/repository.bzl +++ b/download/file/repository.bzl @@ -3,6 +3,7 @@ load("//lib:download.bzl", "download", _DOWNLOAD = "ATTRS") load("//lib:patch.bzl", "patch", _PATCH = "ATTRS") load("//lib:build.bzl", "build", _BUILD = "ATTRS") load("//lib:links.bzl", "links", _LINKS = "ATTRS") +load("//lib:metadata.bzl", "metadata", _METADATA = "ATTRS") load("//lib:workspace.bzl", "write") visibility("//download/...") @@ -20,12 +21,7 @@ download_file( ``` """ -ATTRS = _COMMANDS | _DOWNLOAD | _PATCH | _BUILD | _LINKS | { - "build": attr.label( - doc = "The template for the `BUILD.bazel` file.", - default = ":BUILD.tmpl.bazel", - ), -} +ATTRS = _COMMANDS | _DOWNLOAD | _PATCH | _BUILD | _LINKS | _METADATA def implementation(rctx): canonical = {a: getattr(rctx.attr, a) for a in ATTRS} | {"name": rctx.name} @@ -36,6 +32,8 @@ def implementation(rctx): canonical |= links(rctx) canonical |= commands(rctx) + metadata(rctx, canonical) + return write(rctx, canonical) file = repository_rule( diff --git a/e2e/MODULE.bazel b/e2e/MODULE.bazel index def9065b2c9e117b1985cce5803f1b9c6ad731a8..52e24141919e06497b91b43dc948df4ce817e9f8 100644 --- a/e2e/MODULE.bazel +++ b/e2e/MODULE.bazel @@ -27,6 +27,9 @@ archive( }, extension = ".tar.xz", integrity = "sha256-PWscbDJ+esMLMe4/ix5LTP+lsR1piMNe7r9eHsx/KOg=", + metadata = { + "//archive:metadata.tmpl": ".integrity", + }, patches = [ "//archive:fixture.patch", ], @@ -48,6 +51,20 @@ file( urls = ["file://%workspace%/fixture.txt"], ) +file( + name = "file_with_build", + build = "//file:BUILD.bazel.tmpl", + integrity = "sha256-2QFMRiSESqW6wxR3PWtomtRn+k4dGlChuKmdWpX3L/U=", + metadata = { + "//file:metadata.tmpl": ".integrity", + }, + output = "fixture.txt", + patches = [ + "//file:fixture.patch", + ], + urls = ["file://%workspace%/fixture.txt"], +) + deb = use_repo_rule("@download_utils//download/deb:defs.bzl", "download_deb") deb( @@ -56,6 +73,9 @@ deb( links = { "etc/test/fixture.txt": "symlink.txt", }, + metadata = { + "//deb:metadata.tmpl": ".integrity", + }, patches = [ "//deb:fixture.patch", ], diff --git a/e2e/archive/BUILD.bazel b/e2e/archive/BUILD.bazel index 85ffff8f04d14f94e5f7edde19a67fbc9422e93c..8ce038b86ba220e6d9efccb25db07fd047eee861 100644 --- a/e2e/archive/BUILD.bazel +++ b/e2e/archive/BUILD.bazel @@ -13,3 +13,10 @@ diff_file_test( a = "@archive//:symlink.txt", b = ":fixture.txt", ) + +diff_file_test( + name = "metadata", + size = "small", + a = "@archive//:.integrity", + b = ":fixture.integrity", +) diff --git a/e2e/archive/fixture.integrity b/e2e/archive/fixture.integrity new file mode 100644 index 0000000000000000000000000000000000000000..2c9ff56d3fbe40000d6ba963e87d79fc5a9b5f31 --- /dev/null +++ b/e2e/archive/fixture.integrity @@ -0,0 +1 @@ +sha256-PWscbDJ+esMLMe4/ix5LTP+lsR1piMNe7r9eHsx/KOg= diff --git a/e2e/archive/metadata.tmpl b/e2e/archive/metadata.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..c22e01022a0b74a88a56065e892dfd7b49eaba11 --- /dev/null +++ b/e2e/archive/metadata.tmpl @@ -0,0 +1 @@ +{{integrity}} diff --git a/e2e/deb/BUILD.bazel b/e2e/deb/BUILD.bazel index 0ef7335441a68b4aee5d4c1bf26b143337562e27..8ac830ef5530104b7fb8b00e07f22437cc6b4f8f 100644 --- a/e2e/deb/BUILD.bazel +++ b/e2e/deb/BUILD.bazel @@ -13,3 +13,10 @@ diff_file_test( a = "@deb//:symlink.txt", b = ":fixture.txt", ) + +diff_file_test( + name = "metadata", + size = "small", + a = "@deb//:.integrity", + b = ":fixture.integrity", +) diff --git a/e2e/deb/fixture.integrity b/e2e/deb/fixture.integrity new file mode 100644 index 0000000000000000000000000000000000000000..645f92bb2b20869e08634a7df548dd3e6abaf7ce --- /dev/null +++ b/e2e/deb/fixture.integrity @@ -0,0 +1 @@ +sha256-vMiq8kFBwoSrVEE+Tcs08RvaiNp6MsboWlXS7p1clO0= diff --git a/e2e/deb/metadata.tmpl b/e2e/deb/metadata.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..c22e01022a0b74a88a56065e892dfd7b49eaba11 --- /dev/null +++ b/e2e/deb/metadata.tmpl @@ -0,0 +1 @@ +{{integrity}} diff --git a/e2e/file/BUILD.bazel b/e2e/file/BUILD.bazel index da4daf1b9918653daa0ebea4c3a1307a8ad23d95..e40e52e7bc9e62028fa24918d4e1fe4cbd59714a 100644 --- a/e2e/file/BUILD.bazel +++ b/e2e/file/BUILD.bazel @@ -6,3 +6,10 @@ diff_file_test( a = "@file//:fixture.txt", b = ":fixture.txt", ) + +diff_file_test( + name = "metadata", + size = "small", + a = "@file_with_build//:.integrity", + b = ":fixture.integrity", +) diff --git a/e2e/file/BUILD.bazel.tmpl b/e2e/file/BUILD.bazel.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..6dd2c95cd93e63a77ff009411d9bda1fab33eedb --- /dev/null +++ b/e2e/file/BUILD.bazel.tmpl @@ -0,0 +1,10 @@ +filegroup( + name = "srcs", + srcs = glob({{srcs}}), + visibility = ["//visibility:public"], +) + +exports_files( + glob({{srcs}} + [".integrity"]), + visibility = ["//visibility:public"], +) diff --git a/e2e/file/fixture.integrity b/e2e/file/fixture.integrity new file mode 100644 index 0000000000000000000000000000000000000000..8d01ab88a9d10801720588794eac0ecd4c447339 --- /dev/null +++ b/e2e/file/fixture.integrity @@ -0,0 +1 @@ +sha256-2QFMRiSESqW6wxR3PWtomtRn+k4dGlChuKmdWpX3L/U= diff --git a/e2e/file/metadata.tmpl b/e2e/file/metadata.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..c22e01022a0b74a88a56065e892dfd7b49eaba11 --- /dev/null +++ b/e2e/file/metadata.tmpl @@ -0,0 +1 @@ +{{integrity}} diff --git a/lib/metadata.bzl b/lib/metadata.bzl new file mode 100644 index 0000000000000000000000000000000000000000..4be15900431c094c36a52ebfbbb7b099c2057df4 --- /dev/null +++ b/lib/metadata.bzl @@ -0,0 +1,24 @@ +visibility("//...") + +ATTRS = { + "metadata": attr.label_keyed_string_dict( + doc = """Creates files in the repository at the path of the values with the templated contents of the keys. + +Templates receive a `{{integrity}}` substitution value for exposing the archive subresource integrity.""", + mandatory = False, + ), +} + +def metadata(rctx, canonical): + """ + Generate metadata files based on templates passed in. + + Args: + rctx: The download repository context. + canonical: The final canonical arguments + """ + + if rctx.attr.metadata: + substitutions = {"{{integrity}}": canonical["integrity"]} + for template, output in rctx.attr.metadata.items(): + rctx.template(output, template, substitutions, executable = False) diff --git a/lib/workspace.bzl b/lib/workspace.bzl index f39224f527dac0d52b00514a3d59e67552804ed9..28efaed71875b500bd801aee9a2e4bc8b762162a 100644 --- a/lib/workspace.bzl +++ b/lib/workspace.bzl @@ -21,9 +21,21 @@ def write(rctx, canonical): """ Generate a `WORKSPACE` file that is stamped with the canonical arguments. + Adds the canonical arguments if a `WORKSPACE` exists. + + Does nothing if `rctx.metadata` is truthy as the user is manually deciding to write out metadata. + Args: rctx: The download repository context. canonical: The final canonical arguments """ - rctx.file("WORKSPACE", "# {}".format(canonical), executable = False) + if getattr(rctx.attr, "metadata", None): + return + + content = "# {}".format(canonical) + ws = rctx.path("WORKSPACE") + if ws.exists: + data = rctx.read("WORKSPACE", watch = "no") + content = data + "\n" + content + rctx.file("WORKSPACE", content, executable = False) return canonical