From 44fd8b5c2622f7f53c9ca32d3144257a1eb8ab9c Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 19 Jul 2020 17:19:48 +0200 Subject: [PATCH 1/4] Fix test to demonstrate failure --- unit_test/environment_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unit_test/environment_test.py b/unit_test/environment_test.py index 0827cc0d..ab690a84 100644 --- a/unit_test/environment_test.py +++ b/unit_test/environment_test.py @@ -40,7 +40,7 @@ def test_inheritance(): def test_shell_eval(): - environment_recipe = parse_environment('VAR="$(echo "a test" string)"') + environment_recipe = parse_environment('VAR="$(echo "a test" string)"') env_copy = os.environ.copy() env_copy.pop('VAR', None) @@ -50,8 +50,8 @@ def test_shell_eval(): ) environment_cmds = environment_recipe.as_shell_commands() - assert environment_dict['VAR'] == 'a test string' - assert environment_cmds == ['export VAR="$(echo "a test" string)"'] + assert environment_dict['VAR'] == 'a test string' + assert environment_cmds == ['export VAR="$(echo "a test" string)"'] def test_shell_eval_and_env(): From 3a2d7a21b114c14ee93d29bbc7b16affec251ad5 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 19 Jul 2020 17:32:07 +0200 Subject: [PATCH 2/4] Fix quotes-in-commandsubstitution problem with well-placed shlex.quote --- cibuildwheel/bashlex_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 57791b2c..e09752f2 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -97,7 +97,7 @@ def evaluate_nodes_as_compound_command(nodes: Sequence[bashlex.ast.node], contex def evaluate_nodes_as_simple_command(nodes: List[bashlex.ast.node], context: NodeExecutionContext): - words = [evaluate_node(part, context=context) for part in nodes] + words = [shlex.quote(evaluate_node(part, context=context)) for part in nodes] command = ' '.join(words) return context.executor(command, context.environment) From 28af49a0069916a1a23e21363fead380ab0ff292 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 19 Jul 2020 17:37:25 +0200 Subject: [PATCH 3/4] Simplify by removing shlex.quote and shlex.split when using EnvironmentExecutor --- cibuildwheel/bashlex_eval.py | 10 ++++------ cibuildwheel/docker_container.py | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index e09752f2..8461d4c8 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -1,15 +1,14 @@ -import shlex import subprocess from typing import Callable, Dict, List, NamedTuple, Optional, Sequence import bashlex # type: ignore # a function that takes a shell command and the environment, and returns the result -EnvironmentExecutor = Callable[[str, Dict[str, str]], str] +EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str] -def local_environment_executor(command: str, env: Dict[str, str]) -> str: - return subprocess.check_output(shlex.split(command), env=env, universal_newlines=True) +def local_environment_executor(command: List[str], env: Dict[str, str]) -> str: + return subprocess.check_output(command, env=env, universal_newlines=True) class NodeExecutionContext(NamedTuple): @@ -97,8 +96,7 @@ def evaluate_nodes_as_compound_command(nodes: Sequence[bashlex.ast.node], contex def evaluate_nodes_as_simple_command(nodes: List[bashlex.ast.node], context: NodeExecutionContext): - words = [shlex.quote(evaluate_node(part, context=context)) for part in nodes] - command = ' '.join(words) + command = [evaluate_node(part, context=context) for part in nodes] return context.executor(command, context.environment) diff --git a/cibuildwheel/docker_container.py b/cibuildwheel/docker_container.py index 41b2f42f..c3b226aa 100644 --- a/cibuildwheel/docker_container.py +++ b/cibuildwheel/docker_container.py @@ -180,9 +180,9 @@ class DockerContainer: 'import sys, json, os; json.dump(os.environ.copy(), sys.stdout)' ], capture_output=True)) - def environment_executor(self, command: str, environment: Dict[str, str]) -> str: + def environment_executor(self, command: List[str], environment: Dict[str, str]) -> str: # used as an EnvironmentExecutor to evaluate commands and capture output - return self.call(shlex.split(command), env=environment) + return self.call(command, env=environment) def shell_quote(path: PurePath) -> str: From c5a98377843b37127ff4a069fa84b2562949b9df Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Sun, 19 Jul 2020 19:46:40 +0100 Subject: [PATCH 4/4] Update cibuildwheel/bashlex_eval.py --- cibuildwheel/bashlex_eval.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index 8461d4c8..2c61bc54 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -3,7 +3,7 @@ from typing import Callable, Dict, List, NamedTuple, Optional, Sequence import bashlex # type: ignore -# a function that takes a shell command and the environment, and returns the result +# a function that takes a command and the environment, and returns the result EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str]