From 98a7610999b1dab4e6463db06c9a61e8459a70ce Mon Sep 17 00:00:00 2001 From: Nat Noordanus Date: Sat, 30 Sep 2023 17:33:29 +0200 Subject: [PATCH] Use quotes to improve accuracy of logged commands #169 --- poethepoet/task/cmd.py | 3 ++- poethepoet/task/script.py | 3 ++- tests/fixtures/scripts_project/pyproject.toml | 2 +- tests/test_cmd_tasks.py | 6 +++--- tests/test_default_value.py | 7 +++++-- tests/test_envfile.py | 7 ++++--- tests/test_includes.py | 8 ++++---- tests/test_poe_config.py | 16 +++++++++++----- tests/test_poetry_plugin.py | 4 ++-- tests/test_ref_task.py | 2 +- tests/test_script_tasks.py | 10 +++++----- tests/test_sequence_tasks.py | 14 +++++++------- tests/test_task_running.py | 2 +- 13 files changed, 48 insertions(+), 36 deletions(-) diff --git a/poethepoet/task/cmd.py b/poethepoet/task/cmd.py index afcd74c30..fed74905d 100644 --- a/poethepoet/task/cmd.py +++ b/poethepoet/task/cmd.py @@ -1,3 +1,4 @@ +import shlex from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Tuple, Type, Union from ..exceptions import PoeException @@ -41,7 +42,7 @@ def _handle_run( cmd = (*self._resolve_args(context, env), *extra_args) - self._print_action(" ".join(cmd), context.dry) + self._print_action(shlex.join(cmd), context.dry) return context.get_executor(self.invocation, env, self.options).execute( cmd, use_exec=self.options.get("use_exec", False) diff --git a/poethepoet/task/script.py b/poethepoet/task/script.py index 4b1663ca6..774f4a3e0 100644 --- a/poethepoet/task/script.py +++ b/poethepoet/task/script.py @@ -1,4 +1,5 @@ import re +import shlex from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, Tuple, Type, Union from ..exceptions import ExpressionParseError @@ -65,7 +66,7 @@ def _handle_run( # windows cmd = ("python", "-c", "".join(script)) - self._print_action(" ".join(argv), context.dry) + self._print_action(shlex.join(argv), context.dry) return context.get_executor(self.invocation, env, self.options).execute( cmd, use_exec=self.options.get("use_exec", False) ) diff --git a/tests/fixtures/scripts_project/pyproject.toml b/tests/fixtures/scripts_project/pyproject.toml index d84cbfdf7..7b2ed709b 100644 --- a/tests/fixtures/scripts_project/pyproject.toml +++ b/tests/fixtures/scripts_project/pyproject.toml @@ -14,7 +14,7 @@ default_array_item_task_type = "cmd" [tool.poe.tasks] # Interpret subtasks as cmd instead of ref -composite_task = ["poe_test_echo Hello", "poe_test_echo World!"] +composite_task = ["poe_test_echo Hello", "poe_test_echo 'World!'"] # test_setting_default_task_type echo-args = "pkg:echo_args" diff --git a/tests/test_cmd_tasks.py b/tests/test_cmd_tasks.py index 12eb88e41..fbde5538c 100644 --- a/tests/test_cmd_tasks.py +++ b/tests/test_cmd_tasks.py @@ -2,7 +2,7 @@ def test_call_echo_task(run_poe_subproc, projects, esc_prefix): result = run_poe_subproc("echo", "foo", "!", project="cmds") assert result.capture == ( "Poe => poe_test_echo " - f"POE_ROOT:{projects['cmds']} Password1, task_args: foo !\n" + f"POE_ROOT:{projects['cmds']} Password1, task_args: foo '!'\n" ) assert result.stdout == f"POE_ROOT:{projects['cmds']} Password1, task_args: foo !\n" assert result.stderr == "" @@ -34,7 +34,7 @@ def test_cmd_task_with_args_and_extra_args(run_poe_subproc): "!", project="cmds", ) - assert result.capture == "Poe => poe_test_echo hey you guy !\n" + assert result.capture == "Poe => poe_test_echo hey you guy '!'\n" assert result.stdout == "hey you guy !\n" assert result.stderr == "" @@ -50,7 +50,7 @@ def test_cmd_alias_env_var(run_poe_subproc): def test_cmd_task_with_multiple_value_arg(run_poe_subproc): result = run_poe_subproc("multiple-value-arg", "hey", "1", "2", "3", project="cmds") - assert result.capture == "Poe => poe_test_echo first: hey second: 1 2 3\n" + assert result.capture == "Poe => poe_test_echo 'first: hey second: 1 2 3'\n" assert result.stdout == "first: hey second: 1 2 3\n" assert result.stderr == "" diff --git a/tests/test_default_value.py b/tests/test_default_value.py index 568a31467..c4b0504c3 100644 --- a/tests/test_default_value.py +++ b/tests/test_default_value.py @@ -1,7 +1,7 @@ def test_global_envfile_and_default(run_poe_subproc): result = run_poe_subproc("test", project="default_value") assert ( - "Poe => poe_test_echo !one! !two! !three! !four! !five! !six!\n" + "Poe => poe_test_echo '!one!' '!two!' '!three!' '!four!' '!five!' '!six!'\n" in result.capture ) assert result.stdout == "!one! !two! !three! !four! !five! !six!\n" @@ -19,6 +19,9 @@ def test_global_envfile_and_default_with_presets(run_poe_subproc): } result = run_poe_subproc("test", project="default_value", env=env) - assert "Poe => poe_test_echo !one! !two! !three! 444 !five! 666\n" in result.capture + assert ( + "Poe => poe_test_echo '!one!' '!two!' '!three!' 444 '!five!' 666\n" + in result.capture + ) assert result.stdout == "!one! !two! !three! 444 !five! 666\n" assert result.stderr == "" diff --git a/tests/test_envfile.py b/tests/test_envfile.py index 2f660ee9a..5bb32be59 100644 --- a/tests/test_envfile.py +++ b/tests/test_envfile.py @@ -1,7 +1,7 @@ def test_global_envfile_and_default(run_poe_subproc): result = run_poe_subproc("deploy-dev", project="envfile") assert ( - "Poe => poe_test_echo deploying to admin:12345@dev.example.com:8080\n" + "Poe => poe_test_echo 'deploying to admin:12345@dev.example.com:8080'\n" in result.capture ) assert result.stdout == "deploying to admin:12345@dev.example.com:8080\n" @@ -11,7 +11,7 @@ def test_global_envfile_and_default(run_poe_subproc): def test_task_envfile_and_default(run_poe_subproc): result = run_poe_subproc("deploy-prod", project="envfile") assert ( - "Poe => poe_test_echo deploying to admin:12345@prod.example.com/app\n" + "Poe => poe_test_echo 'deploying to admin:12345@prod.example.com/app'\n" in result.capture ) assert result.stdout == "deploying to admin:12345@prod.example.com/app\n" @@ -24,7 +24,8 @@ def test_multiple_envfiles(run_poe_subproc, projects): ) assert ( - "Poe => poe_test_echo VAL_A-VAL_B-VAL_C-VAL_D-VAL_E-VAL_F!!\n" in result.capture + "Poe => poe_test_echo 'VAL_A-VAL_B-VAL_C-VAL_D-VAL_E-VAL_F!!'\n" + in result.capture ) assert result.stdout == "VAL_A-VAL_B-VAL_C-VAL_D-VAL_E-VAL_F!!\n" assert result.stderr == "" diff --git a/tests/test_includes.py b/tests/test_includes.py index c1bb1008c..15990f9b0 100644 --- a/tests/test_includes.py +++ b/tests/test_includes.py @@ -13,14 +13,14 @@ def test_docs_for_include_toml_file(run_poe_subproc): def test_run_task_included_from_toml_file(run_poe_subproc): result = run_poe_subproc("greet", "Whirl!", project="includes") - assert result.capture == "Poe => poe_test_echo Hello Whirl!\n" + assert result.capture == "Poe => poe_test_echo Hello 'Whirl!'\n" assert result.stdout == "Hello Whirl!\n" assert result.stderr == "" def test_run_task_not_included_from_toml_file(run_poe_subproc): result = run_poe_subproc("echo", "Whirl!", project="includes") - assert result.capture == "Poe => poe_test_echo Whirl!\n" + assert result.capture == "Poe => poe_test_echo 'Whirl!'\n" assert result.stdout == "Whirl!\n" assert result.stderr == "" @@ -49,14 +49,14 @@ def test_running_from_multiple_includes(run_poe_subproc, projects): "Whirl!", project="includes", ) - assert result.capture == "Poe => poe_test_echo Whirl!\n" + assert result.capture == "Poe => poe_test_echo 'Whirl!'\n" assert result.stdout == "Whirl!\n" assert result.stderr == "" result = run_poe_subproc( f'--root={projects["includes/multiple_includes"]}', "greet", "Whirl!" ) - assert result.capture == "Poe => poe_test_echo Hello Whirl!\n" + assert result.capture == "Poe => poe_test_echo Hello 'Whirl!'\n" assert result.stdout == "Hello Whirl!\n" assert result.stderr == "" diff --git a/tests/test_poe_config.py b/tests/test_poe_config.py index d7224ea75..5323aa641 100644 --- a/tests/test_poe_config.py +++ b/tests/test_poe_config.py @@ -12,21 +12,27 @@ def test_setting_default_task_type(run_poe_subproc, projects, esc_prefix): project="scripts", env=no_venv, ) - assert result.capture == f"Poe => echo-args nat, welcome to {projects['scripts']}\n" + assert ( + result.capture == f"Poe => echo-args nat, 'welcome to {projects['scripts']}'\n" + ) assert result.stdout == f"hello nat, welcome to {projects['scripts']}\n" assert result.stderr == "" def test_setting_default_array_item_task_type(run_poe_subproc): result = run_poe_subproc("composite_task", project="scripts", env=no_venv) - assert result.capture == "Poe => poe_test_echo Hello\nPoe => poe_test_echo World!\n" + assert ( + result.capture == "Poe => poe_test_echo Hello\nPoe => poe_test_echo 'World!'\n" + ) assert result.stdout == "Hello\nWorld!\n" assert result.stderr == "" def test_setting_global_env_vars(run_poe_subproc): result = run_poe_subproc("travel", env=no_venv) - assert result.capture == "Poe => poe_test_echo from EARTH to\nPoe => travel[1]\n" + assert ( + result.capture == "Poe => poe_test_echo 'from EARTH to'\nPoe => 'travel[1]'\n" + ) assert result.stdout == "from EARTH to\nMARS\n" assert result.stderr == "" @@ -48,7 +54,7 @@ def test_override_default_verbosity(run_poe_subproc, low_verbosity_project_path) "test", cwd=low_verbosity_project_path, ) - assert result.capture == "Poe => poe_test_echo Hello there!\n" + assert result.capture == "Poe => poe_test_echo Hello 'there!'\n" assert result.stdout == "Hello there!\n" assert result.stderr == "" @@ -59,7 +65,7 @@ def test_partially_decrease_verbosity(run_poe_subproc, high_verbosity_project_pa "test", cwd=high_verbosity_project_path, ) - assert result.capture == "Poe => poe_test_echo Hello there!\n" + assert result.capture == "Poe => poe_test_echo Hello 'there!'\n" assert result.stdout == "Hello there!\n" assert result.stderr == "" diff --git a/tests/test_poetry_plugin.py b/tests/test_poetry_plugin.py index 8008b01d9..82ed12cf4 100644 --- a/tests/test_poetry_plugin.py +++ b/tests/test_poetry_plugin.py @@ -35,12 +35,12 @@ def test_task_with_cli_dependency(run_poetry, projects, is_windows): cwd=projects["poetry_plugin"], ) if is_windows: - assert result.stdout.startswith("Poe => cowpy yo yo yo") + assert result.stdout.startswith("Poe => cowpy 'yo yo yo'") assert "< yo yo yo >" in result.stdout else: # On POSIX cowpy expects notices its being called as a subprocess and tries # unproductively to take input from stdin - assert result.stdout.startswith("Poe => cowpy yo yo yo") + assert result.stdout.startswith("Poe => cowpy 'yo yo yo'") assert ( "< Cowacter, eyes:default, tongue:False, thoughts:False >" in result.stdout ) diff --git a/tests/test_ref_task.py b/tests/test_ref_task.py index 7cb0d1afe..15ab36210 100644 --- a/tests/test_ref_task.py +++ b/tests/test_ref_task.py @@ -7,6 +7,6 @@ def test_ref_passes_named_args_in_definition(run_poe_subproc): def test_ref_passes_extra_args_in_definition(run_poe_subproc): result = run_poe_subproc("greet-funny", project="refs") - assert result.capture == "Poe => poe_test_echo hi lol!\n" + assert result.capture == "Poe => poe_test_echo hi 'lol!'\n" assert result.stdout == "hi lol!\n" assert result.stderr == "" diff --git a/tests/test_script_tasks.py b/tests/test_script_tasks.py index c511fb200..35f74c141 100644 --- a/tests/test_script_tasks.py +++ b/tests/test_script_tasks.py @@ -87,8 +87,8 @@ def test_script_task_with_args_optional(run_poe_subproc, projects, is_windows): env=no_venv, ) assert result.capture == ( - f"Poe => greet-passed-args --greeting=hello --user=nat --optional=welcome " - f"to {named_args_project_path}\n" + f"Poe => greet-passed-args --greeting=hello --user=nat " + f"'--optional=welcome to {named_args_project_path}'\n" ) if is_windows: @@ -238,7 +238,7 @@ def test_script_with_positional_args(run_poe_subproc): result = run_poe_subproc( "greet-positional", "help!", "Santa", project="scripts", env=no_venv ) - assert result.capture == "Poe => greet-positional help! Santa\n" + assert result.capture == "Poe => greet-positional 'help!' Santa\n" assert result.stdout == "help! Santa\n" assert result.stderr == "" @@ -275,14 +275,14 @@ def test_script_with_positional_args_and_options(run_poe_subproc): result = run_poe_subproc( "greet-positional", "help!", "Santa", "--upper", project="scripts", env=no_venv ) - assert result.capture == "Poe => greet-positional help! Santa --upper\n" + assert result.capture == "Poe => greet-positional 'help!' Santa --upper\n" assert result.stdout == "HELP! SANTA\n" assert result.stderr == "" result = run_poe_subproc( "greet-positional", "--upper", "help!", "Santa", project="scripts", env=no_venv ) - assert result.capture == "Poe => greet-positional --upper help! Santa\n" + assert result.capture == "Poe => greet-positional --upper 'help!' Santa\n" assert result.stdout == "HELP! SANTA\n" assert result.stderr == "" diff --git a/tests/test_sequence_tasks.py b/tests/test_sequence_tasks.py index c7eb899ff..4aa1f80b8 100644 --- a/tests/test_sequence_tasks.py +++ b/tests/test_sequence_tasks.py @@ -2,8 +2,8 @@ def test_sequence_task(run_poe_subproc, esc_prefix): result = run_poe_subproc("composite_task", project="sequences") assert result.capture == ( "Poe => poe_test_echo Hello\n" - "Poe => poe_test_echo World!\n" - "Poe => poe_test_echo :)!\n" + "Poe => poe_test_echo 'World!'\n" + "Poe => poe_test_echo ':)!'\n" ) assert result.stdout == "Hello\nWorld!\n:)!\n" assert result.stderr == "" @@ -14,8 +14,8 @@ def test_another_sequence_task(run_poe_subproc, esc_prefix): result = run_poe_subproc("also_composite_task", project="sequences") assert result.capture == ( "Poe => poe_test_echo Hello\n" - "Poe => poe_test_echo World!\n" - "Poe => poe_test_echo :)!\n" + "Poe => poe_test_echo 'World!'\n" + "Poe => poe_test_echo ':)!'\n" ) assert result.stdout == "Hello\nWorld!\n:)!\n" assert result.stderr == "" @@ -25,8 +25,8 @@ def test_a_script_sequence_task_with_args(run_poe_subproc, esc_prefix): # This should be exactly the same as calling the composite_task task directly result = run_poe_subproc("greet-multiple", "--mouse=Jerry", project="sequences") assert result.capture == ( - "Poe => my_package:main(environ.get('cat'))\n" - "Poe => my_package:main(environ['mouse'])\n" + """Poe => 'my_package:main(environ.get('"'"'cat'"'"'))'\n""" + """Poe => 'my_package:main(environ['"'"'mouse'"'"'])'\n""" ) assert result.stdout == "hello Tom\nhello Jerry\n" assert result.stderr == "" @@ -37,7 +37,7 @@ def test_sequence_task_with_multiple_value_arg(run_poe_subproc): "multiple-value-arg", "hey", "1", "2", "3", project="sequences" ) assert result.capture == ( - "Poe => poe_test_echo first: hey\nPoe => poe_test_echo second: 1 2 3\n" + "Poe => poe_test_echo first: hey\nPoe => poe_test_echo second: '1 2 3'\n" "Poe => poe_test_echo Done.\n" ) assert result.stdout == "first: hey\nsecond: 1 2 3\nDone.\n" diff --git a/tests/test_task_running.py b/tests/test_task_running.py index 785a64852..eefb18089 100644 --- a/tests/test_task_running.py +++ b/tests/test_task_running.py @@ -5,7 +5,7 @@ def test_ref_task(run_poe_subproc, projects, esc_prefix): ) assert result.capture == ( "Poe => poe_test_echo " - f"POE_ROOT:{projects['example']} Password1, task_args: foo !\n" + f"POE_ROOT:{projects['example']} Password1, task_args: foo '!'\n" ) assert ( result.stdout == f"POE_ROOT:{projects['example']} Password1, task_args: foo !\n"