diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 79dc4c54dc2e..2194196f1c16 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -2382,8 +2382,6 @@ pub struct AddArgs { pub packages: Vec, /// Add all packages listed in the given `requirements.txt` files. - /// - /// Implies `--raw-sources`. #[arg(long, short, group = "sources", value_parser = parse_file_path)] pub requirements: Vec, diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index 3309deedd9f9..ed0e4640a3bf 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -351,31 +351,32 @@ impl Source { subdirectory, .. } => { - // We can only resolve a full commit hash from a pep508 URL, everything else is ambiguous. - let rev = match reference { - GitReference::FullCommit(ref mut rev) => Some(mem::take(rev)), - _ => None, - } - // Give precedence to an explicit argument. - .or(rev); - - // Error if the user tried to specify a reference but didn't disambiguate. - if reference != GitReference::DefaultBranch - && rev.is_none() - && tag.is_none() - && branch.is_none() - { - return Err(SourceError::UnresolvedReference( - reference.as_str().unwrap().to_owned(), - )); - } - - Source::Git { - rev, - tag, - branch, - git: repository, - subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), + if rev.is_none() && tag.is_none() && branch.is_none() { + let rev = match reference { + GitReference::FullCommit(ref mut rev) => Some(mem::take(rev)), + GitReference::Branch(ref mut rev) => Some(mem::take(rev)), + GitReference::Tag(ref mut rev) => Some(mem::take(rev)), + GitReference::ShortCommit(ref mut rev) => Some(mem::take(rev)), + GitReference::BranchOrTag(ref mut rev) => Some(mem::take(rev)), + GitReference::BranchOrTagOrCommit(ref mut rev) => Some(mem::take(rev)), + GitReference::NamedRef(ref mut rev) => Some(mem::take(rev)), + GitReference::DefaultBranch => None, + }; + Source::Git { + rev, + tag, + branch, + git: repository, + subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), + } + } else { + Source::Git { + rev, + tag, + branch, + git: repository, + subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), + } } } }; diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index c2dc96340a57..7eafe9ba0388 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -622,7 +622,7 @@ fn resolve_requirement( let source = match result { Ok(source) => source, Err(SourceError::UnresolvedReference(rev)) => { - anyhow::bail!( + bail!( "Cannot resolve Git reference `{rev}` for requirement `{name}`. Specify the reference with one of `--tag`, `--branch`, or `--rev`, or use the `--raw-sources` flag.", name = requirement.name ) diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 38a502cb7236..cfbb78650293 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -1113,16 +1113,6 @@ async fn run_project( .combine(Refresh::from(args.settings.upgrade.clone())), ); - // Use raw sources if requirements files are provided as input. - let raw_sources = if args.requirements.is_empty() { - args.raw_sources - } else { - if args.raw_sources { - warn_user!("`--raw-sources` is a no-op for `requirements.txt` files, which are always treated as raw sources"); - } - true - }; - let requirements = args .packages .into_iter() @@ -1141,7 +1131,7 @@ async fn run_project( requirements, args.editable, args.dependency_type, - raw_sources, + args.raw_sources, args.rev, args.tag, args.branch, diff --git a/crates/uv/tests/edit.rs b/crates/uv/tests/edit.rs index df34abc3c60e..ad6296097a54 100644 --- a/crates/uv/tests/edit.rs +++ b/crates/uv/tests/edit.rs @@ -168,14 +168,19 @@ fn add_git() -> Result<()> { + sniffio==1.3.1 "###); - // Adding with an ambiguous Git reference will fail. + // Adding with an ambiguous Git reference should treat it as a revision. uv_snapshot!(context.filters(), context.add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0.0.1"]).arg("--preview"), @r###" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- - error: Cannot resolve Git reference `0.0.1` for requirement `uv-public-pypackage`. Specify the reference with one of `--tag`, `--branch`, or `--rev`, or use the `--raw-sources` flag. + Resolved 5 packages in [TIME] + Prepared 2 packages in [TIME] + Uninstalled 1 package in [TIME] + Installed 2 packages in [TIME] + ~ project==0.1.0 (from file://[TEMP_DIR]/) + + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979) "###); uv_snapshot!(context.filters(), context.add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage"]).arg("--tag=0.0.1").arg("--preview"), @r###" @@ -185,11 +190,10 @@ fn add_git() -> Result<()> { ----- stderr ----- Resolved 5 packages in [TIME] - Prepared 2 packages in [TIME] + Prepared 1 package in [TIME] Uninstalled 1 package in [TIME] - Installed 2 packages in [TIME] + Installed 1 package in [TIME] ~ project==0.1.0 (from file://[TEMP_DIR]/) - + uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979) "###); let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; @@ -3339,7 +3343,8 @@ fn add_requirements_file() -> Result<()> { "#})?; let requirements_txt = context.temp_dir.child("requirements.txt"); - requirements_txt.write_str("Flask==2.3.2\ngit+https://github.com/agronholm/anyio.git@4.4.0")?; + requirements_txt + .write_str("Flask==2.3.2\nanyio @ git+https://github.com/agronholm/anyio.git@4.4.0")?; uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("requirements.txt"), @r###" success: true @@ -3377,24 +3382,15 @@ fn add_requirements_file() -> Result<()> { requires-python = ">=3.12" dependencies = [ "flask==2.3.2", - "anyio @ git+https://github.com/agronholm/anyio.git@4.4.0", + "anyio", ] + + [tool.uv.sources] + anyio = { git = "https://github.com/agronholm/anyio.git", rev = "4.4.0" } "### ); }); - // Using `--raw-sources` with `-r` should warn. - uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("requirements.txt").arg("--raw-sources"), @r###" - success: true - exit_code: 0 - ----- stdout ----- - - ----- stderr ----- - warning: `--raw-sources` is a no-op for `requirements.txt` files, which are always treated as raw sources - Resolved [N] packages in [TIME] - Audited [N] packages in [TIME] - "###); - // Passing a `setup.py` should fail. uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("setup.py"), @r###" success: false @@ -3775,20 +3771,6 @@ fn add_git_to_script() -> Result<()> { pprint([(k, v["title"]) for k, v in data.items()][:10]) "#})?; - // Adding with an ambiguous Git reference will fail. - uv_snapshot!(context.filters(), context - .add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0.0.1"]) - .arg("--preview") - .arg("--script") - .arg("script.py"), @r###" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - error: Cannot resolve Git reference `0.0.1` for requirement `uv-public-pypackage`. Specify the reference with one of `--tag`, `--branch`, or `--rev`, or use the `--raw-sources` flag. - "###); - uv_snapshot!(context.filters(), context .add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage"]) .arg("--tag=0.0.1") diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 9724a9c6c077..39620426d061 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -702,9 +702,7 @@ uv add [OPTIONS] >
--reinstall-package reinstall-package

Reinstall a specific package, regardless of whether it’s already installed. Implies --refresh-package

-
--requirements, -r requirements

Add all packages listed in the given requirements.txt files.

- -

Implies --raw-sources.

+
--requirements, -r requirements

Add all packages listed in the given requirements.txt files

--resolution resolution

The strategy to use when selecting between the different compatible versions for a given package requirement.