From 06edcd18be554cd57d796f55acfbcafa90e861ac Mon Sep 17 00:00:00 2001 From: Silvano Cerza <3314350+silvanocerza@users.noreply.github.com> Date: Fri, 13 Dec 2024 22:31:08 +0100 Subject: [PATCH] Fix running Python commands that include paths with spaces (#21981) This PR fixes running Python commands that include paths with spaces by wrapping python commands and their arguments in quotation marks. I fixed this only in Python as I noticed this while trying to run `pytest` in Zed. Probably this is not the best approach as it doesn't fix other languages too, though I don't know enough about the codebase to fix it like that. I'm not even sure if it's actually feasible right now. I didn't add tests for this either as I couldn't really understand how to easily to that, I tried to look at other languages but couldn't find one that tests their `ContextProvider` directly. Release Notes: - Fix running Python commands that include paths with spaces --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> --- crates/languages/src/python.rs | 20 +++++++++++++------- crates/task/src/lib.rs | 4 ++++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/languages/src/python.rs b/crates/languages/src/python.rs index ec7ddde61d..bd88f8c1f8 100644 --- a/crates/languages/src/python.rs +++ b/crates/languages/src/python.rs @@ -315,7 +315,10 @@ impl ContextProvider for PythonContextProvider { toolchains .active_toolchain(worktree_id, "Python".into(), &mut cx) .await - .map_or_else(|| "python3".to_owned(), |toolchain| toolchain.path.into()) + .map_or_else( + || "python3".to_owned(), + |toolchain| format!("\"{}\"", toolchain.path), + ) } else { String::from("python3") }; @@ -336,14 +339,17 @@ impl ContextProvider for PythonContextProvider { TaskTemplate { label: "execute selection".to_owned(), command: PYTHON_ACTIVE_TOOLCHAIN_PATH.template_value(), - args: vec!["-c".to_owned(), VariableName::SelectedText.template_value()], + args: vec![ + "-c".to_owned(), + VariableName::SelectedText.template_value_with_whitespace(), + ], ..TaskTemplate::default() }, // Execute an entire file TaskTemplate { label: format!("run '{}'", VariableName::File.template_value()), command: PYTHON_ACTIVE_TOOLCHAIN_PATH.template_value(), - args: vec![VariableName::File.template_value()], + args: vec![VariableName::File.template_value_with_whitespace()], ..TaskTemplate::default() }, ]; @@ -358,7 +364,7 @@ impl ContextProvider for PythonContextProvider { args: vec![ "-m".to_owned(), "unittest".to_owned(), - VariableName::File.template_value(), + VariableName::File.template_value_with_whitespace(), ], ..TaskTemplate::default() }, @@ -369,7 +375,7 @@ impl ContextProvider for PythonContextProvider { args: vec![ "-m".to_owned(), "unittest".to_owned(), - "$ZED_CUSTOM_PYTHON_TEST_TARGET".to_owned(), + PYTHON_TEST_TARGET_TASK_VARIABLE.template_value_with_whitespace() ], tags: vec![ "python-unittest-class".to_owned(), @@ -388,7 +394,7 @@ impl ContextProvider for PythonContextProvider { args: vec![ "-m".to_owned(), "pytest".to_owned(), - VariableName::File.template_value(), + VariableName::File.template_value_with_whitespace(), ], ..TaskTemplate::default() }, @@ -399,7 +405,7 @@ impl ContextProvider for PythonContextProvider { args: vec![ "-m".to_owned(), "pytest".to_owned(), - "$ZED_CUSTOM_PYTHON_TEST_TARGET".to_owned(), + PYTHON_TEST_TARGET_TASK_VARIABLE.template_value_with_whitespace(), ], tags: vec![ "python-pytest-class".to_owned(), diff --git a/crates/task/src/lib.rs b/crates/task/src/lib.rs index cf3a414b11..d9f72b4258 100644 --- a/crates/task/src/lib.rs +++ b/crates/task/src/lib.rs @@ -135,6 +135,10 @@ impl VariableName { pub fn template_value(&self) -> String { format!("${self}") } + /// Generates a `"$VARIABLE"`-like string, to be used instead of `Self::template_value` when expanded value could contain spaces or special characters. + pub fn template_value_with_whitespace(&self) -> String { + format!("\"${self}\"") + } } impl FromStr for VariableName {