diff --git a/crates/uv-virtualenv/src/virtualenv.rs b/crates/uv-virtualenv/src/virtualenv.rs index a83979916..a4a021491 100644 --- a/crates/uv-virtualenv/src/virtualenv.rs +++ b/crates/uv-virtualenv/src/virtualenv.rs @@ -447,6 +447,13 @@ pub(crate) fn create( // Add all the activate scripts for different shells for (name, template) in ACTIVATE_TEMPLATES { + // csh has no way to determine its own script location, so a relocatable + // activate.csh is not possible. Skip it entirely instead of generating a + // non-functional script. + if relocatable && *name == "activate.csh" { + continue; + } + let path_sep = if cfg!(windows) { ";" } else { ":" }; let relative_site_packages = [ @@ -477,9 +484,7 @@ pub(crate) fn create( escape_posix_for_single_quotes(location.simplified().to_str().unwrap()) ) } - // Note: - // * relocatable activate scripts appear not to be possible in csh. - // * `activate.ps1` is already relocatable by default. + // Note: `activate.ps1` is already relocatable by default. _ => escape_posix_for_single_quotes(location.simplified().to_str().unwrap()), }; diff --git a/crates/uv/tests/it/venv.rs b/crates/uv/tests/it/venv.rs index ddaaad5cd..5d09ed391 100644 --- a/crates/uv/tests/it/venv.rs +++ b/crates/uv/tests/it/venv.rs @@ -1302,6 +1302,11 @@ fn verify_pyvenv_cfg_relocatable() { activate_nu.assert(predicates::str::contains( r"let virtual_env = (path self | path dirname | path dirname)", )); + + // csh cannot determine its own script location, so activate.csh should not + // be generated when --relocatable is used. + let activate_csh = scripts.child("activate.csh"); + activate_csh.assert(predicates::path::missing()); } /// With `relocatable-envs-default` preview feature, venvs are relocatable by default.