Skip to content

Commit

Permalink
uv: move all uv commands to uv.rs (#869)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsp authored Mar 19, 2024
1 parent b290cae commit 913e8a6
Show file tree
Hide file tree
Showing 9 changed files with 535 additions and 182 deletions.
6 changes: 4 additions & 2 deletions rye/src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::platform::{
use crate::pyproject::latest_available_python_version;
use crate::sources::py::{get_download_url, PythonVersion, PythonVersionRequest};
use crate::utils::{check_checksum, symlink_file, unpack_archive, CommandOutput, IoPathContext};
use crate::uv::Uv;
use crate::uv::UvBuilder;

/// this is the target version that we want to fetch
pub const SELF_PYTHON_TARGET_VERSION: PythonVersionRequest = PythonVersionRequest {
Expand Down Expand Up @@ -123,7 +123,9 @@ pub fn ensure_self_venv_with_toolchain(
}

// Ensure we have uv
let uv = Uv::ensure_exists(CommandOutput::Quiet)?;
let uv = UvBuilder::new()
.with_output(CommandOutput::Quiet)
.ensure_exists()?;

let version = match toolchain_version_request {
Some(ref version_request) => ensure_specific_self_toolchain(output, version_request)
Expand Down
52 changes: 13 additions & 39 deletions rye/src/cli/add.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::env;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::str::FromStr;
Expand All @@ -17,8 +16,8 @@ use crate::consts::VENV_BIN;
use crate::pyproject::{BuildSystem, DependencyKind, ExpandedSources, PyProject};
use crate::sources::py::PythonVersion;
use crate::sync::{autosync, sync, SyncOptions};
use crate::utils::{format_requirement, set_proxy_variables, CommandOutput};
use crate::uv::Uv;
use crate::utils::{format_requirement, get_venv_python_bin, set_proxy_variables, CommandOutput};
use crate::uv::UvBuilder;

const PACKAGE_FINDER_SCRIPT: &str = r#"
import sys
Expand Down Expand Up @@ -450,43 +449,18 @@ fn resolve_requirements_with_uv(
output: CommandOutput,
default_operator: &Operator,
) -> Result<(), Error> {
for req in requirements {
let mut cmd = Uv::ensure_exists(output)?.cmd();
cmd.arg("pip")
.arg("compile")
.arg("--python-version")
.arg(py_ver.format_simple())
.arg("--no-deps")
.arg("--no-header")
.arg("-")
.env("VIRTUAL_ENV", pyproject_toml.venv_path().as_os_str());
if pre {
cmd.arg("--prerelease=allow");
}
if output == CommandOutput::Quiet {
cmd.arg("-q");
}
// this primarily exists for testing
if let Ok(dt) = env::var("__RYE_UV_EXCLUDE_NEWER") {
cmd.arg("--exclude-newer").arg(dt);
}
let sources = ExpandedSources::from_sources(&pyproject_toml.sources()?)?;
sources.add_as_pip_args(&mut cmd);
let mut child = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let child_stdin = child.stdin.as_mut().unwrap();
writeln!(child_stdin, "{}", req)?;

let rv = child.wait_with_output()?;
if !rv.status.success() {
let log = String::from_utf8_lossy(&rv.stderr);
bail!("failed to resolve packages:\n{}", log);
}
let venv_path = pyproject_toml.venv_path();
let py_bin = get_venv_python_bin(&venv_path);
let sources = ExpandedSources::from_sources(&pyproject_toml.sources()?)?;

let uv = UvBuilder::new()
.with_output(output.quieter())
.with_sources(sources)
.ensure_exists()?
.venv(&venv_path, &py_bin, py_ver, None)?;

let mut new_req: Requirement = String::from_utf8_lossy(&rv.stdout).parse()?;
for req in requirements {
let mut new_req = uv.resolve(py_ver, req, pre, env::var("__RYE_UV_EXCLUDE_NEWER").ok())?;

// if a version or URL is already provided we just use the normalized package name but
// retain all old information.
Expand Down
32 changes: 18 additions & 14 deletions rye/src/cli/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::config::Config;
use crate::consts::VENV_BIN;
use crate::pyproject::PyProject;
use crate::utils::{get_venv_python_bin, CommandOutput};
use crate::uv::Uv;
use crate::uv::UvBuilder;

/// Prints the currently installed packages.
#[derive(Parser, Debug)]
Expand All @@ -27,26 +27,30 @@ pub fn execute(cmd: Args) -> Result<(), Error> {
}
let self_venv = ensure_self_venv(CommandOutput::Normal)?;

let status = if Config::current().use_uv() {
Uv::ensure_exists(CommandOutput::Normal)?
.cmd()
.arg("pip")
.arg("freeze")
.env("VIRTUAL_ENV", project.venv_path().as_os_str())
.status()?
if Config::current().use_uv() {
UvBuilder::new()
.with_output(CommandOutput::Normal)
.ensure_exists()?
.venv(
&project.venv_path(),
&python,
&project.venv_python_version()?,
None,
)?
.freeze()?;
} else {
Command::new(self_venv.join(VENV_BIN).join("pip"))
let status = Command::new(self_venv.join(VENV_BIN).join("pip"))
.arg("--python")
.arg(&python)
.arg("freeze")
.env("PYTHONWARNINGS", "ignore")
.env("PIP_DISABLE_PIP_VERSION_CHECK", "1")
.status()?
};
.status()?;

if !status.success() {
bail!("failed to print dependencies via pip");
}
if !status.success() {
bail!("failed to print dependencies via pip");
}
};

Ok(())
}
75 changes: 42 additions & 33 deletions rye/src/installer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::utils::{
get_short_executable_name, get_venv_python_bin, is_executable, symlink_file, CommandOutput,
IoPathContext,
};
use crate::uv::Uv;
use crate::uv::{UvBuilder, UvInstallOptions};

const FIND_SCRIPT_SCRIPT: &str = r#"
import os
Expand Down Expand Up @@ -141,50 +141,59 @@ pub fn install(
requirement.name.as_str(),
)?;

let mut cmd = if Config::current().use_uv() {
let mut cmd = Uv::ensure_exists(output)?.cmd();
cmd.arg("pip")
.arg("install")
.env("VIRTUAL_ENV", &target_venv_path)
.env("PYTHONWARNINGS", "ignore");
cmd
if Config::current().use_uv() {
let result = UvBuilder::new()
.with_output(output.quieter())
.with_sources(sources)
.ensure_exists()?
.venv(&target_venv_path, &py, &py_ver, None)?
.with_output(output)
.install(
&requirement,
UvInstallOptions {
importlib_workaround: py_ver.major == 3 && py_ver.minor == 7,
extras: extra_requirements.to_vec(),
},
);
if result.is_err() {
uninstall_helper(&target_venv_path, &shim_dir)?;
return result;
}
} else {
let mut cmd = Command::new(self_venv.join(VENV_BIN).join("pip"));
cmd.arg("--python")
.arg(&py)
.arg("install")
.env("PYTHONWARNINGS", "ignore")
.env("PIP_DISABLE_PIP_VERSION_CHECK", "1");
cmd
};

sources.add_as_pip_args(&mut cmd);
if output == CommandOutput::Verbose {
cmd.arg("--verbose");
} else {
if output == CommandOutput::Quiet {
cmd.arg("-q");
sources.add_as_pip_args(&mut cmd);
if output == CommandOutput::Verbose {
cmd.arg("--verbose");
} else {
if output == CommandOutput::Quiet {
cmd.arg("-q");
}
cmd.env("PYTHONWARNINGS", "ignore");
}
cmd.env("PYTHONWARNINGS", "ignore");
}
cmd.arg("--").arg(&requirement.to_string());
cmd.arg("--").arg(&requirement.to_string());

// we don't support versions below 3.7, but for 3.7 we need importlib-metadata
// to be installed
if py_ver.major == 3 && py_ver.minor == 7 {
cmd.arg("importlib-metadata==6.6.0");
}

for extra in extra_requirements {
cmd.arg(extra.to_string());
}
// we don't support versions below 3.7, but for 3.7 we need importlib-metadata
// to be installed
if py_ver.major == 3 && py_ver.minor == 7 {
cmd.arg("importlib-metadata==6.6.0");
}

let status = cmd.status()?;
if !status.success() {
uninstall_helper(&target_venv_path, &shim_dir)?;
bail!("tool installation failed");
}
for extra in extra_requirements {
cmd.arg(extra.to_string());
}

let status = cmd.status()?;
if !status.success() {
uninstall_helper(&target_venv_path, &shim_dir)?;
bail!("tool installation failed");
}
};
let out = Command::new(py)
.arg("-c")
.arg(FIND_SCRIPT_SCRIPT)
Expand Down
96 changes: 50 additions & 46 deletions rye/src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::pyproject::{
};
use crate::sources::py::PythonVersion;
use crate::utils::{set_proxy_variables, CommandOutput, IoPathContext};
use crate::uv::Uv;
use crate::uv::{UvBuilder, UvPackageUpgrade};

static FILE_EDITABLE_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^-e (file://.*?)\s*$").unwrap());
static DEP_COMMENT_RE: Lazy<Regex> =
Expand Down Expand Up @@ -390,25 +390,30 @@ fn generate_lockfile(
)?;
};

let mut cmd = if use_uv {
let mut cmd = Uv::ensure_exists(output)?.cmd();
cmd.arg("pip")
.arg("compile")
.arg("--no-header")
.env_remove("VIRTUAL_ENV")
.arg(format!(
"--python-version={}.{}.{}",
py_ver.major, py_ver.minor, py_ver.patch
));

if lock_options.pre {
cmd.arg("--prerelease=allow");
}
// this primarily exists for testing
if let Ok(dt) = env::var("__RYE_UV_EXCLUDE_NEWER") {
cmd.arg("--exclude-newer").arg(dt);
}
cmd
if use_uv {
let upgrade = {
if lock_options.update_all {
UvPackageUpgrade::All
} else if !lock_options.update.is_empty() {
UvPackageUpgrade::Packages(lock_options.update.clone())
} else {
UvPackageUpgrade::Nothing
}
};

UvBuilder::new()
.with_output(output.quieter())
.with_sources(sources.clone())
.with_workdir(workspace_path)
.ensure_exists()?
.lockfile(
py_ver,
requirements_file_in,
&requirements_file,
lock_options.pre,
env::var("__RYE_UV_EXCLUDE_NEWER").ok(),
upgrade,
)?;
} else {
let mut cmd = Command::new(get_pip_compile(py_ver, output)?);
// legacy pip tools requires some extra parameters
Expand All @@ -430,33 +435,32 @@ fn generate_lockfile(
if lock_options.pre {
cmd.arg("--pre");
}
cmd
};

cmd.arg(if output == CommandOutput::Verbose {
"--verbose"
} else {
"-q"
})
.arg("-o")
.arg(&requirements_file)
.arg(requirements_file_in)
.current_dir(workspace_path)
.env("PYTHONWARNINGS", "ignore")
.env("PROJECT_ROOT", make_project_root_fragment(workspace_path));

for pkg in &lock_options.update {
cmd.arg("--upgrade-package");
cmd.arg(pkg);
}
if lock_options.update_all {
cmd.arg("--upgrade");
}
sources.add_as_pip_args(&mut cmd);
set_proxy_variables(&mut cmd);
let status = cmd.status().context("unable to run pip-compile")?;
if !status.success() {
bail!("failed to generate lockfile");
cmd.arg(if output == CommandOutput::Verbose {
"--verbose"
} else {
"-q"
})
.arg("-o")
.arg(&requirements_file)
.arg(requirements_file_in)
.current_dir(workspace_path)
.env("PYTHONWARNINGS", "ignore")
.env("PROJECT_ROOT", make_project_root_fragment(workspace_path));

for pkg in &lock_options.update {
cmd.arg("--upgrade-package");
cmd.arg(pkg);
}
if lock_options.update_all {
cmd.arg("--upgrade");
}
sources.add_as_pip_args(&mut cmd);
set_proxy_variables(&mut cmd);
let status = cmd.status().context("unable to run pip-compile")?;
if !status.success() {
bail!("failed to generate lockfile");
};
};

finalize_lockfile(
Expand Down
8 changes: 8 additions & 0 deletions rye/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,14 @@ pub struct ExpandedSources {
}

impl ExpandedSources {
pub fn empty() -> ExpandedSources {
ExpandedSources {
index_urls: Vec::new(),
find_links: Vec::new(),
trusted_hosts: HashSet::new(),
}
}

/// Takes some sources and expands them.
pub fn from_sources(sources: &[SourceRef]) -> Result<ExpandedSources, Error> {
let mut index_urls = Vec::new();
Expand Down
Loading

0 comments on commit 913e8a6

Please sign in to comment.