Skip to content

Commit

Permalink
refactor: centralize all of the deb_import functionality in deb_impor…
Browse files Browse the repository at this point in the history
…t.bzl

Refactor the package repo templates into their own methods and massively
cleanup the `for`-loop in `_deb_package_index_impl`.

IMHO overall now there's a much better and clear separation of concerns
between the "deb_translate_lock" repo and the "package repos"
(`apt/private/deb_import.bzl`).
  • Loading branch information
jjmaestro committed Nov 26, 2024
1 parent 53606b0 commit acf8b64
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 67 deletions.
4 changes: 2 additions & 2 deletions apt/apt.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ def _apt_install(
and avoid the DEBUG messages.
package_template: (EXPERIMENTAL!) a template file for generated BUILD
files. Available template replacement keys are:
`{target_name}`, `{deps}`, `{urls}`, `{name}`,
`{arch}`, `{sha256}`, `{repo_name}`
`{target_name}`, `{src}`, `{deps}`, `{urls}`,
`{name}`, `{arch}`, `{sha256}`, `{repo_name}`
resolve_transitive: whether dependencies of dependencies should be
resolved and added to the lockfile.
"""
Expand Down
1 change: 1 addition & 0 deletions apt/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ bzl_library(
srcs = ["deb_import.bzl"],
visibility = ["//apt:__subpackages__"],
deps = [
":starlark_codegen",
":util",
"@bazel_tools//tools/build_defs/repo:http.bzl",
],
Expand Down
64 changes: 62 additions & 2 deletions apt/private/deb_import.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"deb_import"

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load(":starlark_codegen.bzl", "starlark")
load(":util.bzl", "util")

# BUILD.bazel template
_DEB_IMPORT_BUILD_TMPL = '''
genrule(
name = "data",
Expand Down Expand Up @@ -62,8 +62,68 @@ def make_deb_import_key(repo_name, package):
util.sanitize(package.version),
)

def deb_import(**kwargs):
def deb_import(name, url, sha256, **kwargs):
http_archive(
name = name,
url = url,
sha256 = sha256,
build_file_content = _DEB_IMPORT_BUILD_TMPL,
**kwargs
)

def _deb_import_tmpl(repo_name, package):
deb_import_key = make_deb_import_key(repo_name, package)

return '''\
deb_import(
name = "{name}",
url = "{url}",
sha256 = "{sha256}",
)
'''.format(name = deb_import_key, url = package.url, sha256 = package.sha256)

def deb_packages(repo_name, packages):
deb_imports = [
_deb_import_tmpl(repo_name, package)
for architectures in packages.values()
for package in architectures.values()
]

return '''\
"""Generated by rules_distroless. DO NOT EDIT."""
load("@rules_distroless//apt/private:deb_import.bzl", "deb_import")
# buildifier: disable=function-docstring
def {repo_name}_packages():
{deb_imports}
'''.format(
repo_name = repo_name,
deb_imports = "\n".join(deb_imports) if deb_imports else " pass",
)

def package_build(package, repo_prefix, repo_name, template):
deb_import_key = make_deb_import_key(repo_name, package)

pkg_repo_name = "@%s%s" % (repo_prefix, deb_import_key)

alias_data = starlark.gen("%s//:data" % pkg_repo_name)
alias_control = starlark.gen("%s//:control" % pkg_repo_name)

deps = [
"//%s/%s" % (dep.name, package.arch)
for dep in package.dependencies
]
deps = starlark.gen(deps, indent_count = 1)

return template.format(
target_name = package.arch,
src = '"@%s%s//:data"' % (repo_prefix, deb_import_key),
deps = deps,
urls = [package.url],
name = package.name,
arch = package.arch,
sha256 = package.sha256,
repo_name = pkg_repo_name,
alias_data = alias_data,
alias_control = alias_control,
)
75 changes: 19 additions & 56 deletions apt/private/deb_translate_lock.bzl
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
"repository rule for generating a dependency graph from a lockfile."

load(":deb_import.bzl", "make_deb_import_key")
load(":deb_import.bzl", "deb_packages", "package_build")
load(":lockfile.bzl", "lockfile")

# header template for packages.bzl file
_DEB_IMPORT_HEADER_TMPL = '''\
"""Generated by rules_distroless. DO NOT EDIT."""
load("@rules_distroless//apt/private:deb_import.bzl", "deb_import")
# buildifier: disable=function-docstring
def {}_packages():
'''

# deb_import template for packages.bzl file
_DEB_IMPORT_TMPL = '''\
deb_import(
name = "{name}",
urls = {urls},
sha256 = "{sha256}",
)
'''

_BUILD_TMPL = """\
exports_files(glob(['packages.bzl']))
Expand All @@ -31,51 +13,32 @@ alias(
"""

def _deb_translate_lock_impl(rctx):
lock_content = rctx.attr.lock_content
package_template = rctx.read(rctx.attr.package_template)
lockf = lockfile.from_json(rctx, lock_content if lock_content else rctx.read(rctx.attr.lock))

package_defs = []

if not lock_content:
package_defs = [_DEB_IMPORT_HEADER_TMPL.format(rctx.attr.name)]
lockf = lockfile.from_json(
rctx,
rctx.attr.lock_content or rctx.read(rctx.attr.lock),
)
lockf.write("lock.json")

if not lockf.packages:
package_defs.append(" pass")
repo_prefix = "@" if rctx.attr.lock_content else ""
repo_name = rctx.attr.name

for package in lockf.packages():
deb_import_key = make_deb_import_key(rctx.attr.name, package)

if not lock_content:
package_defs.append(
_DEB_IMPORT_TMPL.format(
name = deb_import_key,
package_name = package.name,
urls = [package.url],
sha256 = package.sha256,
),
)

repo_name = "%s%s" % ("@" if lock_content else "", deb_import_key)

rctx.file(
"%s/%s/BUILD.bazel" % (package.name, package.arch),
package_template.format(
target_name = package.arch,
src = '"@%s//:data"' % repo_name,
deps = ",\n ".join([
'"//%s/%s"' % (dep.name, package.arch)
for dep in package.dependencies
]),
urls = [package.url],
name = package.name,
arch = package.arch,
sha256 = package.sha256,
repo_name = "%s" % repo_name,
package_build(
package,
repo_prefix,
repo_name,
rctx.read(rctx.attr.package_template),
),
)

rctx.file("packages.bzl", "\n".join(package_defs))
if rctx.attr.lock_content:
packages_bzl = ""
else:
packages_bzl = deb_packages(repo_name, lockf.packages)

rctx.file("packages.bzl", packages_bzl)
rctx.file("BUILD.bazel", _BUILD_TMPL.format(rctx.attr.name.split("~")[-1]))

deb_translate_lock = repository_rule(
Expand Down
21 changes: 15 additions & 6 deletions apt/private/package.BUILD.tmpl
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
"""Generated by rules_distroless. DO NOT EDIT."""

alias(
name = "data",
actual = "@{repo_name}//:data",
actual = {alias_data},
visibility = ["//visibility:public"],
)

alias(
name = "control",
actual = "@{repo_name}//:control",
actual = {alias_control},
visibility = ["//visibility:public"],
)

filegroup(
name = "{target_name}",
name = "deps",
srcs = {deps},
visibility = ["//visibility:public"],
)

filegroup(
name = "{target_name}",
srcs = [
{deps}
] + [":data"]
)
":deps",
":data",
],
visibility = ["//visibility:public"],
)
2 changes: 1 addition & 1 deletion docs/apt_macro.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit acf8b64

Please sign in to comment.