Skip to content

Commit

Permalink
[parsing] Add support for remote packages
Browse files Browse the repository at this point in the history
  • Loading branch information
jwnimmer-tri committed Mar 21, 2023
1 parent 8ea4342 commit c75c4f0
Show file tree
Hide file tree
Showing 12 changed files with 638 additions and 31 deletions.
16 changes: 14 additions & 2 deletions bindings/pydrake/multibody/parsing_py.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,26 @@ PYBIND11_MODULE(parsing, m) {
using Class = PackageMap;
constexpr auto& cls_doc = doc.PackageMap;
py::class_<Class> cls(m, "PackageMap", cls_doc.doc);
{
using Nested = PackageMap::RemoteParams;
constexpr auto& nested_doc = cls_doc.RemoteParams;
py::class_<Nested> nested(cls, "RemoteParams", nested_doc.doc);
nested.def(ParamInit<Nested>());
nested.def("ToJson", &Nested::ToJson, nested_doc.ToJson.doc);
DefAttributesUsingSerialize(&nested, nested_doc);
DefReprUsingSerialize(&nested);
DefCopyAndDeepCopy(&nested);
}
cls // BR
.def(py::init<>(), cls_doc.ctor.doc)
.def(py::init<const Class&>(), py::arg("other"), "Copy constructor")
.def("Add", &Class::Add, py::arg("package_name"),
py::arg("package_path"), cls_doc.Add.doc)
.def("AddMap", &Class::AddMap, py::arg("other_map"), cls_doc.AddMap.doc)
.def("AddPackageXml", &Class::AddPackageXml, py::arg("filename"),
cls_doc.AddPackageXml.doc)
.def("AddRemote", &Class::AddRemote, py::arg("package_name"),
py::arg("params"))
.def("Contains", &Class::Contains, py::arg("package_name"),
cls_doc.Contains.doc)
.def("Remove", &Class::Remove, py::arg("package_name"),
Expand All @@ -53,8 +67,6 @@ PYBIND11_MODULE(parsing, m) {
return self.GetPath(package_name);
},
py::arg("package_name"), cls_doc.GetPath.doc)
.def("AddPackageXml", &Class::AddPackageXml, py::arg("filename"),
cls_doc.AddPackageXml.doc)
.def("PopulateFromFolder", &Class::PopulateFromFolder, py::arg("path"),
cls_doc.PopulateFromFolder.doc)
.def("PopulateFromEnvironment", &Class::PopulateFromEnvironment,
Expand Down
20 changes: 20 additions & 0 deletions bindings/pydrake/multibody/test/parsing_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ def test_package_map(self):
dut.PopulateFromEnvironment(environment_variable='TEST_TMPDIR')
dut.PopulateFromFolder(path=tmpdir)

def test_package_map_remote_params(self):
dut = PackageMap.RemoteParams(
urls=["file:///tmp/missing.zip"],
sha256="0" * 64,
archive_type="zip",
strip_prefix="prefix",)
self.assertIn("missing.zip", dut.ToJson())
copy.copy(dut)
copy.deepcopy(dut)

def test_package_map_add_remote(self):
dut = PackageMap.MakeEmpty()
package_name = "gibberish"
dut.AddRemote(package_name=package_name,
params=PackageMap.RemoteParams(
urls=["file:///tmp/missing.zip"],
sha256="0" * 64))
with self.assertRaisesRegex(RuntimeError, "downloader.*error"):
dut.GetPath(package_name)

def test_parser_file(self):
"""Calls every combination of arguments for the Parser methods which
use a file_name (not contents) and inspects their return type.
Expand Down
18 changes: 18 additions & 0 deletions multibody/parsing/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,14 @@ drake_cc_library(
visibility = ["//visibility:public"],
interface_deps = [
"//common:essential",
"//common:name_value",
],
deps = [
"//common:find_cache",
"//common:find_resource",
"//common:find_runfiles",
"//common:scope_exit",
"//common/yaml",
"@tinyxml2_internal//:tinyxml2",
],
)
Expand Down Expand Up @@ -622,6 +626,20 @@ drake_cc_googletest(
],
)

drake_cc_googletest(
name = "package_map_remote_test",
data = [
"test/package_map_test_packages/compressed.zip",
],
deps = [
":package_map",
"//common:find_cache",
"//common:find_resource",
"//common:scope_exit",
"//common/test_utilities:expect_throws_message",
],
)

drake_cc_googletest(
name = "drake_manifest_resolution_test",
data = [
Expand Down
7 changes: 6 additions & 1 deletion multibody/parsing/package_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,13 @@ def _run(*, temp_dir: Path, package_name: str, urls: List[str], sha256: str,


def _main(argv):
# We expect exactly two command-line arguments to this program:
# - The filename containing JSON data with our *actual* arguments.
# - A dummy argument that we'll ignore. (It's sometimes used by our caller
# to suppress valgrind when we're called from C++ code).
config_json, _ = argv

# Read our config file.
config_json, = argv
with open(config_json, "r") as f:
kwargs = json.load(f)

Expand Down
Loading

0 comments on commit c75c4f0

Please sign in to comment.