From 41c1fc0c4dd268fcd5caf5551b2e7be334865716 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 29 Jul 2024 04:49:38 -0400 Subject: [PATCH] Generate hashes for `--find-links` entries (#5544) ## Summary Closes https://github.com/astral-sh/uv/issues/3874. --- .../src/distribution_database.rs | 18 +- crates/uv-resolver/src/resolution/graph.rs | 151 +++--- crates/uv/tests/common/mod.rs | 4 +- crates/uv/tests/pip_compile.rs | 451 ++++++++++-------- 4 files changed, 339 insertions(+), 285 deletions(-) diff --git a/crates/uv-distribution/src/distribution_database.rs b/crates/uv-distribution/src/distribution_database.rs index 47f67773d..d479f7071 100644 --- a/crates/uv-distribution/src/distribution_database.rs +++ b/crates/uv-distribution/src/distribution_database.rs @@ -428,14 +428,16 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> { // For hash _validation_, callers are expected to enforce the policy when retrieving the // wheel. // TODO(charlie): Request the hashes via a separate method, to reduce the coupling in this API. - if hashes.is_generate() && matches!(dist, BuiltDist::DirectUrl(_) | BuiltDist::Path(_)) { - let wheel = self.get_wheel(dist, hashes).await?; - let metadata = wheel.metadata()?; - let hashes = wheel.hashes; - return Ok(ArchiveMetadata { - metadata: Metadata::from_metadata23(metadata), - hashes, - }); + if hashes.is_generate() { + if dist.file().map_or(true, |file| file.hashes.is_empty()) { + let wheel = self.get_wheel(dist, hashes).await?; + let metadata = wheel.metadata()?; + let hashes = wheel.hashes; + return Ok(ArchiveMetadata { + metadata: Metadata::from_metadata23(metadata), + hashes, + }); + } } let result = self diff --git a/crates/uv-resolver/src/resolution/graph.rs b/crates/uv-resolver/src/resolution/graph.rs index a2d93e3bc..3b5f8eee2 100644 --- a/crates/uv-resolver/src/resolution/graph.rs +++ b/crates/uv-resolver/src/resolution/graph.rs @@ -1,16 +1,17 @@ -use distribution_types::{ - Dist, DistributionMetadata, Name, ResolutionDiagnostic, ResolvedDist, VersionId, - VersionOrUrlRef, -}; use indexmap::IndexSet; -use pep440_rs::{Version, VersionSpecifier}; -use pep508_rs::{MarkerEnvironment, MarkerTree}; use petgraph::{ graph::{Graph, NodeIndex}, Directed, }; -use pypi_types::{HashDigest, ParsedUrlError, Requirement, VerbatimParsedUrl, Yanked}; use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; + +use distribution_types::{ + Dist, DistributionMetadata, Name, ResolutionDiagnostic, ResolvedDist, VersionId, + VersionOrUrlRef, +}; +use pep440_rs::{Version, VersionSpecifier}; +use pep508_rs::{MarkerEnvironment, MarkerTree}; +use pypi_types::{HashDigest, ParsedUrlError, Requirement, VerbatimParsedUrl, Yanked}; use uv_configuration::{Constraints, Overrides}; use uv_distribution::Metadata; use uv_git::GitResolver; @@ -18,7 +19,6 @@ use uv_normalize::{ExtraName, GroupName, PackageName}; use crate::pins::FilePins; use crate::preferences::Preferences; -use crate::pubgrub::PubGrubDistribution; use crate::python_requirement::PythonTarget; use crate::redirect::url_to_precise; use crate::resolution::AnnotatedDist; @@ -274,44 +274,19 @@ impl ResolutionGraph { // Create the distribution. let dist = Dist::from_url(name.clone(), url_to_precise(url.clone(), git))?; - // Extract the hashes, preserving those that were already present in the - // lockfile if necessary. - let hashes = if let Some(digests) = preferences - .match_hashes(name, version) - .filter(|digests| !digests.is_empty()) - { - digests.to_vec() - } else if let Some(metadata_response) = index.distributions().get(&dist.version_id()) { - if let MetadataResponse::Found(ref archive) = *metadata_response { - let mut digests = archive.hashes.clone(); - digests.sort_unstable(); - digests - } else { - vec![] - } - } else { - vec![] - }; + let version_id = VersionId::from_url(&url.verbatim); + + // Extract the hashes. + let hashes = Self::get_hashes(&version_id, name, version, preferences, index); // Extract the metadata. let metadata = { - let dist = PubGrubDistribution::from_url(name, url); - - let response = index - .distributions() - .get(&dist.version_id()) - .unwrap_or_else(|| { - panic!( - "Every package should have metadata: {:?}", - dist.version_id() - ) - }); + let response = index.distributions().get(&version_id).unwrap_or_else(|| { + panic!("Every package should have metadata: {version_id:?}") + }); let MetadataResponse::Found(archive) = &*response else { - panic!( - "Every package should have metadata: {:?}", - dist.version_id() - ) + panic!("Every package should have metadata: {version_id:?}") }; archive.metadata.clone() @@ -324,6 +299,8 @@ impl ResolutionGraph { .expect("Every package should be pinned") .clone(); + let version_id = dist.version_id(); + // Track yanks for any registry distributions. match dist.yanked() { None | Some(Yanked::Bool(false)) => {} @@ -341,49 +318,17 @@ impl ResolutionGraph { } } - // Extract the hashes, preserving those that were already present in the - // lockfile if necessary. - let hashes = if let Some(digests) = preferences - .match_hashes(name, version) - .filter(|digests| !digests.is_empty()) - { - digests.to_vec() - } else if let Some(versions_response) = index.packages().get(name) { - if let VersionsResponse::Found(ref version_maps) = *versions_response { - version_maps - .iter() - .find_map(|version_map| version_map.hashes(version)) - .map(|mut digests| { - digests.sort_unstable(); - digests - }) - .unwrap_or_default() - } else { - vec![] - } - } else { - vec![] - }; + // Extract the hashes. + let hashes = Self::get_hashes(&version_id, name, version, preferences, index); // Extract the metadata. let metadata = { - let dist = PubGrubDistribution::from_registry(name, version); - - let response = index - .distributions() - .get(&dist.version_id()) - .unwrap_or_else(|| { - panic!( - "Every package should have metadata: {:?}", - dist.version_id() - ) - }); + let response = index.distributions().get(&version_id).unwrap_or_else(|| { + panic!("Every package should have metadata: {version_id:?}") + }); let MetadataResponse::Found(archive) = &*response else { - panic!( - "Every package should have metadata: {:?}", - dist.version_id() - ) + panic!("Every package should have metadata: {version_id:?}") }; archive.metadata.clone() @@ -393,6 +338,54 @@ impl ResolutionGraph { }) } + /// Identify the hashes for the [`VersionId`], preserving any hashes that were provided by the + /// lockfile. + fn get_hashes( + version_id: &VersionId, + name: &PackageName, + version: &Version, + preferences: &Preferences, + index: &InMemoryIndex, + ) -> Vec { + // 1. Look for hashes from the lockfile. + if let Some(digests) = preferences.match_hashes(name, version) { + if !digests.is_empty() { + return digests.to_vec(); + } + } + + // 2. Look for hashes from the registry, which are served at the package level. + if let Some(versions_response) = index.packages().get(name) { + if let VersionsResponse::Found(ref version_maps) = *versions_response { + if let Some(digests) = version_maps + .iter() + .find_map(|version_map| version_map.hashes(version)) + .map(|mut digests| { + digests.sort_unstable(); + digests + }) + { + if !digests.is_empty() { + return digests; + } + } + } + } + + // 3. Look for hashes for the distribution (i.e., the specific wheel or source distribution). + if let Some(metadata_response) = index.distributions().get(version_id) { + if let MetadataResponse::Found(ref archive) = *metadata_response { + let mut digests = archive.hashes.clone(); + digests.sort_unstable(); + if !digests.is_empty() { + return digests; + } + } + } + + vec![] + } + /// Returns an iterator over the distinct packages in the graph. fn dists(&self) -> impl Iterator { self.petgraph diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index 7d9b30d19..6c72cfb77 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -879,9 +879,9 @@ pub fn run_and_format>( if let Some(windows_filters) = windows_filters { // The optional leading +/- is for install logs, the optional next line is for lockfiles let windows_only_deps = [ - ("( [+-] )?colorama==\\d+(\\.[\\d+])+\n( # via .*\n)?"), + ("( [+-] )?colorama==\\d+(\\.[\\d+])+( \\\\\n --hash=.*)?\n( # via .*\n)?"), ("( [+-] )?colorama==\\d+(\\.[\\d+])+(\\s+# via .*)?\n"), - ("( [+-] )?tzdata==\\d+(\\.[\\d+])+\n( # via .*\n)?"), + ("( [+-] )?tzdata==\\d+(\\.[\\d+])+( \\\\\n --hash=.*)?\n( # via .*\n)?"), ("( [+-] )?tzdata==\\d+(\\.[\\d+])+(\\s+# via .*)?\n"), ]; let mut removed_packages = 0; diff --git a/crates/uv/tests/pip_compile.rs b/crates/uv/tests/pip_compile.rs index ffbeb0839..ba901d067 100644 --- a/crates/uv/tests/pip_compile.rs +++ b/crates/uv/tests/pip_compile.rs @@ -106,7 +106,7 @@ fn missing_requirements_in() { let context = TestContext::new("3.12"); let requirements_in = context.temp_dir.child("requirements.in"); - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -163,7 +163,7 @@ dependencies = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: true exit_code: 0 @@ -204,7 +204,7 @@ dependencies = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: true exit_code: 0 @@ -244,7 +244,7 @@ dependencies = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--annotation-style=line") .arg("pyproject.toml"), @r###" success: true @@ -274,7 +274,7 @@ fn compile_constraints_txt() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("idna<3.4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -311,7 +311,7 @@ fn compile_constraints_inline() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("idna<3.4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -341,7 +341,7 @@ fn compile_constraints_markers() -> Result<()> { constraints_txt.write_str("sniffio==1.2.0;python_version<='3.7'")?; constraints_txt.write_str("sniffio==1.3.0;python_version>'3.7'")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -380,7 +380,7 @@ fn compile_constraint_extra() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("flask[dotenv]<24.3.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -435,7 +435,7 @@ optional-dependencies.foo = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("foo"), @r###" @@ -478,7 +478,7 @@ optional-dependencies."FrIeNdLy-._.-bArD" = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("FRiENDlY-...-_-BARd"), @r###" @@ -521,7 +521,7 @@ optional-dependencies.foo = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("bar"), @r###" @@ -563,7 +563,7 @@ build-backend = "poetry.core.masonry.api" "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("test"), @r###" @@ -624,7 +624,7 @@ build-backend = "poetry.core.masonry.api" "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: true exit_code: 0 @@ -679,7 +679,7 @@ build-backend = "poetry.core.masonry.api" "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: false exit_code: 2 @@ -738,7 +738,7 @@ setup( "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("dev"), @r###" @@ -796,7 +796,7 @@ setup( "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("setup.cfg") .arg("--extra") .arg("dev"), @r###" @@ -844,7 +844,7 @@ setup( "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("setup.py") .arg("--extra") .arg("dev"), @r###" @@ -926,7 +926,7 @@ optional-dependencies.foo = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("foo") @@ -953,7 +953,7 @@ fn compile_requirements_file_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio==3.7.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--all-extras"), @r###" @@ -987,7 +987,7 @@ optional-dependencies.foo = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("invalid name!"), @r###" @@ -1012,7 +1012,7 @@ fn compile_python_312() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--python-version") .arg("3.12"), @r###" @@ -1049,7 +1049,7 @@ fn compile_python_312_annotation_line() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--annotation-style=line") .arg("requirements.in") .arg("--python-version") @@ -1081,7 +1081,7 @@ fn compile_python_312_no_deps() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-deps") .arg("--python-version") @@ -1146,7 +1146,7 @@ fn compile_sdist_resolution_lowest() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio @ https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--resolution=lowest-direct") .arg("--python-version") @@ -1178,7 +1178,7 @@ fn compile_python_invalid_version() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--python-version") .arg("3.7.x"), @r###" @@ -1203,7 +1203,7 @@ fn compile_python_dev_version() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--python-version") .arg("3.7-dev"), @r###" @@ -1232,7 +1232,7 @@ fn omit_non_matching_annotation() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("idna <3.7; python_version < '3.7'")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("-c") .arg("constraints.txt"), @r###" @@ -1265,7 +1265,7 @@ fn compile_numpy_py38() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("numpy")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-build"), @r###" success: true @@ -1291,7 +1291,7 @@ fn compile_wheel_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1332,7 +1332,7 @@ fn compile_sdist_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1407,7 +1407,7 @@ fn compile_git_branch_https_dependency() -> Result<()> { "uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@test-branch", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1435,7 +1435,7 @@ fn compile_git_tag_https_dependency() -> Result<()> { "uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@test-tag", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1465,7 +1465,7 @@ fn compile_git_date_tag_https_dependency() -> Result<()> { "uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@20240402", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1493,7 +1493,7 @@ fn compile_git_long_commit_https_dependency() -> Result<()> { "uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0dacfd662c64cb4ceb16e6cf65a157a8b715b979", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1521,7 +1521,7 @@ fn compile_git_short_commit_https_dependency() -> Result<()> { "uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0dacfd6", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1548,7 +1548,7 @@ fn compile_git_refs_https_dependency() -> Result<()> { requirements_in .write_str("uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@refs/pull/4/head")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1574,7 +1574,7 @@ fn compile_git_subdirectory_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("example-pkg-a @ git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_a")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1601,7 +1601,7 @@ fn compile_git_concurrent_access() -> Result<()> { requirements_in .write_str("example-pkg-a @ git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_a\nexample-pkg-b @ git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_b")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1630,7 +1630,7 @@ fn compile_git_unnamed_concurrent_access() -> Result<()> { requirements_in .write_str("git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_a\ngit+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_b")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1659,7 +1659,7 @@ fn compile_git_mismatched_name() -> Result<()> { requirements_in .write_str("flask @ git+https://github.com/pallets/flask.git@2.0.0\ndask @ git+https://github.com/pallets/flask.git@3.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -1683,7 +1683,7 @@ fn compile_git_subdirectory_static_metadata() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("uv-public-pypackage @ git+https://github.com/astral-test/uv-workspace-pypackage#subdirectory=uv-public-pypackage")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1709,7 +1709,7 @@ fn mixed_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask==3.0.0\nwerkzeug @ https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1751,7 +1751,7 @@ fn conflicting_direct_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("werkzeug==3.0.0\nwerkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 1 @@ -1774,7 +1774,7 @@ fn compatible_direct_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("werkzeug==2.0.0\nwerkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1799,7 +1799,7 @@ fn conflicting_repeated_url_dependency_version_mismatch() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("werkzeug @ https://files.pythonhosted.org/packages/bd/24/11c3ea5a7e866bf2d97f0501d0b4b1c9bbeade102bb4b588f0d2919a5212/Werkzeug-2.0.1-py3-none-any.whl\nwerkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -1826,7 +1826,7 @@ fn conflicting_repeated_url_dependency_markers() -> Result<()> { werkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl ; python_version < '3.10' "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1854,7 +1854,7 @@ fn conflicting_repeated_url_dependency_version_match() -> Result<()> { requirements_in.write_str("werkzeug @ git+https://github.com/pallets/werkzeug.git@2.0.0\nwerkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -1877,7 +1877,7 @@ fn conflicting_transitive_url_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask==3.0.0\nwerkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 1 @@ -1903,7 +1903,7 @@ fn compatible_repeated_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@0.0.2 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1932,7 +1932,7 @@ fn conflicting_repeated_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@0.0.1 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -1960,7 +1960,7 @@ fn compatible_narrowed_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -1990,7 +1990,7 @@ fn compatible_broader_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@0.0.2 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2020,7 +2020,7 @@ fn compatible_repeated_narrowed_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@0.0.2 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2053,7 +2053,7 @@ fn incompatible_narrowed_url_dependency() -> Result<()> { uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage@test-branch "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -2078,7 +2078,7 @@ fn allowed_transitive_git_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("hatchling_editable @ https://github.com/astral-sh/uv/files/14762645/hatchling_editable.zip")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2111,7 +2111,7 @@ fn allowed_transitive_url_dependency() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("iniconfig @ git+https://github.com/pytest-dev/iniconfig@9cae43103df70bac6fde7b9f35ad11a9f1be0cb4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -2149,7 +2149,7 @@ fn allowed_transitive_canonical_url_dependency() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("iniconfig @ git+https://github.com/pytest-dev/iniconfig.git@9cae43103df70bac6fde7b9f35ad11a9f1be0cb4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -2184,7 +2184,7 @@ fn allowed_transitive_url_path_dependency() -> Result<()> { requirements_in.write_str("hatchling_editable @ ${HATCH_PATH}")?; let hatchling_path = current_dir()?.join("../../scripts/packages/hatchling_editable"); - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .env("HATCH_PATH", hatchling_path.as_os_str()), @r###" success: true @@ -2220,7 +2220,7 @@ fn requirement_constraint_override_url() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("anyio==3.7.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt") @@ -2252,7 +2252,7 @@ fn requirement_override_prerelease() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("flask<2.0.1,!=2.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -2306,7 +2306,7 @@ optional-dependencies.bar = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--all-extras"), @r###" success: true @@ -2362,7 +2362,7 @@ optional-dependencies.bar = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--annotation-style=line") .arg("pyproject.toml") .arg("--all-extras"), @r###" @@ -2408,7 +2408,7 @@ optional-dependencies.bar = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--all-extras") .arg("--extra") @@ -2446,7 +2446,7 @@ dependencies = ["anyio==3.7.0", "anyio==4.0.0"] "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: false exit_code: 1 @@ -2478,7 +2478,7 @@ dependencies = ["anyio==300.1.4"] "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: false exit_code: 1 @@ -2612,7 +2612,7 @@ fn compile_wheel_path_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ file:flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2645,7 +2645,7 @@ fn compile_wheel_path_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ file://flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2678,7 +2678,7 @@ fn compile_wheel_path_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ ./flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2894,7 +2894,7 @@ fn compile_yanked_version_direct() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("attrs==21.1.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -2920,7 +2920,7 @@ fn compile_yanked_version_indirect() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("attrs>20.3.0,<21.2.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 1 @@ -2951,7 +2951,7 @@ fn override_dependency() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("werkzeug==2.3.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -3007,7 +3007,7 @@ fn override_dependency_from_pyproject() -> Result<()> { "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .current_dir(&context.temp_dir) , @r###" @@ -3063,7 +3063,7 @@ fn constraint_dependency_from_pyproject() -> Result<()> { "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml"), @r###" success: true exit_code: 0 @@ -3113,7 +3113,7 @@ fn override_dependency_from_specific_uv_toml() -> Result<()> { "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--config-file") .arg("../uv/uv.toml") @@ -3164,7 +3164,7 @@ fn override_multi_dependency() -> Result<()> { "tomli>=1.1.0; python_version >= '3.11'\ntomli<1.0.0; python_version < '3.11'", )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -3209,7 +3209,7 @@ fn dont_add_override_for_non_activated_extra() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("pysocks==1.7.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -3249,7 +3249,7 @@ fn override_dependency_from_workspace_invalid_syntax() -> Result<()> { "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .current_dir(&context.temp_dir) , @r###" @@ -3285,7 +3285,7 @@ fn override_dependency_url() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("werkzeug @ https://files.pythonhosted.org/packages/cc/94/5f7079a0e00bd6863ef8f1da638721e9da21e5bacee597595b318f71d62e/Werkzeug-1.0.1-py2.py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -3330,7 +3330,7 @@ fn override_dependency_unnamed_url() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("https://files.pythonhosted.org/packages/cc/94/5f7079a0e00bd6863ef8f1da638721e9da21e5bacee597595b318f71d62e/Werkzeug-1.0.1-py2.py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--override") .arg("overrides.txt"), @r###" @@ -3371,7 +3371,7 @@ fn missing_registry_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black[tensorboard]==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -3407,7 +3407,7 @@ fn missing_url_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask[tensorboard] @ https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -3448,7 +3448,7 @@ fn preserve_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ https://files.PYTHONHOSTED.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -3494,7 +3494,7 @@ fn preserve_project_root() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ file://${PROJECT_ROOT}/flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -3534,7 +3534,7 @@ fn respect_http_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ ${URL}")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .env("URL", "https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl"), @r###" success: true @@ -3575,7 +3575,7 @@ fn respect_unnamed_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("${URL}")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .env("URL", "https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl"), @r###" success: true @@ -3617,7 +3617,7 @@ fn error_missing_unnamed_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("${URL}")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -3647,7 +3647,7 @@ fn respect_file_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask @ ${FILE_PATH}")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .env("FILE_PATH", context.temp_dir.join("flask-3.0.0-py3-none-any.whl")), @r###" success: true @@ -3951,7 +3951,7 @@ fn cache_errors_are_non_fatal() -> Result<()> { ]; let check = || { - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pip") .arg("compile") .arg(requirements_in.path()) @@ -4014,7 +4014,7 @@ fn compile_html() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("jinja2<=3.1.2")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .env_remove("UV_EXCLUDE_NEWER") .arg("requirements.in") .arg("--index-url") @@ -4044,7 +4044,7 @@ fn trailing_slash() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("jinja2")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--index-url") .arg("https://test.pypi.org/simple"), @r###" @@ -4063,7 +4063,7 @@ fn trailing_slash() -> Result<()> { "### ); - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--index-url") .arg("https://test.pypi.org/simple/"), @r###" @@ -4092,7 +4092,7 @@ fn compile_legacy_sdist_pep_517() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flake8 @ https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -4123,7 +4123,7 @@ fn compile_legacy_sdist_setuptools() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flake8 @ https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--legacy-setup-py"), @r###" success: true @@ -4155,7 +4155,7 @@ fn generate_hashes_registry() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio==4.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--generate-hashes"), @r###" success: true @@ -4191,7 +4191,7 @@ fn generate_hashes_source_distribution_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio @ https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--generate-hashes"), @r###" success: true @@ -4226,7 +4226,7 @@ fn generate_hashes_built_distribution_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio @ https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--generate-hashes"), @r###" success: true @@ -4261,7 +4261,7 @@ fn generate_hashes_git() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio @ git+https://github.com/agronholm/anyio@4.3.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--generate-hashes"), @r###" success: true @@ -4295,7 +4295,7 @@ fn generate_hashes_unnamed_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--generate-hashes"), @r###" success: true @@ -4409,6 +4409,65 @@ fn generate_hashes_editable() -> Result<()> { Ok(()) } +/// Include hashes from a `--find-links` index in the generated output. +#[test] +fn generate_hashes_find_links_directory() -> Result<()> { + let context = TestContext::new("3.12"); + let requirements_in = context.temp_dir.child("requirements.in"); + requirements_in.write_str("tqdm")?; + + uv_snapshot!(context.filters(), context.pip_compile() + .arg("requirements.in") + .arg("--generate-hashes") + .arg("--find-links") + .arg(context.workspace_root.join("scripts").join("links")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + # This file was autogenerated by uv via the following command: + # uv pip compile --cache-dir [CACHE_DIR] requirements.in --generate-hashes + tqdm==1000.0.0 \ + --hash=sha256:a34996d4bd5abb2336e14ff0a2d22b92cfd0f0ed344e6883041ce01953276a13 + # via -r requirements.in + + ----- stderr ----- + Resolved 1 package in [TIME] + "### + ); + + Ok(()) +} + +/// Include hashes from a `--find-links` index in the generated output. +#[test] +fn generate_hashes_find_links_url() -> Result<()> { + let context = TestContext::new("3.12"); + let requirements_in = context.temp_dir.child("requirements.in"); + requirements_in.write_str("tqdm")?; + + uv_snapshot!(context.filters(), context.pip_compile() + .arg("requirements.in") + .arg("--generate-hashes") + .arg("--no-index") + .arg("--find-links") + .arg("https://download.pytorch.org/whl/torch_stable.html"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + # This file was autogenerated by uv via the following command: + # uv pip compile --cache-dir [CACHE_DIR] requirements.in --generate-hashes --no-index + tqdm==4.64.1 \ + --hash=sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1 + # via -r requirements.in + + ----- stderr ----- + Resolved 1 package in [TIME] + "### + ); + + Ok(()) +} + /// Compile using `--find-links` with a local directory. #[test] fn find_links_directory() -> Result<()> { @@ -4452,7 +4511,7 @@ fn find_links_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("tqdm")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .arg("--find-links") @@ -4480,7 +4539,7 @@ fn find_links_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("tqdm\n--find-links ${URL}")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .env("URL", "https://download.pytorch.org/whl/torch_stable.html"), @r###" @@ -4508,7 +4567,7 @@ fn find_links_requirements_txt() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-f https://download.pytorch.org/whl/torch_stable.html\ntqdm")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .arg("--emit-find-links"), @r###" @@ -4542,7 +4601,7 @@ fn avoid_irrelevant_extras() -> Result<()> { extras[dev] "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--find-links") .arg(context.workspace_root.join("scripts").join("links")), @r###" @@ -4595,7 +4654,7 @@ coverage = ["example[test]", "extras>=0.0.1,<=0.0.2"] let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-e .[test,coverage]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--find-links") .arg(context.workspace_root.join("scripts").join("links")), @r###" @@ -4671,7 +4730,7 @@ fn upgrade_none() -> Result<()> { # via black "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt"), @r###" @@ -4726,7 +4785,7 @@ fn upgrade_all() -> Result<()> { # via black "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -4782,7 +4841,7 @@ fn upgrade_package() -> Result<()> { # via black "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -4828,7 +4887,7 @@ fn upgrade_constraint() -> Result<()> { iniconfig==1.0.0 "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -4847,7 +4906,7 @@ fn upgrade_constraint() -> Result<()> { "### ); - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -4947,7 +5006,7 @@ fn unnamed_requirement_with_package_name() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -4986,7 +5045,7 @@ fn no_annotate() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-annotate"), @r###" success: true @@ -5016,7 +5075,7 @@ fn no_header() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-header"), @r###" success: true @@ -5050,7 +5109,7 @@ fn custom_compile_command() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--custom-compile-command") .arg("./custom-uv-compile.sh"), @r###" @@ -5078,7 +5137,7 @@ fn custom_compile_command() -> Result<()> { ); // with env var - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .env("UV_CUSTOM_COMPILE_COMMAND", "./custom-uv-compile.sh"), @r###" success: true @@ -5114,7 +5173,7 @@ fn allow_unsafe() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("werkzeug==3.0.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--allow-unsafe"), @r###" success: true @@ -5143,7 +5202,7 @@ fn resolver_legacy() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("werkzeug==3.0.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--resolver=legacy"), @r###" success: false @@ -5166,7 +5225,7 @@ fn emit_index_urls() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-url") .arg("--index-url") @@ -5209,7 +5268,7 @@ fn emit_find_links() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-find-links") .arg("--find-links") @@ -5250,7 +5309,7 @@ fn emit_find_links_relative() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-f ./\niniconfig")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-find-links"), @r###" success: true @@ -5278,7 +5337,7 @@ fn emit_build_options() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("black==23.10.1")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-build-options") .arg("--only-binary") @@ -5321,7 +5380,7 @@ fn no_index_requirements_txt() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--no-index\ntqdm")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 1 @@ -5347,7 +5406,7 @@ fn index_url_requirements_txt() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--index-url https://google.com\ntqdm")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--index-url") .arg("https://pypi.org/simple"), @r###" @@ -5377,7 +5436,7 @@ fn conflicting_index_urls_requirements_txt() -> Result<()> { let constraints_in = context.temp_dir.child("constraints.in"); constraints_in.write_str("--index-url https://wikipedia.org\nflask")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.in"), @r###" @@ -5403,7 +5462,7 @@ fn matching_index_urls_requirements_txt() -> Result<()> { let constraints_in = context.temp_dir.child("constraints.in"); constraints_in.write_str("--index-url https://pypi.org/simple")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.in"), @r###" @@ -5429,7 +5488,7 @@ fn offline_registry() -> Result<()> { requirements_in.write_str("black==23.10.1")?; // Resolve with `--offline` with an empty cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--offline"), @r###" success: false @@ -5445,7 +5504,7 @@ fn offline_registry() -> Result<()> { ); // Populate the cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -5471,7 +5530,7 @@ fn offline_registry() -> Result<()> { ); // Resolve with `--offline` with a populated cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--offline"), @r###" success: true @@ -5509,7 +5568,7 @@ fn offline_registry_backtrack() -> Result<()> { requirements_in.write_str("iniconfig==1.1.1")?; // Populate the cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -5528,7 +5587,7 @@ fn offline_registry_backtrack() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("iniconfig")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--offline"), @r###" success: true @@ -5558,7 +5617,7 @@ fn offline_find_links() -> Result<()> { // Resolve with `--offline` and `--find-links`. We indicate that the network was disabled, // since both the `--find-links` and the registry lookups fail (but, importantly, we don't error // when failing to fetch the `--find-links` URL). - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--find-links") .arg("https://download.pytorch.org/whl/torch_stable.html") @@ -5576,7 +5635,7 @@ fn offline_find_links() -> Result<()> { ); // Resolve with `--offline`, `--find-links`, and `--no-index`. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--find-links") .arg("https://download.pytorch.org/whl/torch_stable.html") @@ -5605,7 +5664,7 @@ fn offline_direct_url() -> Result<()> { requirements_in.write_str("iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl")?; // Resolve with `--offline` with an empty cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--offline"), @r###" success: false @@ -5619,7 +5678,7 @@ fn offline_direct_url() -> Result<()> { ); // Populate the cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -5635,7 +5694,7 @@ fn offline_direct_url() -> Result<()> { ); // Resolve with `--offline` with a populated cache. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--offline"), @r###" success: true @@ -5663,7 +5722,7 @@ fn invalid_metadata_requires_python() -> Result<()> { requirements_in.write_str("validation==2.0.0")?; // `2.0.0` has invalid metadata. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .arg("--find-links") @@ -5695,7 +5754,7 @@ fn invalid_metadata_multiple_dist_info() -> Result<()> { requirements_in.write_str("validation==3.0.0")?; // `3.0.0` has an invalid structure (multiple `.dist-info` directories). - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .arg("--find-links") @@ -5725,7 +5784,7 @@ fn invalid_metadata_backtrack() -> Result<()> { // `2.0.0` and `3.0.0` have invalid metadata. We should backtrack to `1.0.0` (the preceding // version, which has valid metadata). - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-index") .arg("--find-links") @@ -5891,7 +5950,7 @@ fn compile_constraints_compatible_url() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("anyio @ https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -5928,7 +5987,7 @@ fn compile_constraints_compatible_url_version() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("anyio>4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -5965,7 +6024,7 @@ fn compile_constraints_incompatible_url() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("anyio @ https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -5990,7 +6049,7 @@ fn index_url_in_requirements() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--index-url https://download.pytorch.org/whl\nanyio<4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 1 @@ -6013,7 +6072,7 @@ fn index_url_from_command_line() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--index-url https://download.pytorch.org/whl\nanyio<4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--index-url") .arg("https://pypi.org/simple"), @r###" @@ -6045,7 +6104,7 @@ fn unsupported_scheme() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio @ bzr+https://example.com/anyio")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -6069,7 +6128,7 @@ fn no_deps_valid_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask[dotenv]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-deps"), @r###" success: true @@ -6095,7 +6154,7 @@ fn no_deps_invalid_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask[empty]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-deps"), @r###" success: true @@ -6218,7 +6277,7 @@ fn no_strip_extra() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask[dotenv]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-strip-extras"), @r###" success: true @@ -6261,7 +6320,7 @@ fn no_strip_extras() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio[trio]\nanyio[doc]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-strip-extras"), @r###" success: true @@ -6360,7 +6419,7 @@ fn no_strip_markers() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio ; python_version > '3.11'")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-strip-markers") .arg("--python-platform") @@ -6396,7 +6455,7 @@ fn no_strip_markers_multiple_markers() -> Result<()> { trio ; sys_platform == 'win32' "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-strip-markers") .arg("--python-platform") @@ -6441,7 +6500,7 @@ fn no_strip_markers_transitive_marker() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("trio ; python_version > '3.11'")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--no-strip-markers") .arg("--python-platform") @@ -6911,7 +6970,7 @@ fn universal_local_path_requirement() -> Result<()> { . "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -6982,7 +7041,7 @@ fn universal_overlapping_local_requirement() -> Result<()> { . "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7056,7 +7115,7 @@ fn universal_disjoint_local_requirement() -> Result<()> { // Some marker expressions on the output here are missing due to https://github.com/astral-sh/uv/issues/5086, // but the local versions are still respected correctly. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7135,7 +7194,7 @@ fn universal_disjoint_base_or_local_requirement() -> Result<()> { // Some marker expressions on the output here are missing due to https://github.com/astral-sh/uv/issues/5086, // but the local versions are still respected correctly. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7212,7 +7271,7 @@ fn universal_nested_overlapping_local_requirement() -> Result<()> { . "})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7286,7 +7345,7 @@ fn universal_nested_overlapping_local_requirement() -> Result<()> { requires-python = ">=3.11" "#})?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7371,7 +7430,7 @@ fn universal_nested_disjoint_local_requirement() -> Result<()> { // Some marker expressions on the output here are missing due to https://github.com/astral-sh/uv/issues/5086, // but the local versions are still respected correctly. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--universal") .arg("--find-links") @@ -7973,7 +8032,7 @@ fn compile_constraints_compatible_version() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("filelock==3.8.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -8012,7 +8071,7 @@ fn compile_constraints_incompatible_version() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("filelock==3.8.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -8040,7 +8099,7 @@ fn conflicting_url_markers() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("filelock==3.8.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -8149,7 +8208,7 @@ fn override_with_compatible_constraint() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("anyio>=3.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt") @@ -8192,7 +8251,7 @@ fn override_with_incompatible_constraint() -> Result<()> { let overrides_txt = context.temp_dir.child("overrides.txt"); overrides_txt.write_str("anyio>=3.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt") @@ -8218,7 +8277,7 @@ fn unsafe_package() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--unsafe-package") .arg("jinja2") @@ -8263,7 +8322,7 @@ fn pre_release_upper_bound_exclude() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask<2.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--prerelease=allow"), @r###" success: true @@ -8300,7 +8359,7 @@ fn pre_release_upper_bound_include() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask<2.0.0rc4")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--prerelease=allow"), @r###" success: true @@ -8338,7 +8397,7 @@ fn pre_alias() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("flask<2.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--pre"), @r###" success: true @@ -8377,7 +8436,7 @@ fn pre_release_constraint() -> Result<()> { let constraints_txt = context.temp_dir.child("constraints.txt"); constraints_txt.write_str("flask<=2.0.0rc2")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--constraint") .arg("constraints.txt"), @r###" @@ -8436,7 +8495,7 @@ dev = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("dev"), @r###" @@ -8486,7 +8545,7 @@ dev = [ "#, )?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("pyproject.toml") .arg("--extra") .arg("dev"), @r###" @@ -8548,7 +8607,7 @@ fn empty_index_url_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-url") .env("UV_INDEX_URL", ""), @r###" @@ -8581,7 +8640,7 @@ fn empty_extra_index_url_env_var() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-url") .env("EXTRA_UV_INDEX_URL", ""), @r###" @@ -8615,7 +8674,7 @@ fn empty_index_url_env_var_override() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--index-url https://test.pypi.org/simple\nidna")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-url") .env("UV_INDEX_URL", ""), @r###" @@ -8644,7 +8703,7 @@ fn index_url_env_var_override() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("--index-url https://pypi.org/simple\nidna")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-url") .env("UV_INDEX_URL", "https://test.pypi.org/simple"), @r###" @@ -8815,7 +8874,7 @@ dev = [ let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-e .[dev]")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -8864,7 +8923,7 @@ dev = ["setuptools"] let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("-e .")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--resolution=lowest-direct"), @r###" success: true @@ -8896,7 +8955,7 @@ fn metadata_2_2() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("pyo3-mixed @ https://files.pythonhosted.org/packages/2b/b8/e04b783d3569d5b61b1dcdfda683ac2e3617340539aecd0f099fbade0b4a/pyo3_mixed-2.1.5.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -8964,7 +9023,7 @@ fn not_found_direct_url() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("iniconfig @ https://files.pythonhosted.org/packages/ef/a6/fake/iniconfig-2.0.0-py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -9091,7 +9150,7 @@ fn requirement_wheel_name_mismatch() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: false exit_code: 2 @@ -9125,7 +9184,7 @@ fn preserve_hashes_no_upgrade() -> Result<()> { "})?; // Avoid adding any additional hashes to the "lockfile". - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -9169,7 +9228,7 @@ fn preserve_hashes_upgrade() -> Result<()> { "})?; // Requesting an upgrade should update the hashes, even if the version didn't change. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -9258,7 +9317,7 @@ fn preserve_hashes_no_existing_hashes() -> Result<()> { "})?; // Add additional hashes to the "lockfile". - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -9349,7 +9408,7 @@ fn preserve_hashes_newer_version() -> Result<()> { "})?; // Requesting a more specific version should update the hashes. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--output-file") .arg("requirements.txt") @@ -9504,7 +9563,7 @@ fn unnamed_git_requirement() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("git+https://github.com/pallets/flask.git@3.0.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -9543,7 +9602,7 @@ fn unnamed_https_requirement() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("https://github.com/pallets/flask/archive/refs/tags/3.0.2.tar.gz")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in"), @r###" success: true exit_code: 0 @@ -10306,7 +10365,7 @@ fn compile_index_url_first_match() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("jinja2==3.1.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--index-url") .arg("https://pypi.org/simple") .arg("--extra-index-url") @@ -10338,7 +10397,7 @@ fn compile_index_url_fallback() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("jinja2==3.1.0")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--index-strategy") .arg("unsafe-any-match") .arg("--index-url") @@ -10378,7 +10437,7 @@ fn compile_index_url_fallback_prefer_primary() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--index-strategy") .arg("unsafe-any-match") .arg("--index-url") @@ -10418,7 +10477,7 @@ fn compile_index_url_unsafe_highest() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--index-strategy") .arg("unsafe-best-match") .arg("--index-url") @@ -10461,7 +10520,7 @@ fn compile_index_url_unsafe_lowest() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("anyio<100")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--resolution") .arg("lowest") .arg("--index-strategy") @@ -10498,7 +10557,7 @@ fn emit_index_annotation_hide_password() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("requests")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-annotation") .env("UV_INDEX_URL", "https://test-user:test-password@pypi.org/simple"), @r###" @@ -10539,7 +10598,7 @@ fn emit_index_annotation_pypi_org_simple() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("requests")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-annotation"), @r###" success: true @@ -10582,7 +10641,7 @@ fn emit_index_annotation_no_annotate() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("requests")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-annotation") .arg("--no-annotate"), @r###" @@ -10618,7 +10677,7 @@ fn emit_index_annotation_line() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("requests")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--emit-index-annotation") .arg("--annotation-style") @@ -10655,7 +10714,7 @@ fn emit_index_annotation_multiple_indexes() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("uv\nrequests")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") .arg("--extra-index-url") .arg("https://test.pypi.org/simple") @@ -10688,7 +10747,7 @@ fn no_version_for_direct_dependency() -> Result<()> { let requirements_in = context.temp_dir.child("requirements.in"); requirements_in.write_str("pypyp==1,>=1.2")?; - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("requirements.in") // Must error before we make any network requests .arg("--offline"), @r###" @@ -11173,7 +11232,7 @@ fn tool_uv_sources() -> Result<()> { )?; // Install the editable packages. - uv_snapshot!(context.pip_compile() + uv_snapshot!(context.filters(), context.pip_compile() .arg("--preview") .arg(require_path) .arg("--extra") @@ -11226,7 +11285,7 @@ fn dynamic_pyproject_toml() -> Result<()> { let bird_feeder = context.temp_dir.child("bird_feeder/__init__.py"); bird_feeder.write_str("__all__= []")?; - uv_snapshot!(context.pip_compile().arg("pyproject.toml"), @r###" + uv_snapshot!(context.filters(), context.pip_compile().arg("pyproject.toml"), @r###" success: true exit_code: 0 ----- stdout -----