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 "index repo" (`apt/private/index.bzl`) and the "package
repos" (`apt/private/deb_import.bzl`).
  • Loading branch information
jjmaestro committed Oct 28, 2024
1 parent f241766 commit 481f477
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 71 deletions.
4 changes: 2 additions & 2 deletions apt/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def _distroless_extension(module_ctx):
name = install.name,
lock = install.lock,
lock_content = lockf.as_json(),
package_template = install.package_template,
package_arch_build_template = install.package_arch_build_template,
)

if mod.is_root:
Expand All @@ -74,7 +74,7 @@ install = tag_class(attrs = {
doc = """Whether dependencies of dependencies should be resolved and added to the lockfile.""",
default = True,
),
"package_template": attr.label(doc = "(EXPERIMENTAL!) a template file for generated BUILD files."),
"package_arch_build_template": attr.label(doc = "(EXPERIMENTAL!) a template file for the generated package BUILD files per architecture."),
})

apt = module_extension(
Expand Down
6 changes: 3 additions & 3 deletions apt/index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def deb_index(
manifest,
lock = None,
nolock = False,
package_template = None,
package_arch_build_template = None,
resolve_transitive = True):
"""A convience repository macro for apt rules.
Expand Down Expand Up @@ -81,7 +81,7 @@ def deb_index(
manifest: label to a `manifest.yaml`
lock: label to a `lock.json`
nolock: bool, set to True if you explicitly want to run without a lock and avoid the DEBUG messages.
package_template: (EXPERIMENTAL!) a template file for generated BUILD files.
package_arch_build_template: (EXPERIMENTAL!) a template file for the generated package BUILD files per architecture.
Available template replacement keys are: `{target_name}`, `{deps}`, `{urls}`, `{name}`, `{arch}`, `{sha256}`, `{repo_name}`
resolve_transitive: whether dependencies of dependencies should be resolved and added to the lockfile.
"""
Expand All @@ -100,5 +100,5 @@ def deb_index(
_deb_package_index(
name = name,
lock = lock if lock else "@" + name + "_resolve//:lock.json",
package_template = package_template,
package_arch_build_template = package_arch_build_template,
)
2 changes: 1 addition & 1 deletion apt/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports_files([
"dpkg_statusd.sh",
"dpkg_status.sh",
"copy.sh.tmpl",
"package.BUILD.tmpl",
"package_arch.BUILD.tmpl",
])

bzl_library(
Expand Down
64 changes: 61 additions & 3 deletions apt/private/deb_import.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load(":util.bzl", "util")

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

def deb_import(**kwargs):
def deb_import(name, url, sha256):
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_arch_build(package, repo_prefix, repo_name, arch_template):
def deps_str(dependencies, arch, depth):
return ("\n" + " " * depth).join([
'"//%s/%s",' % (dep.name, arch)
for dep in dependencies
])

deb_import_key = make_deb_import_key(repo_name, package)

deps = '[":data"]'
if package.dependencies:
deps += """ + [
{deps}
]""".format(deps = deps_str(package.dependencies, package.arch, 8))
deps += ","

return arch_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 = "%s%s" % (repo_prefix, deb_import_key),
)
76 changes: 20 additions & 56 deletions apt/private/index.bzl
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
"apt-get"

load(":deb_import.bzl", "make_deb_import_key")
load(":deb_import.bzl", "deb_packages", "package_arch_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,52 +13,33 @@ alias(
"""

def _deb_package_index_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 architectures in lockf.packages.values():
for package in architectures.values():
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_arch_build(
package,
repo_prefix,
repo_name,
rctx.read(rctx.attr.package_arch_build_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_package_index = repository_rule(
Expand All @@ -85,5 +48,6 @@ deb_package_index = repository_rule(
"lock": attr.label(),
"lock_content": attr.string(doc = "INTERNAL: DO NOT USE"),
"package_template": attr.label(default = "//apt/private:package.BUILD.tmpl"),
"package_arch_build_template": attr.label(default = "//apt/private:package_arch.BUILD.tmpl"),
},
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Generated by rules_distroless. DO NOT EDIT."""

alias(
name = "data",
actual = "@{repo_name}//:data",
Expand All @@ -12,8 +14,6 @@ alias(

filegroup(
name = "{target_name}",
srcs = {deps}
visibility = ["//visibility:public"],
srcs = [
{deps}
] + [":data"]
)
)
4 changes: 2 additions & 2 deletions docs/apt.md

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

0 comments on commit 481f477

Please sign in to comment.