Skip to content

Commit e95fda9

Browse files
committed
support shell expression and python statements
Signed-off-by: Tin Lai <tin@tinyiu.com>
1 parent a886b7f commit e95fda9

File tree

2 files changed

+27
-20
lines changed

2 files changed

+27
-20
lines changed

examples/if-conditions.yaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,26 @@ environment:
55
windows:
66
# the following would not shows up as it evaluates to false
77
- window_name: window 1 ${ha} $Foo
8-
if:
9-
shell: ${Foo}
8+
if: ${Foo}
109
panes:
1110
- shell_command:
1211
- echo "this shouldn't shows up"
1312
- echo neither should this $Foo
1413
- window_name: window 2
1514
panes:
16-
# should not shows up
15+
# should not shows up; using shell expression
1716
- if:
18-
python: 1+1==3
17+
shell: '[ 5 -lt 4 ]'
1918
shell_command:
2019
- echo the above is a false statement
21-
# no if conditions
22-
- shell_command:
23-
- echo no condition
20+
# python conditions
21+
- if:
22+
python: import os; os.path.isdir('${PWD}')
23+
shell_command:
24+
- echo "checking for PWD (${PWD}) is a directory in python"
2425
- python -m http.server
2526
# display by default, but can be disabled by running `show_htop=false tmuxp load .....`
2627
- if: ${show_htop}
2728
shell_command:
28-
- echo the above is a true statement (by default), but can be disabled on-demand
29+
- echo "the above is a true statement (by default), but can be disabled on-demand"
2930
- htop

src/tmuxp/workspace/loader.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import os
55
import pathlib
6+
import subprocess
67
import typing as t
78

89
logger = logging.getLogger(__name__)
@@ -16,9 +17,10 @@ def optional_windows_and_pane(
1617
The function evaluates the 'if' condition specified in `workspace_dict` to determine inclusion:
1718
- If 'if' key is not present, it defaults to True.
1819
- If 'if' is a string or boolean, it's treated as a shell variable.
19-
- 'if' can be a dictionary containing 'shell' or 'python' keys with valid expressions.
20-
- 'shell' expressions are expanded and checked against true values ('y', 'yes', '1', 'on', 'true', 't').
21-
- 'python' expressions are evaluated using `eval()`
20+
- 'if' can be a dictionary containing 'shell', 'shell_var' or 'python' keys with valid expressions.
21+
- 'shell_var' expressions are expanded and checked against true values ('y', 'yes', '1', 'on', 'true', 't').
22+
- 'shell' expressions are evaluated using subprocess
23+
- 'python' expressions are evaluated using `exec()`
2224
2325
Parameters
2426
----------
@@ -35,18 +37,22 @@ def optional_windows_and_pane(
3537
if_cond = workspace_dict["if"]
3638
if isinstance(if_cond, (str, bool)):
3739
# treat this as shell variable
38-
if_cond = {"shell": if_cond}
39-
if not isinstance(if_cond, dict) or not ("shell" in if_cond or "python" in if_cond):
40+
if_cond = {"shell_var": if_cond}
41+
if not isinstance(if_cond, dict) or not any(predicate in if_cond for predicate in ("python", "shell", "shell_var")):
4042
raise ValueError(f"if conditions does not contains valid expression: {if_cond}")
43+
if "shell_var" in if_cond:
44+
if expandshell(str(if_cond["shell_var"])).lower() not in ("y", "yes", "1", "on", "true", "t"):
45+
return False
4146
if "shell" in if_cond:
42-
if isinstance(if_cond["shell"], str):
43-
if expandshell(if_cond["shell"]).lower() not in ("y", "yes", "1", "on", "true", "t"):
44-
return False
45-
elif isinstance(if_cond["shell"], bool):
46-
if not if_cond["shell"]:
47-
return False
47+
if subprocess.run(if_cond["shell"], shell=True).returncode != 0:
48+
return False
4849
if "python" in if_cond:
49-
if if_cond["python"] and not eval(if_cond["python"]): # dangerous
50+
# assign the result of the last statement from the python snippet
51+
py_statements = if_cond["python"].split(";")
52+
py_statements[-1] = f"ret={py_statements[-1]}"
53+
locals = {}
54+
exec(";".join(py_statements), {}, locals)
55+
if not locals['ret']:
5056
return False
5157
return True
5258

0 commit comments

Comments
 (0)