Skip to content

Commit 986ea83

Browse files
authored
Let XML executables/nodes be "required" (like in ROS 1) (#751)
* Let XML nodes be "required" Essentially on_exit="shutdown" is equivalent to ROS 1 required="true". This feature is implemented using the python launchfile on_exit mechanism. Right now "shutdown" is the only action accepted by on_exit, but theoretically more "on_exit" actions could be added later. Example: <executable cmd="ls" on_exit="shutdown"/> * Added tests for yaml Signed-off-by: Matthew Elwin <[email protected]>
1 parent d644861 commit 986ea83

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

launch/launch/actions/execute_process.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from typing import Text
2323

2424
from .execute_local import ExecuteLocal
25-
25+
from .shutdown_action import Shutdown
2626
from ..descriptions import Executable
2727
from ..frontend import Entity
2828
from ..frontend import expose_action
@@ -331,6 +331,16 @@ def parse(
331331
if name is not None:
332332
kwargs['name'] = parser.parse_substitution(name)
333333

334+
if 'on_exit' not in ignore:
335+
on_exit = entity.get_attr('on_exit', optional=True)
336+
if on_exit is not None:
337+
if on_exit == 'shutdown':
338+
kwargs['on_exit'] = [Shutdown()]
339+
else:
340+
raise ValueError(
341+
'Attribute on_exit of Entity node expected to be shutdown but got `{}`'
342+
'Other on_exit actions not yet supported'.format(on_exit))
343+
334344
if 'prefix' not in ignore:
335345
prefix = entity.get_attr('launch-prefix', optional=True)
336346
if prefix is not None:

launch_xml/test/launch_xml/test_executable.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import textwrap
2020

2121
from launch import LaunchService
22+
from launch.actions import Shutdown
2223
from launch.frontend import Parser
2324

2425
import pytest
@@ -67,5 +68,21 @@ def test_executable_wrong_subtag():
6768
assert 'whats_this' in str(excinfo.value)
6869

6970

71+
def test_executable_on_exit():
72+
xml_file = \
73+
"""\
74+
<launch>
75+
<executable cmd="ls" on_exit="shutdown"/>
76+
</launch>
77+
"""
78+
xml_file = textwrap.dedent(xml_file)
79+
root_entity, parser = Parser.load(io.StringIO(xml_file))
80+
ld = parser.parse_description(root_entity)
81+
executable = ld.entities[0]
82+
sub_entities = executable.get_sub_entities()
83+
assert len(sub_entities) == 1
84+
assert isinstance(sub_entities[0], Shutdown)
85+
86+
7087
if __name__ == '__main__':
7188
test_executable()

launch_yaml/test/launch_yaml/test_executable.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import textwrap
1919

2020
from launch import LaunchService
21+
from launch.actions import Shutdown
2122
from launch.frontend import Parser
2223

2324

@@ -64,5 +65,22 @@ def test_executable():
6465
assert(0 == ls.run())
6566

6667

68+
def test_executable_on_exit():
69+
yaml_file = \
70+
"""\
71+
launch:
72+
- executable:
73+
cmd: ls
74+
on_exit: shutdown
75+
"""
76+
yaml_file = textwrap.dedent(yaml_file)
77+
root_entity, parser = Parser.load(io.StringIO(yaml_file))
78+
ld = parser.parse_description(root_entity)
79+
executable = ld.entities[0]
80+
sub_entities = executable.get_sub_entities()
81+
assert len(sub_entities) == 1
82+
assert isinstance(sub_entities[0], Shutdown)
83+
84+
6785
if __name__ == '__main__':
6886
test_executable()

0 commit comments

Comments
 (0)