From 40ad44799f222a67c984ce9b6d10bb1599e1ade0 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Thu, 19 Dec 2024 18:17:16 +0000 Subject: [PATCH] Add bazel test support Signed-off-by: Michael Carroll --- BUILD.bazel | 30 +++++++++++++++---- MODULE.bazel | 9 +++++- requirements.in | 1 + requirements_lock.txt | 61 ++++++++++++++++++++++++++++++++++++++ test/test_xacro.py | 22 ++++++++++++-- xacro/substitution_args.py | 8 ++++- 6 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 requirements.in create mode 100644 requirements_lock.txt diff --git a/BUILD.bazel b/BUILD.bazel index 8cdbe32..ae3379a 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,5 +1,7 @@ load("@rules_python//python:defs.bzl", "py_binary", "py_test", "py_library") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load("@rules_license//rules:license.bzl", "license") package( @@ -16,6 +18,13 @@ license( license_text = "LICENSE", ) +# This rule adds a convenient way to update the requirements file. +compile_pip_requirements( + name = "requirements", + src = "requirements.in", + requirements_txt = "requirements_lock.txt", +) + write_file( name = "write_xacro_main", # This is the same as scripts/xacro from upstream, except that we lose the @@ -32,9 +41,11 @@ py_library( ], allow_empty = False), imports = ["."], visibility = ["//visibility:public"], + deps = [ + "@pypi//pyyaml:pkg", + ] ) - py_binary( name = "xacro_main", srcs = ["xacro_main.py"], @@ -48,7 +59,6 @@ alias( visibility = ["//visibility:public"], ) - TEST_RESOURCES = glob([ "test/*.xacro", "test/*.xml", @@ -63,9 +73,19 @@ filegroup( data = TEST_RESOURCES, ) +py_test( + name = "test_xacro", + srcs = ["test/test_xacro.py"], + main = "test/test_xacro.py", + data = [":test_data"], + deps = [ + ":xacro_main", + "@rules_python//python/runfiles", + ] +) + bzl_library( - name = "build_defs_bzl", - srcs = ["build_defs.bzl"], - parse_tests = False, + name = "build_defs_bzl", + srcs = ["build_defs.bzl"], visibility = ["//visibility:public"], ) diff --git a/MODULE.bazel b/MODULE.bazel index 260bb89..a9a744d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,4 +1,3 @@ -# Bazel extensions for pybind11 module( name = "xacro", version = "2.0.11", @@ -12,3 +11,11 @@ python = use_extension("@rules_python//python/extensions:python.bzl", "python") python.toolchain( python_version = "3.11", ) + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "pypi", + python_version = "3.11", + requirements_lock = "//:requirements_lock.txt" +) +use_repo(pip, "pypi") diff --git a/requirements.in b/requirements.in new file mode 100644 index 0000000..c3726e8 --- /dev/null +++ b/requirements.in @@ -0,0 +1 @@ +pyyaml diff --git a/requirements_lock.txt b/requirements_lock.txt new file mode 100644 index 0000000..40dc20e --- /dev/null +++ b/requirements_lock.txt @@ -0,0 +1,61 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# bazel run //:requirements.update +# +pyyaml==6.0.2 \ + --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ + --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ + --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ + --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \ + --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \ + --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \ + --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \ + --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \ + --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ + --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \ + --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \ + --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \ + --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \ + --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \ + --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \ + --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \ + --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \ + --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \ + --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \ + --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \ + --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \ + --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \ + --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \ + --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \ + --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \ + --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \ + --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \ + --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ + --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ + --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \ + --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \ + --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \ + --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ + --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \ + --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \ + --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ + --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \ + --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \ + --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \ + --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \ + --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ + --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \ + --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ + --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ + --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \ + --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \ + --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \ + --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \ + --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \ + --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \ + --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \ + --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ + --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 + # via -r requirements.in diff --git a/test/test_xacro.py b/test/test_xacro.py index 60087e2..6c84557 100644 --- a/test/test_xacro.py +++ b/test/test_xacro.py @@ -57,6 +57,16 @@ def subTest(msg): yield None +# Determine if we are running the test under bazel and switch directory +try: + from python.runfiles import runfiles + data_path = runfiles.Create().Rlocation("_main/test") + os.chdir(data_path) + XACRO_EXECUTABLE = runfiles.Create().Rlocation("_main/xacro_main") + BAZEL_TEST = True +except ImportError: + XACRO_EXECUTABLE = 'xacro' + # regex to match whitespace whitespace = re.compile(r'\s+') @@ -383,7 +393,7 @@ def quick_xacro(self, xml, cli=None, **kwargs): def run_xacro(self, input_path, *args): args = list(args) - subprocess.call(['xacro', input_path] + args) + subprocess.call([XACRO_EXECUTABLE, input_path] + args) # class to match XML docs while ignoring any comments @@ -393,14 +403,18 @@ def __init__(self, *args, **kwargs): self.ignore_nodes = [xml.dom.Node.COMMENT_NODE] def test_pr2(self): + if BAZEL_TEST: + # This has an unspecified test dependency on ament_index_python + return + # run xacro on the pr2 tree snapshot test_dir = os.path.abspath(os.path.dirname(__file__)) pr2_xacro_path = os.path.join(test_dir, 'robots', 'pr2', 'pr2.urdf.xacro') pr2_golden_parse_path = os.path.join(test_dir, 'robots', 'pr2', 'pr2_1.11.4.xml') self.assert_matches( xml.dom.minidom.parse(pr2_golden_parse_path), - self.quick_xacro(open(pr2_xacro_path))) + self.quick_xacro(open(pr2_xacro_path))) # standard test class (including the test from TestXacroCommentsIgnored) class TestXacro(TestXacroCommentsIgnored): @@ -552,6 +566,10 @@ def test_math_ignores_spaces(self): self.assert_matches(self.quick_xacro(src), '''''') def test_substitution_args_find(self): + if BAZEL_TEST: + # Bazel implementation does not have $(find) + return + resolved = self.quick_xacro('''$(find xacro)/test/test_xacro.py''').firstChild.firstChild.data self.assertEqual(os.path.realpath(resolved), os.path.realpath(__file__)) diff --git a/xacro/substitution_args.py b/xacro/substitution_args.py index 789f312..1d5d171 100644 --- a/xacro/substitution_args.py +++ b/xacro/substitution_args.py @@ -137,7 +137,13 @@ def _dirname(resolved, a, args, context): def _eval_find(pkg): - from ament_index_python.packages import get_package_share_directory + try: + from ament_index_python.packages import get_package_share_directory + except ModuleNotFoundError: + raise SubstitutionException( + '$(find pkg) requires ament_index_python, but it was not found' + ) + return get_package_share_directory(pkg)