Skip to content

Commit

Permalink
Merge pull request #15 from ApexAI/no-python-in-setup
Browse files Browse the repository at this point in the history
Do not run Python during 'configure_ros2'
  • Loading branch information
kilian-funk authored Aug 28, 2024
2 parents 3bf5db7 + 4528389 commit 227322c
Show file tree
Hide file tree
Showing 18 changed files with 1,445 additions and 3,018 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.clwb/*
bazel-*

# Python caches
/**/__pycache__/
2 changes: 1 addition & 1 deletion repos/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

exports_files(glob(["*.lock"]))
exports_files(["bazel.repos"] + glob(["*.lock.bzl"]))

alias(
name = "repos_lock.update",
Expand Down
39 changes: 26 additions & 13 deletions repos/config/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,24 @@ load("@rules_ros//repos/config/detail:ros2_config.bzl", "ros2_config")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("@rules_ros//repos/config:distros.bzl", "DISTROS")

def _configure_ros2(*, name, distro_src, repo_index_overlays):
distro_src_wo_index = {k: v for k, v in distro_src.items() if k != "repo_index"}
distro_src_wo_index["build_file_content"] = 'exports_files(["ros2.repos"])'
def _configure_ros2(*, name, distro_src, repos_index_overlays):
distro_src_wo_setup_file = {k: v for k, v in distro_src.items() if k != "setup_file"}
distro_src_wo_setup_file["build_file_content"] = 'exports_files(["ros2.repos"])'

maybe(name = "ros2", **distro_src_wo_index)
maybe(name = "ros2", **distro_src_wo_setup_file)

ros2_config(
name = name,
repo_index = distro_src["repo_index"],
repo_index_overlays = [
repos_index = "@ros2//:ros2.repos",
repos_index_overlays = [
"@rules_ros//repos/config:bazel.repos",
] + repo_index_overlays,
] + repos_index_overlays,
setup_file = distro_src["setup_file"],
)

def configure_ros2(*, name = "ros2_config", repo_index_overlays = [], distro):
"""
"""
def configure_ros2(*, name = "ros2_config", repos_index_overlays = [], distro):
"""Configure ROS 2 repositories based on the given distro name."""

if type(distro) == type(""):
if not distro in DISTROS:
fail("Distro {} is not supported. Choose one of {}".format(distro, DISTROS.keys()))
Expand All @@ -41,6 +42,18 @@ def configure_ros2(*, name = "ros2_config", repo_index_overlays = [], distro):
if not type(distro) == type({}) or not "repo_rule" in distro:
fail("Distro either needs to be a string (e.g. 'iron') or a dict with arguments for the maybe repo rule")
distro_src = distro
if not type(repo_index_overlays) == type([]):
fail("repo_index_overlays needs to be a list of *.repos files")
_configure_ros2(name = name, distro_src = distro_src, repo_index_overlays = repo_index_overlays)
if not type(repos_index_overlays) == type([]):
fail("repos_index_overlays needs to be a list of *.repos files")
_configure_ros2(name = name, distro_src = distro_src, repos_index_overlays = repos_index_overlays)

def configure_repos(*, name = "ros2_config", repos_index, repos_index_overlays = [], setup_file):
"""Configure ROS 2 repositories based on the custom *.repos file."""

if not type(repos_index_overlays) == type([]):
fail("repos_index_overlays needs to be a list of *.repos files")
ros2_config(
name = name,
repos_index = repos_index,
repos_index_overlays = repos_index_overlays,
setup_file = setup_file,
)
14 changes: 10 additions & 4 deletions repos/config/detail/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@python_deps//:requirements.bzl", "requirement")
load("@ros2_config//:repos_lock_file.bzl", "REPOS_LOCK_FILE")
load("@ros2_config//:repos_index_file.bzl", "REPOS_INDEX_FILE")
load("@ros2_config//:repos_overlay_files.bzl", "REPOS_OVERLAY_FILES")
load("@ros2_config//:repos_setup_file.bzl", "REPOS_SETUP_FILE")

py_binary(
name = "repos_lock.update",
srcs = ["lock_repos.py"],
srcs = ["lock_repos.py", "generate_ros2_config.py"],
main = "lock_repos.py",
data = ["@ros2//:ros2.repos", REPOS_LOCK_FILE],
args = ["$(execpath @ros2//:ros2.repos)", "$(execpath {})".format(REPOS_LOCK_FILE)],
data = [REPOS_INDEX_FILE, REPOS_SETUP_FILE] + REPOS_OVERLAY_FILES,
args = [
"$(execpath {})".format(REPOS_INDEX_FILE),
"$(execpath {})".format(REPOS_SETUP_FILE),
] + ["$(execpath {})".format(f) for f in REPOS_OVERLAY_FILES],
deps = [requirement("pyyaml")],
visibility = ["//visibility:public"],
)
30 changes: 15 additions & 15 deletions repos/config/detail/generate_ros2_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#! /usr/bin/env python3
# Copyright 2024 Apex.AI, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -17,22 +16,27 @@
import yaml


HEADER = """
HEADER = """#
# DO NOT EDIT THIS FILE MANUALLY!
#
# To update, call `bazel run @rules_ros//repos/config:repos_lock.update` with the right distro set in the WORKSPACE
#
load("@bazel_tools//tools/build_defs/repo:utils.bzl", _maybe = "maybe")
load("@rules_ros//repos/config/detail:git_repository.bzl", _git_repository = "git_repository")
load("@rules_ros//repos/config/detail:http_archive.bzl", "http_archive")
load("@rules_ros//repos/config/detail:new_local_repository.bzl", _new_local_repository = "new_local_repository")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", _maybe = "maybe")
def setup():
pass
"""


def print_setup(repos):
print(HEADER)
def print_setup(repos, output_file):
print(HEADER, file=output_file)
for repo, spec in repos.items():
if spec.get("bazel") is not None:
print(build_load_command(repo, spec))
print(build_load_command(repo, spec), file=output_file)


def build_load_command(repo, spec):
Expand Down Expand Up @@ -102,17 +106,13 @@ def merge_dict(origin, to_add):
origin[key]=value


def main():
if len(sys.argv) < 2:
raise ValueError("At least one YAML file required as input.")
def print_setup_file(yaml_files, output_file):
if len(yaml_files) < 1:
raise ValueError("At least one YAML file is required as input.")

repos = {}
for input_path in sys.argv[1:]:
for input_path in yaml_files:
with (open(input_path,"r")) as repo_file:
merge_dict(repos, yaml.safe_load(repo_file)["repositories"])

print_setup(repos)


if __name__ == "__main__":
main()
print_setup(repos, output_file)
25 changes: 14 additions & 11 deletions repos/config/detail/lock_repos.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@
import os
import hashlib
from pathlib import Path
from generate_ros2_config import print_setup_file

REPO_TYPES = ["git", "tar"]

def main():
parser = argparse.ArgumentParser(description="Generate a lock file for a given repos file.")
parser.add_argument('repos', type=str, help='Input YAML file')
parser.add_argument('lock', type=str, help='Output YAML file with pinned repos')
parser.add_argument('--tar', action='store_true', help='Use the Github archive download.')
parser = argparse.ArgumentParser(description='Generate a Bazel setup file containing repo '
'rules to load every repository for a given repos file.')
parser.add_argument('repos', type=str, help='Input YAML *.repos file')
parser.add_argument('setup_bzl', type=str, help='Output Bazel setup file with repo rules.')
parser.add_argument('overlays', type=str, nargs='*', help='Additional YAML files are used as '
'overlays for *.repos file, e.g., to declare BUILD files for a repo.')
parser.add_argument('--tar', action='store_true', help='Use the GitHub archive download.')

args = parser.parse_args()
print(f"Calling {args.repos} {args.lock}")
print(f"Using {args.repos} to generate {args.setup_bzl}")

with open(args.repos, "r") as repos_file:
repos = yaml.safe_load(repos_file)
Expand All @@ -51,13 +55,12 @@ def main():
add_attributes(repos["repositories"][repo], additional_attributes)
print("{}: {}".format(repo, [*additional_attributes.values()]))

with open(args.lock, "w", encoding='utf8') as lock_file:
print(
"#\n# To update, call `bazel run @rules_ros//repos/config:repos_lock.update` with the right distro set in the WORKSPACE\n#",
file = lock_file
)
with tempfile.NamedTemporaryFile(mode='w+t', encoding='utf8') as lock_file:
yaml.dump(repos, lock_file, default_flow_style=False, allow_unicode=True)

with open(args.setup_bzl, mode='w', encoding='utf8') as setup_bzl:
print_setup_file(yaml_files=[lock_file.name] + args.overlays, output_file=setup_bzl)

def add_attributes(dictionary, additional_attributes):
for k,v in additional_attributes.items():
dictionary[k] = v
Expand Down Expand Up @@ -126,4 +129,4 @@ def fetch_repo_details(url, branch):


if __name__ == "__main__":
main()
main()
29 changes: 10 additions & 19 deletions repos/config/detail/ros2_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,28 @@
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "update_attrs")

_archive_attrs = {
"repo_index": attr.label(
"repos_index": attr.label(
doc = "YAML file containing the details of every ros2 repository.",
),
"repo_index_overlays": attr.label_list(
"repos_index_overlays": attr.label_list(
default = [],
doc = """
Additional YAML files used as overlays for `repo_index` e.g. to declare BUILD files
for a repo.
""",
),
"_generate_ros2_config": attr.label(
default = "generate_ros2_config.py",
),
"verbose": attr.bool(
default = False,
doc = "Prints the calling sequence to stdout.",
"setup_file": attr.label(
doc = "Resulting .bzl file containing repo rules to load every ros2 repository.",
),
}

def _ros2_config_impl(ctx):
result = ctx.execute(
[ctx.attr._generate_ros2_config, ctx.attr.repo_index] +
ctx.attr.repo_index_overlays,
)
if result.return_code != 0:
fail(result.stderr)

ctx.file("setup.bzl", content = result.stdout)
ctx.file("repos_lock_file.bzl", content = "REPOS_LOCK_FILE = '{}'".format(ctx.attr.repo_index))
ctx.file("WORKSPACE", content = "workspace(name = {}".format(ctx.name), executable = False)
ctx.file("BUILD", executable = False)
ctx.file("repos_index_file.bzl", content = "REPOS_INDEX_FILE = '{}'".format(ctx.attr.repos_index))
ctx.file("repos_overlay_files.bzl", content = "REPOS_OVERLAY_FILES = {}".format(["{}".format(l) for l in ctx.attr.repos_index_overlays]))
ctx.file("repos_setup_file.bzl", content = "REPOS_SETUP_FILE = '{}'".format(ctx.attr.setup_file))
ctx.symlink(ctx.attr.setup_file, "setup.bzl")
ctx.file("WORKSPACE", content = "workspace(name = {})".format(ctx.name), executable = False)
ctx.file("BUILD.bazel", content = "exports_files(glob(['**/*']))", executable = False)

return update_attrs(ctx.attr, _archive_attrs.keys(), {})

Expand Down
2 changes: 1 addition & 1 deletion repos/config/distros.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ DISTROS = {
url = _URL_TEMPLATE.format(distro, date),
strip_prefix = _STRIP_PREFIX_TEMPLATE.format(distro, date),
sha256 = sha,
repo_index = "@rules_ros//repos/config:ros2_{}.lock".format(distro),
setup_file = "@rules_ros//repos/config:setup_{}.lock.bzl".format(distro),
)
for distro, date, sha in _VERSIONS
}
Loading

0 comments on commit 227322c

Please sign in to comment.