Avoid treating uv add -r as --raw-sources (#6287)

## Summary

I suspect this was added because there's no way for users to pass (e.g.)
`--tag`, so the references are ambiguous. I think it's better to write
them as `rev` than to fail, though. It's just less efficient when we
fetch.

Closes https://github.com/astral-sh/uv/issues/6276.

Closes https://github.com/astral-sh/uv/issues/6275.
This commit is contained in:
Charlie Marsh 2024-08-21 12:28:02 -04:00 committed by GitHub
parent d8095b1fb8
commit 70dba6f954
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 49 additions and 80 deletions

View file

@ -2382,8 +2382,6 @@ pub struct AddArgs {
pub packages: Vec<String>, pub packages: Vec<String>,
/// Add all packages listed in the given `requirements.txt` files. /// Add all packages listed in the given `requirements.txt` files.
///
/// Implies `--raw-sources`.
#[arg(long, short, group = "sources", value_parser = parse_file_path)] #[arg(long, short, group = "sources", value_parser = parse_file_path)]
pub requirements: Vec<PathBuf>, pub requirements: Vec<PathBuf>,

View file

@ -351,31 +351,32 @@ impl Source {
subdirectory, subdirectory,
.. ..
} => { } => {
// We can only resolve a full commit hash from a pep508 URL, everything else is ambiguous. if rev.is_none() && tag.is_none() && branch.is_none() {
let rev = match reference { let rev = match reference {
GitReference::FullCommit(ref mut rev) => Some(mem::take(rev)), GitReference::FullCommit(ref mut rev) => Some(mem::take(rev)),
_ => None, GitReference::Branch(ref mut rev) => Some(mem::take(rev)),
} GitReference::Tag(ref mut rev) => Some(mem::take(rev)),
// Give precedence to an explicit argument. GitReference::ShortCommit(ref mut rev) => Some(mem::take(rev)),
.or(rev); GitReference::BranchOrTag(ref mut rev) => Some(mem::take(rev)),
GitReference::BranchOrTagOrCommit(ref mut rev) => Some(mem::take(rev)),
// Error if the user tried to specify a reference but didn't disambiguate. GitReference::NamedRef(ref mut rev) => Some(mem::take(rev)),
if reference != GitReference::DefaultBranch GitReference::DefaultBranch => None,
&& rev.is_none() };
&& tag.is_none() Source::Git {
&& branch.is_none() rev,
{ tag,
return Err(SourceError::UnresolvedReference( branch,
reference.as_str().unwrap().to_owned(), git: repository,
)); subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()),
} }
} else {
Source::Git { Source::Git {
rev, rev,
tag, tag,
branch, branch,
git: repository, git: repository,
subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()), subdirectory: subdirectory.map(|path| path.to_string_lossy().into_owned()),
}
} }
} }
}; };

View file

@ -624,7 +624,7 @@ fn resolve_requirement(
let source = match result { let source = match result {
Ok(source) => source, Ok(source) => source,
Err(SourceError::UnresolvedReference(rev)) => { 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.", "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 name = requirement.name
) )

View file

@ -1113,16 +1113,6 @@ async fn run_project(
.combine(Refresh::from(args.settings.upgrade.clone())), .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 let requirements = args
.packages .packages
.into_iter() .into_iter()
@ -1141,7 +1131,7 @@ async fn run_project(
requirements, requirements,
args.editable, args.editable,
args.dependency_type, args.dependency_type,
raw_sources, args.raw_sources,
args.rev, args.rev,
args.tag, args.tag,
args.branch, args.branch,

View file

@ -168,17 +168,8 @@ fn add_git() -> Result<()> {
+ sniffio==1.3.1 + 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###" 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
----- 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").arg("--preview"), @r###"
success: true success: true
exit_code: 0 exit_code: 0
----- stdout ----- ----- stdout -----
@ -192,6 +183,19 @@ fn add_git() -> Result<()> {
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979) + 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###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 5 packages in [TIME]
Prepared 1 package in [TIME]
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
~ project==0.1.0 (from file://[TEMP_DIR]/)
"###);
let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?; let pyproject_toml = fs_err::read_to_string(context.temp_dir.join("pyproject.toml"))?;
insta::with_settings!({ insta::with_settings!({
@ -3342,7 +3346,8 @@ fn add_requirements_file() -> Result<()> {
"#})?; "#})?;
let requirements_txt = context.temp_dir.child("requirements.txt"); 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###" uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("requirements.txt"), @r###"
success: true success: true
@ -3380,24 +3385,15 @@ fn add_requirements_file() -> Result<()> {
requires-python = ">=3.12" requires-python = ">=3.12"
dependencies = [ dependencies = [
"flask==2.3.2", "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. // Passing a `setup.py` should fail.
uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("setup.py"), @r###" uv_snapshot!(context.filters(), context.add(&[]).arg("-r").arg("setup.py"), @r###"
success: false success: false
@ -3778,20 +3774,6 @@ fn add_git_to_script() -> Result<()> {
pprint([(k, v["title"]) for k, v in data.items()][:10]) 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 uv_snapshot!(context.filters(), context
.add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage"]) .add(&["uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage"])
.arg("--tag=0.0.1") .arg("--tag=0.0.1")

View file

@ -702,9 +702,7 @@ uv add [OPTIONS] <PACKAGES|--requirements <REQUIREMENTS>>
</dd><dt><code>--reinstall-package</code> <i>reinstall-package</i></dt><dd><p>Reinstall a specific package, regardless of whether it&#8217;s already installed. Implies <code>--refresh-package</code></p> </dd><dt><code>--reinstall-package</code> <i>reinstall-package</i></dt><dd><p>Reinstall a specific package, regardless of whether it&#8217;s already installed. Implies <code>--refresh-package</code></p>
</dd><dt><code>--requirements</code>, <code>-r</code> <i>requirements</i></dt><dd><p>Add all packages listed in the given <code>requirements.txt</code> files.</p> </dd><dt><code>--requirements</code>, <code>-r</code> <i>requirements</i></dt><dd><p>Add all packages listed in the given <code>requirements.txt</code> files</p>
<p>Implies <code>--raw-sources</code>.</p>
</dd><dt><code>--resolution</code> <i>resolution</i></dt><dd><p>The strategy to use when selecting between the different compatible versions for a given package requirement.</p> </dd><dt><code>--resolution</code> <i>resolution</i></dt><dd><p>The strategy to use when selecting between the different compatible versions for a given package requirement.</p>