From 5fe1241c559154ecd2767020b108506bcf2c6451 Mon Sep 17 00:00:00 2001 From: Chris Pryer Date: Thu, 29 Feb 2024 21:40:49 -0500 Subject: [PATCH] Skip `uv compile` step for URL-based dependencies in `add` command --- rye/src/cli/add.rs | 38 +++++---- rye/tests/common/mod.rs | 17 ++++ .../wheels/twine-1.5.0-py2.py3-none-any.whl | Bin 0 -> 15816 bytes rye/tests/test_add.rs | 75 +++++++++++++++++- 4 files changed, 113 insertions(+), 17 deletions(-) create mode 100644 rye/tests/fixtures/wheels/twine-1.5.0-py2.py3-none-any.whl diff --git a/rye/src/cli/add.rs b/rye/src/cli/add.rs index 52162d3077..6bfe28ef20 100644 --- a/rye/src/cli/add.rs +++ b/rye/src/cli/add.rs @@ -468,23 +468,29 @@ fn resolve_requirements_with_uv( 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 mut new_req: Requirement = String::from_utf8_lossy(&rv.stdout).parse()?; + // we can skip the `uv compile` step for dependencies with direct references (URLs/paths) + let mut new_req = if matches!(req.version_or_url, Some(VersionOrUrl::Url(_))) { + req.clone() + } else { + 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); + } + String::from_utf8_lossy(&rv.stdout).parse()? + }; + if let Some(ref mut version_or_url) = new_req.version_or_url { if let VersionOrUrl::VersionSpecifier(ref mut specs) = version_or_url { *version_or_url = VersionOrUrl::VersionSpecifier(VersionSpecifiers::from_iter({ diff --git a/rye/tests/common/mod.rs b/rye/tests/common/mod.rs index a40d00f6e9..93ea8c1d2b 100644 --- a/rye/tests/common/mod.rs +++ b/rye/tests/common/mod.rs @@ -30,6 +30,11 @@ pub const INSTA_FILTERS: &[(&str, &str)] = &[ (r" in (\d+\.)?\d+(ms|s)\b", " in [EXECUTION_TIME]"), (r"\\\\?([\w\d.])", "/$1"), (r"rye.exe", "rye"), + // fixtures + ( + r"(\b[A-Z]:)?[\\/].*?[\\/]tests[\\/]fixtures[\\/]", + "[FIXTURES]/", + ), ]; fn marked_tempdir() -> TempDir { @@ -102,6 +107,18 @@ pub fn get_bin() -> PathBuf { get_cargo_bin("rye") } +#[allow(unused)] +pub fn get_fixtures_dir() -> PathBuf { + get_cargo_manifest_dir().join("tests").join("fixtures") +} + +#[allow(unused)] +pub fn get_cargo_manifest_dir() -> PathBuf { + std::env::var_os("CARGO_MANIFEST_DIR") + .map(PathBuf::from) + .unwrap() +} + pub struct Space { #[allow(unused)] tempdir: TempDir, diff --git a/rye/tests/fixtures/wheels/twine-1.5.0-py2.py3-none-any.whl b/rye/tests/fixtures/wheels/twine-1.5.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..af870cd4593ec95fc29a1d17d344cd5166900e11 GIT binary patch literal 15816 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

7`zAtCZ>)Eqj*T@Y{ZE5?Mfw6moY~ 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