Skip to content

Commit 7c3f517

Browse files
Add support for arbitrary commands in formatted executables
This commit allows formatted_executable definitions to have a `commands` attribute, which can define the lines that should be in the formatted output. The default is to format all of the commands for the experiment, but this can be override to format arbitrary strings / variables. Item in the `commands` list will be expanded as a variable definition, and then split over new-lines before formatting based on the formatted executable definition.
1 parent bca398e commit 7c3f517

File tree

7 files changed

+33
-7
lines changed

7 files changed

+33
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
formatted_executables:
22
command:
33
join_separator: '\n'
4+
commands:
5+
- '{unformatted_command}'

lib/ramble/ramble/application.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,8 @@ def _define_formatted_executables(self):
11381138
based on the formatting requested.
11391139
"""
11401140

1141+
self.variables[self.keywords.unformatted_command] = "\n".join(self._command_list)
1142+
11411143
for var_name, formatted_conf in self._formatted_executables.items():
11421144
if var_name in self.variables:
11431145
raise FormattedExecutableError(
@@ -1159,13 +1161,17 @@ def _define_formatted_executables(self):
11591161

11601162
indentation = " " * n_indentation
11611163

1162-
formatted_str = ""
1163-
for cmd in self._command_list:
1164-
if formatted_str:
1165-
formatted_str += join_separator
1166-
formatted_str += indentation + prefix + cmd
1164+
commands_to_format = self._command_list
1165+
if namespace.commands in formatted_conf:
1166+
commands_to_format = formatted_conf[namespace.commands].copy()
1167+
1168+
formatted_lines = []
1169+
for command in commands_to_format:
1170+
expanded = self.expander.expand_var(command)
1171+
for out_line in expanded.split("\n"):
1172+
formatted_lines.append(indentation + prefix + out_line)
11671173

1168-
self.variables[var_name] = formatted_str
1174+
self.variables[var_name] = join_separator.join(formatted_lines)
11691175

11701176
def _derive_variables_for_template_path(self, workspace):
11711177
"""Define variables for template paths (for add_expand_vars)"""
@@ -2135,7 +2141,7 @@ def _copy_files(obj_inst, obj_type, repo_root):
21352141

21362142
repo_path = os.path.join(workspace.named_deployment, "object_repo")
21372143

2138-
repo_lock = lk.Lock(repo_path)
2144+
repo_lock = lk.Lock(os.path.join(repo_path, ".ramble-obj-repo.lock"))
21392145

21402146
with lk.WriteTransaction(repo_lock):
21412147
_copy_files(self, ramble.repository.ObjectTypes.applications, repo_path)

lib/ramble/ramble/keywords.py

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"batch_submit": {"type": key_type.required, "level": output_level.variable},
4848
"mpi_command": {"type": key_type.required, "level": output_level.variable},
4949
"experiment_template_name": {"type": key_type.reserved, "level": output_level.key},
50+
"unformatted_command": {"type": key_type.reserved, "level": output_level.variable},
5051
}
5152

5253

lib/ramble/ramble/namespace.py

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class namespace:
5959
indentation = "indentation"
6060
prefix = "prefix"
6161
join_separator = "join_separator"
62+
commands = "commands"
6263

6364
# For variants
6465
package_manager = "package_manager"

lib/ramble/ramble/schema/formatted_executables.py

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@
2626
"prefix": {"type": "string", "default": ""},
2727
"indentation": {"type": "number", "default": 0},
2828
"join_separator": {"type": "string", "default": "\n"},
29+
"commands": {
30+
"type": "array",
31+
"default": ["{unformatted_command}"],
32+
"items": {
33+
"type": "string",
34+
},
35+
},
2936
},
3037
},
3138
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
formatted_executables:
22
command:
33
join_separator: '\n'
4+
commands:
5+
- '{unformatted_command}'

lib/ramble/ramble/test/end_to_end/formatted_executables.py

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ def test_formatted_executables(mutable_config, mutable_mock_workspace_path, mock
3636
prefix: 'from_ws '
3737
indentation: 9
3838
join_separator: ';'
39+
ws_test_def:
40+
prefix: 'test_from_ws '
41+
indentation: 2
42+
commands:
43+
- '{mpi_command} test'
3944
applications:
4045
basic:
4146
formatted_executables:
@@ -74,6 +79,7 @@ def test_formatted_executables(mutable_config, mutable_mock_workspace_path, mock
7479
f.write("{app_exec_def}\n")
7580
f.write("{wl_exec_def}\n")
7681
f.write("{exp_exec_def}\n")
82+
f.write("{ws_test_def}\n")
7783
ws._re_read()
7884

7985
workspace("setup", "--dry-run", global_args=["-w", workspace_name])
@@ -88,6 +94,7 @@ def test_formatted_executables(mutable_config, mutable_mock_workspace_path, mock
8894
assert ";" + " " * 9 + "from_ws echo" in data
8995
assert "\n" + " " * 11 + "from_wl echo" in data
9096
assert "\n" + " " * 10 + "from_exp echo" in data
97+
assert "\n" + " " * 2 + "test_from_ws mpirun -n 16 -ppn 16 test" in data
9198

9299

93100
def test_redefined_executable_errors(

0 commit comments

Comments
 (0)