mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Move shell manipulation into its own crate (#5028)
## Summary This is going to get a little more complex as we support Windows, so carving it out.
This commit is contained in:
parent
ba217f1059
commit
a61464e802
11 changed files with 42 additions and 17 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -4456,7 +4456,6 @@ dependencies = [
|
||||||
"flate2",
|
"flate2",
|
||||||
"fs-err",
|
"fs-err",
|
||||||
"futures",
|
"futures",
|
||||||
"home",
|
|
||||||
"ignore",
|
"ignore",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"indicatif",
|
"indicatif",
|
||||||
|
@ -4476,7 +4475,6 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rustc-hash 2.0.0",
|
"rustc-hash 2.0.0",
|
||||||
"same-file",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
|
@ -4506,6 +4504,7 @@ dependencies = [
|
||||||
"uv-resolver",
|
"uv-resolver",
|
||||||
"uv-scripts",
|
"uv-scripts",
|
||||||
"uv-settings",
|
"uv-settings",
|
||||||
|
"uv-shell",
|
||||||
"uv-tool",
|
"uv-tool",
|
||||||
"uv-types",
|
"uv-types",
|
||||||
"uv-virtualenv",
|
"uv-virtualenv",
|
||||||
|
@ -5086,6 +5085,15 @@ dependencies = [
|
||||||
"uv-warnings",
|
"uv-warnings",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uv-shell"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"home",
|
||||||
|
"same-file",
|
||||||
|
"uv-fs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uv-state"
|
name = "uv-state"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
|
@ -41,13 +41,14 @@ uv-git = { path = "crates/uv-git" }
|
||||||
uv-installer = { path = "crates/uv-installer" }
|
uv-installer = { path = "crates/uv-installer" }
|
||||||
uv-macros = { path = "crates/uv-macros" }
|
uv-macros = { path = "crates/uv-macros" }
|
||||||
uv-normalize = { path = "crates/uv-normalize" }
|
uv-normalize = { path = "crates/uv-normalize" }
|
||||||
|
uv-python = { path = "crates/uv-python" }
|
||||||
uv-requirements = { path = "crates/uv-requirements" }
|
uv-requirements = { path = "crates/uv-requirements" }
|
||||||
uv-resolver = { path = "crates/uv-resolver" }
|
uv-resolver = { path = "crates/uv-resolver" }
|
||||||
uv-scripts = { path = "crates/uv-scripts" }
|
uv-scripts = { path = "crates/uv-scripts" }
|
||||||
uv-settings = { path = "crates/uv-settings" }
|
uv-settings = { path = "crates/uv-settings" }
|
||||||
|
uv-shell = { path = "crates/uv-shell" }
|
||||||
uv-state = { path = "crates/uv-state" }
|
uv-state = { path = "crates/uv-state" }
|
||||||
uv-tool = { path = "crates/uv-tool" }
|
uv-tool = { path = "crates/uv-tool" }
|
||||||
uv-python = { path = "crates/uv-python" }
|
|
||||||
uv-types = { path = "crates/uv-types" }
|
uv-types = { path = "crates/uv-types" }
|
||||||
uv-version = { path = "crates/uv-version" }
|
uv-version = { path = "crates/uv-version" }
|
||||||
uv-virtualenv = { path = "crates/uv-virtualenv" }
|
uv-virtualenv = { path = "crates/uv-virtualenv" }
|
||||||
|
|
|
@ -109,6 +109,10 @@ Utilities for reading package requirements from `pyproject.toml` and `requiremen
|
||||||
|
|
||||||
Functionality for resolving Python packages and their dependencies.
|
Functionality for resolving Python packages and their dependencies.
|
||||||
|
|
||||||
|
## [uv-shell](./uv-shell)
|
||||||
|
|
||||||
|
Utilities for detecting and manipulating shell environments.
|
||||||
|
|
||||||
## [uv-types](./uv-types)
|
## [uv-types](./uv-types)
|
||||||
|
|
||||||
Shared traits for uv, to avoid circular dependencies.
|
Shared traits for uv, to avoid circular dependencies.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name = "uv-normalize"
|
name = "uv-normalize"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Normalization for distribution, package and extra anmes"
|
description = "Normalization for distribution, package and extra names."
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
14
crates/uv-shell/Cargo.toml
Normal file
14
crates/uv-shell/Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "uv-shell"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2021"
|
||||||
|
description = "Utilities for detecting and manipulating shell environments"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
uv-fs = { workspace = true }
|
||||||
|
|
||||||
|
home = { workspace = true }
|
||||||
|
same-file = { workspace = true }
|
|
@ -4,7 +4,7 @@ use uv_fs::Simplified;
|
||||||
/// Shells for which virtualenv activation scripts are available.
|
/// Shells for which virtualenv activation scripts are available.
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||||
#[allow(clippy::doc_markdown)]
|
#[allow(clippy::doc_markdown)]
|
||||||
pub(crate) enum Shell {
|
pub enum Shell {
|
||||||
/// Bourne Again SHell (bash)
|
/// Bourne Again SHell (bash)
|
||||||
Bash,
|
Bash,
|
||||||
/// Friendly Interactive SHell (fish)
|
/// Friendly Interactive SHell (fish)
|
||||||
|
@ -32,7 +32,7 @@ impl Shell {
|
||||||
///
|
///
|
||||||
/// If `SHELL` is set, but contains a value that doesn't correspond to one of the supported
|
/// If `SHELL` is set, but contains a value that doesn't correspond to one of the supported
|
||||||
/// shell types, then return `None`.
|
/// shell types, then return `None`.
|
||||||
pub(crate) fn from_env() -> Option<Shell> {
|
pub fn from_env() -> Option<Shell> {
|
||||||
if std::env::var_os("NU_VERSION").is_some() {
|
if std::env::var_os("NU_VERSION").is_some() {
|
||||||
Some(Shell::Nushell)
|
Some(Shell::Nushell)
|
||||||
} else if std::env::var_os("FISH_VERSION").is_some() {
|
} else if std::env::var_os("FISH_VERSION").is_some() {
|
||||||
|
@ -68,7 +68,7 @@ impl Shell {
|
||||||
/// assert_eq!(Shell::from_shell_path("/usr/bin/zsh"), Some(Shell::Zsh));
|
/// assert_eq!(Shell::from_shell_path("/usr/bin/zsh"), Some(Shell::Zsh));
|
||||||
/// assert_eq!(Shell::from_shell_path("/opt/my_custom_shell"), None);
|
/// assert_eq!(Shell::from_shell_path("/opt/my_custom_shell"), None);
|
||||||
/// ```
|
/// ```
|
||||||
pub(crate) fn from_shell_path(path: impl AsRef<Path>) -> Option<Shell> {
|
pub fn from_shell_path(path: impl AsRef<Path>) -> Option<Shell> {
|
||||||
parse_shell_from_path(path.as_ref())
|
parse_shell_from_path(path.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ impl Shell {
|
||||||
/// Some of the logic here is based on rustup's rc file detection.
|
/// Some of the logic here is based on rustup's rc file detection.
|
||||||
///
|
///
|
||||||
/// See: <https://github.com/rust-lang/rustup/blob/fede22fea7b160868cece632bd213e6d72f8912f/src/cli/self_update/shell.rs#L197>
|
/// See: <https://github.com/rust-lang/rustup/blob/fede22fea7b160868cece632bd213e6d72f8912f/src/cli/self_update/shell.rs#L197>
|
||||||
pub(crate) fn configuration_files(self) -> Vec<PathBuf> {
|
pub fn configuration_files(self) -> Vec<PathBuf> {
|
||||||
let Some(home_dir) = home::home_dir() else {
|
let Some(home_dir) = home::home_dir() else {
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
|
@ -158,7 +158,7 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the given path is on the `PATH` in this shell.
|
/// Returns `true` if the given path is on the `PATH` in this shell.
|
||||||
pub(crate) fn contains_path(path: &Path) -> bool {
|
pub fn contains_path(path: &Path) -> bool {
|
||||||
std::env::var_os("PATH")
|
std::env::var_os("PATH")
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -167,7 +167,7 @@ impl Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the command necessary to prepend a directory to the `PATH` in this shell.
|
/// Returns the command necessary to prepend a directory to the `PATH` in this shell.
|
||||||
pub(crate) fn prepend_path(self, path: &Path) -> Option<String> {
|
pub fn prepend_path(self, path: &Path) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
Shell::Nushell => None,
|
Shell::Nushell => None,
|
||||||
Shell::Bash | Shell::Zsh => Some(format!(
|
Shell::Bash | Shell::Zsh => Some(format!(
|
|
@ -32,12 +32,13 @@ uv-fs = { workspace = true }
|
||||||
uv-git = { workspace = true }
|
uv-git = { workspace = true }
|
||||||
uv-installer = { workspace = true }
|
uv-installer = { workspace = true }
|
||||||
uv-normalize = { workspace = true }
|
uv-normalize = { workspace = true }
|
||||||
|
uv-python = { workspace = true, features = ["schemars"]}
|
||||||
uv-requirements = { workspace = true }
|
uv-requirements = { workspace = true }
|
||||||
uv-resolver = { workspace = true }
|
uv-resolver = { workspace = true }
|
||||||
uv-scripts = { workspace = true }
|
uv-scripts = { workspace = true }
|
||||||
uv-settings = { workspace = true, features = ["schemars"] }
|
uv-settings = { workspace = true, features = ["schemars"] }
|
||||||
|
uv-shell = { workspace = true }
|
||||||
uv-tool = { workspace = true }
|
uv-tool = { workspace = true }
|
||||||
uv-python = { workspace = true, features = ["schemars"]}
|
|
||||||
uv-types = { workspace = true }
|
uv-types = { workspace = true }
|
||||||
uv-virtualenv = { workspace = true }
|
uv-virtualenv = { workspace = true }
|
||||||
uv-warnings = { workspace = true }
|
uv-warnings = { workspace = true }
|
||||||
|
@ -50,7 +51,6 @@ clap = { workspace = true, features = ["derive", "string", "wrap_help"] }
|
||||||
flate2 = { workspace = true, default-features = false }
|
flate2 = { workspace = true, default-features = false }
|
||||||
fs-err = { workspace = true, features = ["tokio"] }
|
fs-err = { workspace = true, features = ["tokio"] }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
home = { workspace = true }
|
|
||||||
indexmap = { workspace = true }
|
indexmap = { workspace = true }
|
||||||
indicatif = { workspace = true }
|
indicatif = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
@ -59,7 +59,6 @@ owo-colors = { workspace = true }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
same-file = { workspace = true }
|
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
textwrap = { workspace = true }
|
textwrap = { workspace = true }
|
||||||
|
|
|
@ -22,6 +22,7 @@ use uv_python::{
|
||||||
EnvironmentPreference, PythonFetch, PythonInstallation, PythonPreference, PythonRequest,
|
EnvironmentPreference, PythonFetch, PythonInstallation, PythonPreference, PythonRequest,
|
||||||
};
|
};
|
||||||
use uv_requirements::RequirementsSpecification;
|
use uv_requirements::RequirementsSpecification;
|
||||||
|
use uv_shell::Shell;
|
||||||
use uv_tool::{entrypoint_paths, find_executable_directory, InstalledTools, Tool, ToolEntrypoint};
|
use uv_tool::{entrypoint_paths, find_executable_directory, InstalledTools, Tool, ToolEntrypoint};
|
||||||
use uv_warnings::{warn_user, warn_user_once};
|
use uv_warnings::{warn_user, warn_user_once};
|
||||||
|
|
||||||
|
@ -31,7 +32,6 @@ use crate::commands::tool::common::resolve_requirements;
|
||||||
use crate::commands::{ExitStatus, SharedState};
|
use crate::commands::{ExitStatus, SharedState};
|
||||||
use crate::printer::Printer;
|
use crate::printer::Printer;
|
||||||
use crate::settings::ResolverInstallerSettings;
|
use crate::settings::ResolverInstallerSettings;
|
||||||
use crate::shell::Shell;
|
|
||||||
|
|
||||||
/// Install a tool.
|
/// Install a tool.
|
||||||
pub(crate) async fn install(
|
pub(crate) async fn install(
|
||||||
|
|
|
@ -7,12 +7,12 @@ use tracing::debug;
|
||||||
|
|
||||||
use uv_configuration::PreviewMode;
|
use uv_configuration::PreviewMode;
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
|
use uv_shell::Shell;
|
||||||
use uv_tool::find_executable_directory;
|
use uv_tool::find_executable_directory;
|
||||||
use uv_warnings::warn_user_once;
|
use uv_warnings::warn_user_once;
|
||||||
|
|
||||||
use crate::commands::ExitStatus;
|
use crate::commands::ExitStatus;
|
||||||
use crate::printer::Printer;
|
use crate::printer::Printer;
|
||||||
use crate::shell::Shell;
|
|
||||||
|
|
||||||
/// Ensure that the executable directory is in PATH.
|
/// Ensure that the executable directory is in PATH.
|
||||||
pub(crate) async fn update_shell(preview: PreviewMode, printer: Printer) -> Result<ExitStatus> {
|
pub(crate) async fn update_shell(preview: PreviewMode, printer: Printer) -> Result<ExitStatus> {
|
||||||
|
|
|
@ -26,12 +26,12 @@ use uv_python::{
|
||||||
PythonPreference, PythonRequest,
|
PythonPreference, PythonRequest,
|
||||||
};
|
};
|
||||||
use uv_resolver::{ExcludeNewer, FlatIndex};
|
use uv_resolver::{ExcludeNewer, FlatIndex};
|
||||||
|
use uv_shell::Shell;
|
||||||
use uv_types::{BuildContext, BuildIsolation, HashStrategy};
|
use uv_types::{BuildContext, BuildIsolation, HashStrategy};
|
||||||
|
|
||||||
use crate::commands::reporters::PythonDownloadReporter;
|
use crate::commands::reporters::PythonDownloadReporter;
|
||||||
use crate::commands::{pip, ExitStatus, SharedState};
|
use crate::commands::{pip, ExitStatus, SharedState};
|
||||||
use crate::printer::Printer;
|
use crate::printer::Printer;
|
||||||
use crate::shell::Shell;
|
|
||||||
|
|
||||||
/// Create a virtual environment.
|
/// Create a virtual environment.
|
||||||
#[allow(clippy::unnecessary_wraps, clippy::fn_params_excessive_bools)]
|
#[allow(clippy::unnecessary_wraps, clippy::fn_params_excessive_bools)]
|
||||||
|
|
|
@ -53,7 +53,6 @@ pub(crate) mod commands;
|
||||||
pub(crate) mod logging;
|
pub(crate) mod logging;
|
||||||
pub(crate) mod printer;
|
pub(crate) mod printer;
|
||||||
pub(crate) mod settings;
|
pub(crate) mod settings;
|
||||||
pub(crate) mod shell;
|
|
||||||
pub(crate) mod version;
|
pub(crate) mod version;
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue