pixi-ros 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pixi_ros/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """Pixi-ROS: A Pixi extension for ROS package management."""
2
+
3
+ __version__ = "0.1.0"
pixi_ros/cli.py ADDED
@@ -0,0 +1,77 @@
1
+ """Main CLI entry point for pixi-ros."""
2
+
3
+ from typing import Annotated
4
+
5
+ import typer
6
+
7
+ from pixi_ros.init import init_workspace
8
+ from pixi_ros.mappings import get_ros_distros
9
+
10
+ app = typer.Typer(
11
+ name="pixi-ros",
12
+ help="Pixi extension for ROS package management",
13
+ no_args_is_help=True,
14
+ )
15
+
16
+ pkg_app = typer.Typer(help="Manage ROS packages")
17
+ app.add_typer(pkg_app, name="pkg")
18
+
19
+
20
+ @app.command()
21
+ def init(
22
+ distro: Annotated[
23
+ str | None,
24
+ typer.Option(
25
+ "--distro",
26
+ "-d",
27
+ help="ROS distribution (e.g., humble, iron, jazzy)",
28
+ ),
29
+ ] = None,
30
+ ):
31
+ """Initialize pixi.toml for a ROS workspace."""
32
+ # If distro not provided, prompt user to select one
33
+ if distro is None:
34
+ available_distros = get_ros_distros()
35
+ typer.echo("Available ROS distributions:")
36
+ for i, d in enumerate(available_distros, 1):
37
+ typer.echo(f" {i}. {d}")
38
+
39
+ # Prompt for selection
40
+ selection = typer.prompt(
41
+ "\nSelect a distribution (enter number or name)",
42
+ type=str,
43
+ )
44
+
45
+ # Parse selection (either number or name)
46
+ try:
47
+ selection_num = int(selection)
48
+ dist_count = len(available_distros)
49
+ if 1 <= selection_num <= dist_count:
50
+ distro = available_distros[selection_num - 1]
51
+ else:
52
+ typer.echo(
53
+ f"Error: Invalid selection.Please choose 1-{dist_count}",
54
+ err=True,
55
+ )
56
+ raise typer.Exit(code=1)
57
+ except ValueError as err:
58
+ # User entered a name instead of number
59
+ if selection in available_distros:
60
+ distro = selection
61
+ else:
62
+ typer.echo(
63
+ f"Error: '{selection}' is not a valid ROS distribution", err=True
64
+ )
65
+ typer.echo(f"Available: {', '.join(available_distros)}", err=True)
66
+ raise typer.Exit(code=1) from err
67
+
68
+ init_workspace(distro)
69
+
70
+
71
+ def main():
72
+ """Entry point for the CLI."""
73
+ app()
74
+
75
+
76
+ if __name__ == "__main__":
77
+ main()
pixi_ros/config.py ADDED
@@ -0,0 +1,34 @@
1
+ """Configuration handling for pixi-ros."""
2
+
3
+ from pathlib import Path
4
+
5
+
6
+ def find_config_file(start_path: Path | None = None) -> Path | None:
7
+ """
8
+ Search for .pixi-ros.toml configuration file.
9
+
10
+ Searches upward from start_path (or cwd) until a config file is found.
11
+
12
+ Args:
13
+ start_path: Starting directory for search (defaults to cwd)
14
+
15
+ Returns:
16
+ Path to config file if found, None otherwise
17
+ """
18
+ if start_path is None:
19
+ start_path = Path.cwd()
20
+
21
+ current = start_path.resolve()
22
+
23
+ # Search upward until we hit the root
24
+ while True:
25
+ config_path = current / ".pixi-ros.toml"
26
+ if config_path.exists():
27
+ return config_path
28
+
29
+ parent = current.parent
30
+ if parent == current: # Reached root
31
+ break
32
+ current = parent
33
+
34
+ return None
@@ -0,0 +1,56 @@
1
+ # Mapping files
2
+
3
+ This file contains mappings from ROS package names to their conda package equivalents.
4
+ These are split by channel. e.g. conda-forge.
5
+
6
+ ## Format
7
+
8
+ The file is based on the rosdep format, with the following structure:
9
+
10
+ - Keys are ROS package names, as presented in the package.xml (e.g. `udev`, `uncrustify`, `uuid`).
11
+ - Values are dictionaries mapping channels to lists of conda package names.
12
+
13
+ Example:
14
+
15
+ ```yaml
16
+ udev:
17
+ pixi:
18
+ linux: [libusb, libudev]
19
+ osx: [libusb]
20
+ win64: [libusb]
21
+ uncrustify:
22
+ pixi: [uncrustify]
23
+ unzip:
24
+ pixi: [unzip]
25
+ uuid:
26
+ pixi:
27
+ linux: [libuuid]
28
+ osx: []
29
+ win64: []
30
+ virtualenv:
31
+ pixi: [virtualenv]
32
+ ```
33
+
34
+ ## Customization
35
+
36
+ You can override these mappings by creating your own `pixi-ros/channel.yaml` file in:
37
+
38
+ 1. **Workspace directory** (highest priority): `./pixi-ros/channel.yaml`
39
+ 2. **User config directory**: `~/.pixi-ros/channel.yaml`
40
+ 3. **Built-in defaults** (these file): Used if no custom file is found
41
+
42
+ If you use the same channel name it will override the file completely.
43
+ The channel names are not used for specific package lookups, only to find the correct mapping file.
44
+ e.g. if you name the file `foobar.yaml` it will still be able to fetch the packages from other channels.
45
+
46
+
47
+ ## Fallback Behavior
48
+
49
+ If a package is not found in channel.yaml, pixi-ros will automatically:
50
+ 1. Convert underscores to dashes
51
+ 2. Prepend `ros-{distro}-`
52
+
53
+ For example, `my_custom_package` becomes `ros-humble-my-custom-package`.
54
+
55
+ ## Local packages
56
+ If a package is found in the `src` folder and also defined in the mapping, it will use the local package.
@@ -0,0 +1,125 @@
1
+ # Pixi-ROS Workspace
2
+
3
+ This ROS {distro} workspace is configured to use [Pixi](https://pixi.sh) for dependency management.
4
+
5
+ ## What is Pixi?
6
+
7
+ Pixi is a modern package manager that uses conda packages. It provides:
8
+ - Fast, reproducible dependency resolution
9
+ - Automatic environment management
10
+ - Reproducible with a lockfile
11
+ - Cross-platform support (Linux, macOS, Windows)
12
+
13
+ ## Getting Started
14
+
15
+ ### 1. Install Dependencies
16
+
17
+ ```bash
18
+ pixi install
19
+ ```
20
+
21
+ This installs all dependencies specified in `pixi.toml` from the configured channels.
22
+
23
+ ### 2. Build the Workspace
24
+
25
+ ```bash
26
+ pixi run build
27
+ ```
28
+
29
+ This runs `colcon build` to compile your ROS packages.
30
+
31
+ ### 3. Run Tests
32
+
33
+ ```bash
34
+ pixi run test
35
+ ```
36
+
37
+ This runs `colcon test` to execute your test suite.
38
+
39
+ ### 4. Clean Build Artifacts
40
+
41
+ ```bash
42
+ pixi run clean
43
+ ```
44
+
45
+ Removes `build/`, `install/`, and `log/` directories.
46
+
47
+ ### 5. Add additional dependencies
48
+
49
+ ```bash
50
+ pixi add <package-name>
51
+ # or for packages you would install with pip/uv/poetry:
52
+ pixi add --pypi <package-name>
53
+ ```
54
+
55
+ This adds new dependencies to `pixi.toml` and installs them.
56
+
57
+ ## Environment Activation
58
+
59
+ After the first build, pixi will automatically source the ROS setup script (`install/setup.bash`)
60
+ when you enter the pixi environment. This means you don't need to manually source it!
61
+
62
+ To activate the environment, run:
63
+
64
+ ```bash
65
+ pixi shell
66
+ ```
67
+
68
+ This starts a new shell with the ROS environment activated.
69
+
70
+ The environment will also be automatically activated when you run commands with `pixi run <command>`.
71
+
72
+ ## Adding Dependencies
73
+
74
+ ### Add a Conda Package
75
+
76
+ ```bash
77
+ pixi add <package-name>
78
+ ```
79
+
80
+ ### Add ROS Dependencies
81
+
82
+ When you add dependencies to your `package.xml` files, run:
83
+
84
+ ```bash
85
+ pixi ros init --distro {distro}
86
+ ```
87
+
88
+ This will update `pixi.toml` with the new dependencies.
89
+
90
+ ## Unavailable Packages
91
+
92
+ If you see commented-out packages in `pixi.toml` with `# NOT FOUND`, these packages
93
+ were not found in the configured channels. You may need to:
94
+ - Check if the package name is correct
95
+ - Add additional channels with `pixi project channel add <channel-url>`
96
+ - Install the package through pip: `pixi add --pypi <package-name>`
97
+ - Add it to [conda-forge](https://github.com/conda-forge/staged-recipes) or [RoboStack](https://robostack.github.io/Contributing.html)
98
+
99
+ ## Common Issues
100
+
101
+ ### Build Fails
102
+
103
+ If `pixi run build` fails:
104
+ 1. Make sure all dependencies are installed: `pixi install`
105
+ 2. Clean and rebuild: `pixi run clean && pixi run build`
106
+ 3. Validate the build task is correct for your workspace.
107
+
108
+ ### Environment Issues
109
+
110
+ If `ros2` commands aren't found:
111
+ 1. Run commands through pixi: `pixi run <command>`
112
+ 2. Or use a pixi shell: `pixi shell`
113
+
114
+ ## Learn More
115
+
116
+ - **Pixi Documentation**: https://pixi.sh
117
+ - **RoboStack Documentation**: https://robostack.github.io/
118
+ - **ROS {distro} Documentation**: https://docs.ros.org/en/{distro}/
119
+ - **pixi-ros GitHub**: https://github.com/prefix-dev/pixi-ros
120
+
121
+ ## Channels
122
+
123
+ This workspace uses the following channels:
124
+ - `https://prefix.dev/robostack-{distro}` - ROS packages
125
+ - `https://prefix.dev/conda-forge` - System dependencies