From 3698df8fe65cc593495e1747897eff5f980a2b8b Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Sun, 25 Aug 2024 23:25:05 +0200 Subject: [PATCH] Pin rosdistro version and package the script to be usable without `nix develop` Now the script works without updating rosdep, i.e., fetching the database from the Internet. --- flake.lock | 19 ++++++++++++- flake.nix | 66 +++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 25 ++++++++++++++++++ ros2nix/ros2nix.py | 10 ++++--- 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 pyproject.toml diff --git a/flake.lock b/flake.lock index 0ed9144..dc3be98 100644 --- a/flake.lock +++ b/flake.lock @@ -79,7 +79,24 @@ "nixpkgs": [ "nix-ros-overlay", "nixpkgs" - ] + ], + "rosdistro": "rosdistro" + } + }, + "rosdistro": { + "flake": false, + "locked": { + "lastModified": 1724605071, + "narHash": "sha256-Aj43AvXYn8etRXhyDc1RwJXV0g37NilmduevcYrcaZY=", + "owner": "ros", + "repo": "rosdistro", + "rev": "bab0a532400c16d89606a8c7fb450f26e6028745", + "type": "github" + }, + "original": { + "owner": "ros", + "repo": "rosdistro", + "type": "github" } }, "systems": { diff --git a/flake.nix b/flake.nix index 194070e..0aabd27 100644 --- a/flake.nix +++ b/flake.nix @@ -3,9 +3,10 @@ inputs.flake-utils.url = "github:numtide/flake-utils"; inputs.nix-ros-overlay.url = "github:lopsided98/nix-ros-overlay/master"; inputs.nixpkgs.follows = "nix-ros-overlay/nixpkgs"; + inputs.rosdistro = { url = "github:ros/rosdistro"; flake = false; }; outputs = - { nixpkgs, flake-utils, nix-ros-overlay, ... }: + { nixpkgs, flake-utils, nix-ros-overlay, ... } @ inputs: flake-utils.lib.eachDefaultSystem ( system: let @@ -13,6 +14,63 @@ inherit system; overlays = [ nix-ros-overlay.overlays.default ]; }; + rosdistro = pkgs.stdenv.mkDerivation { + pname = "rosdistro"; + version = inputs.rosdistro.lastModifiedDate; + src = inputs.rosdistro; + postPatch = '' + substituteInPlace rosdep/sources.list.d/20-default.list \ + --replace-fail https://raw.githubusercontent.com/ros/rosdistro/master/ file://${placeholder "out"}/ + ''; + postInstall = '' + mkdir -p $out + cp -r * $out + ''; + }; + rosdep-unwrapped = pkgs.python3Packages.rosdep.overrideAttrs ({ postPatch ? "", ...}: { + postPatch = postPatch + '' + substituteInPlace src/rosdep2/rep3.py \ + --replace-fail https://raw.githubusercontent.com/ros/rosdistro/master/ file://${rosdistro}/ + ''; + }); + rosdep-cache = pkgs.stdenv.mkDerivation { + pname = "rosdep-cache"; + version = inputs.rosdistro.lastModifiedDate; + nativeBuildInputs = [ + rosdep-unwrapped + ]; + ROSDEP_SOURCE_PATH = "${rosdistro}/rosdep/sources.list.d"; + ROSDISTRO_INDEX_URL = "file://${rosdistro}/index-v4.yaml"; + ROS_HOME = placeholder "out"; + buildCommand = '' + mkdir -p $out + rosdep update + ''; + }; + # rosdep with offline database + rosdep = pkgs.python3Packages.rosdep.overrideAttrs ({ postFixup ? "", ...}: { + postFixup = postFixup + '' + wrapProgram $out/bin/rosdep --set-default ROS_HOME ${rosdep-cache} + ''; + }); + ros2nix = pkgs.python3Packages.buildPythonApplication { + pname = "ros2nix"; + version = inputs.self.lastModifiedDate; + src = pkgs.lib.cleanSource ./.; + pyproject = true; + + nativeBuildInputs = with pkgs.python3Packages; [ + setuptools + ]; + propagatedBuildInputs = [ + pkgs.superflore + pkgs.nixfmt-rfc-style + ]; + makeWrapperArgs = [ + "--set-default ROS_HOME ${rosdep-cache}" + "--set-default ROSDEP_SOURCE_PATH ${rosdistro}/rosdep/sources.list.d" + ]; + }; in { devShells.default = pkgs.mkShell { @@ -23,6 +81,12 @@ pkgs.superflore pkgs.python3Packages.rosdep ]; + ROSDEP_SOURCE_PATH = "${rosdistro}/rosdep/sources.list.d"; + ROSDISTRO_INDEX_URL = "file://${rosdistro}/index-v4.yaml"; + }; + packages = { + default = ros2nix; + inherit rosdistro rosdep-cache rosdep ros2nix; }; } ); diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5c844cd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,25 @@ +[project] +name = "ros2nix" +version = "0.0.1" +authors = [ + { name="Michal Sojka", email="wsh@2x.cz" }, +] +description = "Convert ROS package.xml to Nix expression package.nix" +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache 2", + "Operating System :: OS Independent", +] + +[project.urls] +Homepage = "https://github.com/wentasah/ros2nix" +Issues = "https://github.com/wentasah/ros2nix/issues" + +[project.scripts] +ros2nix = "ros2nix.ros2nix:main" + +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" diff --git a/ros2nix/ros2nix.py b/ros2nix/ros2nix.py index 0544761..df8fa09 100755 --- a/ros2nix/ros2nix.py +++ b/ros2nix/ros2nix.py @@ -12,7 +12,7 @@ from rosinstall_generator.distro import get_distro from superflore.PackageMetadata import PackageMetadata from superflore.exceptions import UnresolvedDependency from superflore.generators.nix.nix_package import NixPackage -from nix_expression import NixExpression, NixLicense +from .nix_expression import NixExpression, NixLicense from superflore.utils import (download_file, get_distro_condition_context, get_distros, get_pkg_version, info, resolve_dep, retry_on_exception, warn) @@ -59,7 +59,7 @@ def get_output_file_name(pkg, args): return os.path.join(args.output_dir, fn) -def main(args): +def ros2nix(args): parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("source", nargs="+", help="Path to package.xml") # TODO or a directory containing package.xml or an ") @@ -170,7 +170,9 @@ def main(args): err("Failed to write derivation to disk!") raise e +def main(): + import sys + ros2nix(sys.argv[1:]) if __name__ == '__main__': - import sys - main(sys.argv[1:]) + main()