Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions muto_composer/plugins/launch_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,12 @@ def source_workspaces(self, current: StackManifest):
self.get_logger().error("Failed to parse source data as JSON.")
return

# Get stack name - check metadata.name first, then name, then default
stack_name = self._get_stack_name(current)
# Get stack name - handle both dict and StackManifest msg objects
if isinstance(current, dict):
stack_name = self._get_stack_name(current)
else:
# StackManifest msg: use .name attribute directly
stack_name = getattr(current, "name", None) or "default"
workspace_dir = os.path.join(WORKSPACES_PATH, stack_name.replace(" ", "_"))

def source_script(name: str, script_path: str) -> None:
Expand Down Expand Up @@ -390,8 +394,14 @@ def _launch_via_ros2_launch(self, context: StackContext, full_path: str, launch_
launch_file: Original launch file name (for tracking)
"""
# Source the workspace before launching
working_dir = os.path.dirname(os.path.dirname(full_path))
setup_bash = os.path.join(working_dir, "install", "setup.bash")
# Use context.workspace_path (the actual colcon workspace root) rather than
# deriving from the launch file path, which breaks for nested package structures.
workspace_dir = (
context.workspace_path
if context and context.workspace_path
else os.path.dirname(os.path.dirname(full_path))
)
setup_bash = os.path.join(workspace_dir, "install", "setup.bash")
if os.path.exists(setup_bash):
self._source_workspace(setup_bash)

Expand Down
1 change: 1 addition & 0 deletions test/test_launch_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def test_source_workspaces_no_current_stack(self, mock_environ_update, mock_subp
@patch("os.environ.update")
def test_source_workspace(self, mock_environ_update, mock_subprocess_run, mock_get_path):
mock_current = MagicMock()
mock_current.name = "Test Stack"
mock_current.source = json.dumps({"workspace_name": "/mock/file"})
# Mock the _get_stack_name method
with patch.object(self.node, "_get_stack_name", return_value="Test Stack"), patch(
Expand Down
Loading