From b296c04a679ee204e2448558065f127dddad671d Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Sat, 17 Feb 2024 22:47:40 +0100 Subject: [PATCH] Add CMD support (#1523) ## Sumamry This PR adds the `activation.bat`, `deactivation.bat` and `pyenv.bat` files to add support for using uv from CMD. This PR further fixes an issue with our trampoline implementation where calling an executable like `black` failed: ``` (venv) C:\Users\Micha\astral\test>where black C:\Users\Micha\astral\test\.venv\Scripts\black.exe (venv) C:\Users\Micha\astral\test>black C:\Users\Micha\AppData\Local\Programs\Python\Python312\python.exe: can't open file 'C:\\Users\\Micha\\astral\\test\\black': [Errno 2] No such file or directory ``` The issue was that CMD doesn't extend `black` to its full path before passing it to the trampoline and our trampoline generated the command ` black` instead of ` .venv/Scripts/black`, and Python can't find `black` in the project directory. This PR fixes this by using the full executable name (that we already parsed out to discover the Python version). This adds one complication, we need to preserve the arguments without repeating the executable name that is the first argument. One option is to use [`CommandLineToArgvW`](https://learn.microsoft.com/de-de/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw) and then serialize the arguments 1.. to a string again. I decided against that. Win32 API calls are easy to get wrong. That's why I implemented the parsing rules specified in [`CommandLineToArgvW`](https://learn.microsoft.com/de-de/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw) to skip the first argument. Fixes https://github.com/astral-sh/uv/issues/1471 ## Test Plan https://github.com/astral-sh/uv/assets/1203881/bdb537b6-97c8-4f7e-bb4a-3a614eb5e0f6 Powershell continues to work https://github.com/astral-sh/uv/assets/1203881/6c806477-a7c6-4047-9ffc-5ed91c6f1c84 I haven't been able to test the aarch binaries. --- crates/gourgeist/src/activator/.gitattributes | 1 + crates/gourgeist/src/activator/activate.bat | 59 ++++++ crates/gourgeist/src/activator/deactivate.bat | 39 ++++ crates/gourgeist/src/activator/pydoc.bat | 22 ++ crates/gourgeist/src/bare.rs | 3 + crates/uv-trampoline/src/bounce.rs | 193 ++++++++++++------ .../uv-trampoline-aarch64-console.exe | Bin 14336 -> 16384 bytes .../trampolines/uv-trampoline-aarch64-gui.exe | Bin 14848 -> 16896 bytes .../uv-trampoline-x86_64-console.exe | Bin 15872 -> 16896 bytes .../trampolines/uv-trampoline-x86_64-gui.exe | Bin 15872 -> 17920 bytes 10 files changed, 258 insertions(+), 59 deletions(-) create mode 100644 crates/gourgeist/src/activator/.gitattributes create mode 100644 crates/gourgeist/src/activator/activate.bat create mode 100644 crates/gourgeist/src/activator/deactivate.bat create mode 100644 crates/gourgeist/src/activator/pydoc.bat diff --git a/crates/gourgeist/src/activator/.gitattributes b/crates/gourgeist/src/activator/.gitattributes new file mode 100644 index 000000000..69b47b5ad --- /dev/null +++ b/crates/gourgeist/src/activator/.gitattributes @@ -0,0 +1 @@ +*.bat text eol=crlf diff --git a/crates/gourgeist/src/activator/activate.bat b/crates/gourgeist/src/activator/activate.bat new file mode 100644 index 000000000..524f61d5a --- /dev/null +++ b/crates/gourgeist/src/activator/activate.bat @@ -0,0 +1,59 @@ +@REM Copyright (c) 2020-202x The virtualenv developers +@REM +@REM Permission is hereby granted, free of charge, to any person obtaining +@REM a copy of this software and associated documentation files (the +@REM "Software"), to deal in the Software without restriction, including +@REM without limitation the rights to use, copy, modify, merge, publish, +@REM distribute, sublicense, and/or sell copies of the Software, and to +@REM permit persons to whom the Software is furnished to do so, subject to +@REM the following conditions: +@REM +@REM The above copyright notice and this permission notice shall be +@REM included in all copies or substantial portions of the Software. +@REM +@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +@REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +@REM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +@REM NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +@REM LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +@REM OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +@REM WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@set "VIRTUAL_ENV={{ VIRTUAL_ENV_DIR }}" + +@set "VIRTUAL_ENV_PROMPT=venv" +@if NOT DEFINED VIRTUAL_ENV_PROMPT ( + @for %%d in ("%VIRTUAL_ENV%") do @set "VIRTUAL_ENV_PROMPT=%%~nxd" +) + +@if defined _OLD_VIRTUAL_PROMPT ( + @set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) else ( + @if not defined PROMPT ( + @set "PROMPT=$P$G" + ) + @if not defined VIRTUAL_ENV_DISABLE_PROMPT ( + @set "_OLD_VIRTUAL_PROMPT=%PROMPT%" + ) +) +@if not defined VIRTUAL_ENV_DISABLE_PROMPT ( + @set "PROMPT=(%VIRTUAL_ENV_PROMPT%) %PROMPT%" +) + +@REM Don't use () to avoid problems with them in %PATH% +@if defined _OLD_VIRTUAL_PYTHONHOME @goto ENDIFVHOME + @set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" +:ENDIFVHOME + +@set PYTHONHOME= + +@REM if defined _OLD_VIRTUAL_PATH ( +@if not defined _OLD_VIRTUAL_PATH @goto ENDIFVPATH1 + @set "PATH=%_OLD_VIRTUAL_PATH%" +:ENDIFVPATH1 +@REM ) else ( +@if defined _OLD_VIRTUAL_PATH @goto ENDIFVPATH2 + @set "_OLD_VIRTUAL_PATH=%PATH%" +:ENDIFVPATH2 + +@set "PATH=%VIRTUAL_ENV%\{{ BIN_NAME }};%PATH%" \ No newline at end of file diff --git a/crates/gourgeist/src/activator/deactivate.bat b/crates/gourgeist/src/activator/deactivate.bat new file mode 100644 index 000000000..95af1351b --- /dev/null +++ b/crates/gourgeist/src/activator/deactivate.bat @@ -0,0 +1,39 @@ +@REM Copyright (c) 2020-202x The virtualenv developers +@REM +@REM Permission is hereby granted, free of charge, to any person obtaining +@REM a copy of this software and associated documentation files (the +@REM "Software"), to deal in the Software without restriction, including +@REM without limitation the rights to use, copy, modify, merge, publish, +@REM distribute, sublicense, and/or sell copies of the Software, and to +@REM permit persons to whom the Software is furnished to do so, subject to +@REM the following conditions: +@REM +@REM The above copyright notice and this permission notice shall be +@REM included in all copies or substantial portions of the Software. +@REM +@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +@REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +@REM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +@REM NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +@REM LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +@REM OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +@REM WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +@set VIRTUAL_ENV= +@set VIRTUAL_ENV_PROMPT= + +@REM Don't use () to avoid problems with them in %PATH% +@if not defined _OLD_VIRTUAL_PROMPT @goto ENDIFVPROMPT + @set "PROMPT=%_OLD_VIRTUAL_PROMPT%" + @set _OLD_VIRTUAL_PROMPT= +:ENDIFVPROMPT + +@if not defined _OLD_VIRTUAL_PYTHONHOME @goto ENDIFVHOME + @set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + @set _OLD_VIRTUAL_PYTHONHOME= +:ENDIFVHOME + +@if not defined _OLD_VIRTUAL_PATH @goto ENDIFVPATH + @set "PATH=%_OLD_VIRTUAL_PATH%" + @set _OLD_VIRTUAL_PATH= +:ENDIFVPATH \ No newline at end of file diff --git a/crates/gourgeist/src/activator/pydoc.bat b/crates/gourgeist/src/activator/pydoc.bat new file mode 100644 index 000000000..8a8d590d2 --- /dev/null +++ b/crates/gourgeist/src/activator/pydoc.bat @@ -0,0 +1,22 @@ +@REM Copyright (c) 2020-202x The virtualenv developers +@REM +@REM Permission is hereby granted, free of charge, to any person obtaining +@REM a copy of this software and associated documentation files (the +@REM "Software"), to deal in the Software without restriction, including +@REM without limitation the rights to use, copy, modify, merge, publish, +@REM distribute, sublicense, and/or sell copies of the Software, and to +@REM permit persons to whom the Software is furnished to do so, subject to +@REM the following conditions: +@REM +@REM The above copyright notice and this permission notice shall be +@REM included in all copies or substantial portions of the Software. +@REM +@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +@REM EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +@REM MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +@REM NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +@REM LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +@REM OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +@REM WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +python.exe -m pydoc %* \ No newline at end of file diff --git a/crates/gourgeist/src/bare.rs b/crates/gourgeist/src/bare.rs index 4c7808d3a..efb2e0355 100644 --- a/crates/gourgeist/src/bare.rs +++ b/crates/gourgeist/src/bare.rs @@ -18,6 +18,9 @@ const ACTIVATE_TEMPLATES: &[(&str, &str)] = &[ ("activate.fish", include_str!("activator/activate.fish")), ("activate.nu", include_str!("activator/activate.nu")), ("activate.ps1", include_str!("activator/activate.ps1")), + ("activate.bat", include_str!("activator/activate.bat")), + ("deactivate.bat", include_str!("activator/deactivate.bat")), + ("pydoc.bat", include_str!("activator/pydoc.bat")), ( "activate_this.py", include_str!("activator/activate_this.py"), diff --git a/crates/uv-trampoline/src/bounce.rs b/crates/uv-trampoline/src/bounce.rs index 18cf561cd..690ce5bfb 100644 --- a/crates/uv-trampoline/src/bounce.rs +++ b/crates/uv-trampoline/src/bounce.rs @@ -37,43 +37,64 @@ fn getenv(name: &CStr) -> Option { } } -fn make_child_cmdline(is_gui: bool) -> Vec { - unsafe { - let python_exe = find_python_exe(is_gui); +/// Transform ` ` to `python `. +fn make_child_cmdline(is_gui: bool) -> CString { + let executable_name: CString = executable_filename(); + let python_exe = find_python_exe(is_gui, &executable_name); + let mut child_cmdline = Vec::::new(); - let my_cmdline = CStr::from_ptr(GetCommandLineA() as _); - let mut child_cmdline = Vec::::new(); - child_cmdline.push(b'"'); - for byte in python_exe.as_bytes() { - if *byte == b'"' { - // 3 double quotes: one to end the quoted span, one to become a literal double-quote, - // and one to start a new quoted span. - child_cmdline.extend(br#"""""#); - } else { - child_cmdline.push(*byte); - } - } - child_cmdline.extend(br#"" "#); - child_cmdline.extend(my_cmdline.to_bytes_with_nul()); - //eprintln!("new_cmdline: {}", core::str::from_utf8_unchecked(new_cmdline.as_slice())); - child_cmdline - } + push_quoted_path(&python_exe, &mut child_cmdline); + child_cmdline.push(b' '); + + // Use the full executable name because CMD only passes the name of the executable (but not the path) + // when e.g. invoking `black` instead of `/Scripts/black` and Python then fails + // to find the file. Unfortunately, this complicates things because we now need to split the executable + // from the arguments string... + push_quoted_path(&executable_name, &mut child_cmdline); + + push_arguments(&mut child_cmdline); + + child_cmdline.push(b'\0'); + + // Helpful when debugging trampline issues + // eprintln!( + // "executable_name: '{}'\nnew_cmdline: {}", + // core::str::from_utf8(executable_name.to_bytes(), + // core::str::from_utf8(child_cmdline.as_slice()) + // ); + + // SAFETY: We push the null termination byte at the end. + unsafe { CString::from_vec_with_nul_unchecked(child_cmdline) } } -/// The scripts are in the same directory as the Python interpreter, so we can find Python by getting the locations of -/// the current .exe and replacing the filename with `python[w].exe`. -fn find_python_exe(is_gui: bool) -> CString { - unsafe { - // MAX_PATH is a lie, Windows paths can be longer. - // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation - // But it's a good first guess, usually paths are short and we should only need a single attempt. - let mut buffer: Vec = vec![0; MAX_PATH as usize]; - loop { - // Call the Windows API function to get the module file name - let len = GetModuleFileNameA(0, buffer.as_mut_ptr(), buffer.len() as u32); +fn push_quoted_path(path: &CStr, command: &mut Vec) { + command.push(b'"'); + for byte in path.to_bytes() { + if *byte == b'"' { + // 3 double quotes: one to end the quoted span, one to become a literal double-quote, + // and one to start a new quoted span. + command.extend(br#"""""#); + } else { + command.push(*byte); + } + } + command.extend(br#"""#); +} - // That's the error condition because len doesn't include the trailing null byte - if len as usize == buffer.len() { +/// Returns the full path of the executable. +/// See https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea +fn executable_filename() -> CString { + // MAX_PATH is a lie, Windows paths can be longer. + // https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation + // But it's a good first guess, usually paths are short and we should only need a single attempt. + let mut buffer: Vec = vec![0; MAX_PATH as usize]; + loop { + // Call the Windows API function to get the module file name + let len = unsafe { GetModuleFileNameA(0, buffer.as_mut_ptr(), buffer.len() as u32) }; + + // That's the error condition because len doesn't include the trailing null byte + if len as usize == buffer.len() { + unsafe { let last_error = GetLastError(); match last_error { ERROR_INSUFFICIENT_BUFFER => { @@ -86,30 +107,84 @@ fn find_python_exe(is_gui: bool) -> CString { ExitProcess(1); } } - } else { - buffer.truncate(len as usize + b"\0".len()); - break; + } + } else { + buffer.truncate(len as usize + b"\0".len()); + break; + } + } + + unsafe { CString::from_vec_with_nul_unchecked(buffer) } +} + +/// The scripts are in the same directory as the Python interpreter, so we can find Python by getting the locations of +/// the current .exe and replacing the filename with `python[w].exe`. +fn find_python_exe(is_gui: bool, executable_name: &CStr) -> CString { + // Replace the filename (the last segment of the path) with "python.exe" + // Assumption: We are not in an encoding where a backslash byte can be part of a larger character. + let bytes = executable_name.to_bytes(); + let Some(last_backslash) = bytes.iter().rposition(|byte| *byte == b'\\') else { + eprintln!( + "Invalid current exe path (missing backslash): `{}`", + &*executable_name.to_string_lossy() + ); + unsafe { + ExitProcess(1); + } + }; + + let mut buffer = bytes[..last_backslash + 1].to_vec(); + buffer.extend_from_slice(if is_gui { + b"pythonw.exe" + } else { + b"python.exe" + }); + buffer.push(b'\0'); + + unsafe { CString::from_vec_with_nul_unchecked(buffer) } +} + +fn push_arguments(output: &mut Vec) { + let arguments_as_str = unsafe { + // SAFETY: We rely on `GetCommandLineA` to return a valid pointer to a null terminated string. + CStr::from_ptr(GetCommandLineA() as _) + }; + + // Skip over the executable name and then push the rest of the arguments + let after_executable = skip_one_argument(arguments_as_str.to_bytes()); + + output.extend_from_slice(after_executable) +} + +fn skip_one_argument(arguments: &[u8]) -> &[u8] { + let mut quoted = false; + let mut offset = 0; + let mut bytes_iter = arguments.iter().peekable(); + + // Implements https://learn.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=msvc-170 + while let Some(byte) = bytes_iter.next().copied() { + match byte { + b'"' => { + quoted = !quoted; + } + b'\\' => { + // Skip over escaped quotes or even number of backslashes. + if matches!(bytes_iter.peek().copied(), Some(&b'\"' | &b'\\')) { + offset += 1; + bytes_iter.next(); + } + } + byte => { + if byte.is_ascii_whitespace() && !quoted { + break; + } } } - // Replace the filename (the last segment of the path) with "python.exe" - // Assumption: We are not in an encoding where a backslash byte can be part of a larger character. - let Some(last_backslash) = buffer.iter().rposition(|byte| *byte == b'\\') else { - eprintln!( - "Invalid current exe path (missing backslash): `{}`", - CString::from_vec_with_nul_unchecked(buffer) - .to_string_lossy() - .as_ref() - ); - ExitProcess(1); - }; - buffer.truncate(last_backslash + 1); - buffer.extend_from_slice(if is_gui { - b"pythonw.exe\0" - } else { - b"python.exe\0" - }); - CString::from_vec_with_nul_unchecked(buffer) + + offset += 1; } + + &arguments[offset..] } fn make_job_object() -> HANDLE { @@ -137,7 +212,7 @@ fn make_job_object() -> HANDLE { } } -fn spawn_child(si: &STARTUPINFOA, child_cmdline: &mut [u8]) -> HANDLE { +fn spawn_child(si: &STARTUPINFOA, child_cmdline: CString) -> HANDLE { unsafe { if si.dwFlags & STARTF_USESTDHANDLES != 0 { // ignore errors from these -- if the handle's not inheritable/not valid, then nothing @@ -151,7 +226,7 @@ fn spawn_child(si: &STARTUPINFOA, child_cmdline: &mut [u8]) -> HANDLE { null(), // Why does this have to be mutable? Who knows. But it's not a mistake -- // MS explicitly documents that this buffer might be mutated by CreateProcess. - child_cmdline.as_mut_ptr(), + child_cmdline.into_bytes_with_nul().as_mut_ptr(), null(), null(), 1, @@ -236,14 +311,14 @@ fn clear_app_starting_state(child_handle: HANDLE) { pub fn bounce(is_gui: bool) -> ! { unsafe { - let mut child_cmdline = make_child_cmdline(is_gui); - let job = make_job_object(); + let child_cmdline = make_child_cmdline(is_gui); let mut si = MaybeUninit::::uninit(); GetStartupInfoA(si.as_mut_ptr()); let si = si.assume_init(); - let child_handle = spawn_child(&si, child_cmdline.as_mut_slice()); + let child_handle = spawn_child(&si, child_cmdline); + let job = make_job_object(); check!(AssignProcessToJobObject(job, child_handle)); // (best effort) Close all the handles that we can diff --git a/crates/uv-trampoline/trampolines/uv-trampoline-aarch64-console.exe b/crates/uv-trampoline/trampolines/uv-trampoline-aarch64-console.exe index 9f1d81b6e93fdc4988bb4960e492b234c81af513..d678453efd91ac64ec0f4fe932755e1536458ff6 100755 GIT binary patch literal 16384 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 delta 6380 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 delta 6981 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 diff --git a/crates/uv-trampoline/trampolines/uv-trampoline-x86_64-gui.exe b/crates/uv-trampoline/trampolines/uv-trampoline-x86_64-gui.exe index 0cd54ab12db138784fe776c6a127d8fb7e56cc73..6a1c98ebd87e138c198fe644034cdce79a0d919f 100644 GIT binary patch delta 7337 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 delta 6264 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 fJn$4!uOI3@RQGE8tGi!y9