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>
This commit is contained in:
Silvano Cerza 2024-12-13 22:31:08 +01:00 committed by GitHub
parent e53c1a8ee3
commit 06edcd18be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 17 additions and 7 deletions

View file

@ -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(),

View file

@ -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 {