Bring harmony to the test snapshot filtering situation (#2678)

The snapshot filtering situation has gotten way out of hand, with each
test hand-rolling it's own filters on top of copied cruft from previous
tests.

I've attempted to address this holistically:

- `TestContext.filters()` has everything you should need 
- This was introduced a while ago, but needed a few more filters for it
to be generalized everywhere
- Using `INSTA_FILTERS` is **not recommended** unless you do not want
the context filters
    - It is okay to extend these filters for things unrelated to paths
- If you have to write a custom path filter, please highlight it in
review so we can address it in the common module
- `TestContext.site_packages()` gives cross-platform access to the
site-packages directory
    - Do not manually construct the path to site-packages from the venv
- Do not turn off tests on Windows because you manually constructed a
Unix path to site-packages
- `TestContext.workspace_root` gives access to uv's repository directory
    - Use this for installing from `scripts/packages/`
- If you need coverage for relative paths, copy the test package into
the `temp_dir` don't change the working directory of the test fixture

There is additional work that can be done here, such as:

- Auditing and removing additional uses of `INSTA_FILTERS`
- Updating manual construction of `Command` instances to use a utility
- The `venv` tests are particularly frightening in their lack of a test
context and could use some love
- Improving the developer experience i.e. apply context filters to
snapshots by default
This commit is contained in:
Zanie Blue 2024-03-27 09:10:12 -05:00 committed by GitHub
parent ffd78d0821
commit 248d6f89ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 696 additions and 1393 deletions

View File

@ -3,7 +3,12 @@ use std::path::{Component, Path, PathBuf};
use once_cell::sync::Lazy;
pub static CWD: Lazy<PathBuf> = Lazy::new(|| std::env::current_dir().unwrap());
pub static CWD: Lazy<PathBuf> = Lazy::new(|| {
std::env::current_dir()
.unwrap()
.canonicalize()
.expect("The current directory must exist")
});
pub trait Simplified {
/// Simplify a [`Path`].
@ -34,7 +39,9 @@ impl<T: AsRef<Path>> Simplified for T {
fn user_display(&self) -> std::path::Display {
let path = dunce::simplified(self.as_ref());
path.strip_prefix(&*CWD).unwrap_or(path).display()
path.strip_prefix(CWD.simplified())
.unwrap_or(path)
.display()
}
}

View File

@ -5,8 +5,11 @@ fn main() {
// The workspace root directory is not available without walking up the tree
// https://github.com/rust-lang/cargo/issues/3946
let workspace_root = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap())
.join("..")
.join("..");
.parent()
.expect("CARGO_MANIFEST_DIR should be nested in workspace")
.parent()
.expect("CARGO_MANIFEST_DIR should be doubly nested in workspace")
.to_path_buf();
commit_info(&workspace_root);

View File

@ -8,7 +8,7 @@ use assert_fs::prelude::*;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, INSTA_FILTERS};
use crate::common::{get_bin, TestContext};
mod common;
@ -66,18 +66,13 @@ fn prune_no_op() -> Result<()> {
.assert()
.success();
let filters = [(r"Pruning cache at: .*", "Pruning cache at: [CACHE_DIR]")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, prune_command(&context).arg("--verbose"), @r###"
uv_snapshot!(context.filters(), prune_command(&context).arg("--verbose"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Pruning cache at: [CACHE_DIR]
Pruning cache at: [CACHE_DIR]/
No unused entries found
"###);
@ -102,25 +97,14 @@ fn prune_stale_directory() -> Result<()> {
let simple = context.cache_dir.child("simple-v4");
simple.create_dir_all()?;
let filters = [
(r"Pruning cache at: .*", "Pruning cache at: [CACHE_DIR]"),
(
r"Removing dangling cache entry: .*[\\|/]simple-v4",
"Pruning cache at: [CACHE_DIR]/simple-v4",
),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, prune_command(&context).arg("--verbose"), @r###"
uv_snapshot!(context.filters(), prune_command(&context).arg("--verbose"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Pruning cache at: [CACHE_DIR]
DEBUG Pruning cache at: [CACHE_DIR]/simple-v4
Pruning cache at: [CACHE_DIR]/
DEBUG Removing dangling cache entry: [CACHE_DIR]/simple-v4
Removed 1 directory
"###);
@ -145,16 +129,17 @@ fn prune_stale_symlink() -> Result<()> {
let wheels = context.cache_dir.child("wheels-v0");
fs_err::remove_dir_all(wheels)?;
let filters = [
(r"Pruning cache at: .*", "Pruning cache at: [CACHE_DIR]"),
(
r"Removing dangling cache entry: .*[\\|/]archive-v0[\\|/].*",
"Pruning cache at: [CACHE_DIR]/archive-v0/anyio",
),
]
let filters: Vec<_> = context
.filters()
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
.chain([
// The cache entry does not have a stable key, so we filter it out
(
r"\[CACHE_DIR\](\\|\/)(.+)(\\|\/).*",
"[CACHE_DIR]/$2/[ENTRY]",
),
])
.collect();
uv_snapshot!(filters, prune_command(&context).arg("--verbose"), @r###"
success: true
@ -162,8 +147,8 @@ fn prune_stale_symlink() -> Result<()> {
----- stdout -----
----- stderr -----
Pruning cache at: [CACHE_DIR]
DEBUG Pruning cache at: [CACHE_DIR]/archive-v0/anyio
Pruning cache at: [CACHE_DIR]/
DEBUG Removing dangling cache entry: [CACHE_DIR]/archive-v0/[ENTRY]
Removed 44 files ([SIZE])
"###);

View File

@ -45,6 +45,7 @@ pub struct TestContext {
pub cache_dir: assert_fs::TempDir,
pub venv: PathBuf,
pub python_version: String,
pub workspace_root: PathBuf,
// Standard filters for this test context
filters: Vec<(String, String)>,
@ -56,6 +57,17 @@ impl TestContext {
let cache_dir = assert_fs::TempDir::new().expect("Failed to create cache dir");
let venv = create_venv(&temp_dir, &cache_dir, python_version);
// The workspace root directory is not available without walking up the tree
// https://github.com/rust-lang/cargo/issues/3946
let workspace_root = Path::new(&std::env::var("CARGO_MANIFEST_DIR").unwrap())
.parent()
.expect("CARGO_MANIFEST_DIR should be nested in workspace")
.parent()
.expect("CARGO_MANIFEST_DIR should be doubly nested in workspace")
.to_path_buf();
let site_packages = site_packages_path(&venv, format!("python{python_version}"));
let mut filters = Vec::new();
filters.extend(
Self::path_patterns(&cache_dir)
@ -63,15 +75,52 @@ impl TestContext {
.map(|pattern| (pattern, "[CACHE_DIR]/".to_string())),
);
filters.extend(
Self::path_patterns(&temp_dir)
Self::path_patterns(&site_packages)
.into_iter()
.map(|pattern| (pattern, "[TEMP_DIR]/".to_string())),
.map(|pattern| (pattern, "[SITE_PACKAGES]/".to_string())),
);
filters.extend(
Self::path_patterns(&venv)
.into_iter()
.map(|pattern| (pattern, "[VENV]/".to_string())),
);
filters.extend(
Self::path_patterns(&temp_dir)
.into_iter()
.map(|pattern| (pattern, "[TEMP_DIR]/".to_string())),
);
filters.extend(
Self::path_patterns(&workspace_root)
.into_iter()
.map(|pattern| (pattern, "[WORKSPACE]/".to_string())),
);
// Account for [`Simplified::user_display`] which is relative to the command working directory
filters.push((
Self::path_pattern(
site_packages
.strip_prefix(&temp_dir)
.expect("The test site-packages directory is always in the tempdir"),
),
"[SITE_PACKAGES]/".to_string(),
));
filters.push((
Self::path_pattern(
venv.strip_prefix(&temp_dir)
.expect("The test virtual environment directory is always in the tempdir"),
),
"[VENV]/".to_string(),
));
// Filter non-deterministic temporary directory names
// Note we apply this _after_ all the full paths to avoid breaking their matching
filters.push((r"(\\|\/)\.tmp.*(\\|\/)".to_string(), "/[TMP]/".to_string()));
// Account for platform prefix differences `file://` (Unix) vs `file:///` (Windows)
filters.push((r"file:///".to_string(), "file://".to_string()));
// Destroy any remaining UNC prefixes (Windows only)
filters.push((r"\\\\\?\\".to_string(), String::new()));
Self {
temp_dir,
@ -79,6 +128,7 @@ impl TestContext {
venv,
python_version: python_version.to_string(),
filters,
workspace_root,
}
}
@ -128,33 +178,35 @@ impl TestContext {
.stdout(version);
}
/// Generate an escaped regex pattern for the given path.
/// Generate various escaped regex patterns for the given path.
fn path_patterns(path: impl AsRef<Path>) -> Vec<String> {
vec![
let mut patterns = Vec::new();
// We can only canonicalize paths that exist already
if path.as_ref().exists() {
patterns.push(Self::path_pattern(
path.as_ref()
.canonicalize()
.expect("Failed to create canonical path"),
));
}
// Include a non-canonicalized version
patterns.push(Self::path_pattern(path));
patterns
}
/// Generate an escaped regex pattern for the given path.
fn path_pattern(path: impl AsRef<Path>) -> String {
format!(
// Trim the trailing separator for cross-platform directories filters
r"{}\\?/?",
regex::escape(
&path
.as_ref()
.canonicalize()
.expect("Failed to create canonical path")
// Normalize the path to match display and remove UNC prefixes on Windows
.simplified()
.display()
.to_string(),
)
// Make seprators platform agnostic because on Windows we will display
regex::escape(&path.as_ref().simplified_display().to_string())
// Make separators platform agnostic because on Windows we will display
// paths with Unix-style separators sometimes
.replace(r"\\", r"(\\|\/)")
),
// Include a non-canonicalized version
format!(
r"{}\\?/?",
regex::escape(&path.as_ref().simplified().display().to_string())
.replace(r"\\", r"(\\|\/)")
),
]
)
}
/// Standard snapshot filters _plus_ those for this test context.
@ -176,17 +228,21 @@ impl TestContext {
/// Returns the site-packages folder inside the venv.
pub fn site_packages(&self) -> PathBuf {
site_packages_path(
&self.venv,
format!("{}{}", self.python_kind(), self.python_version),
)
}
}
fn site_packages_path(venv: &Path, python: String) -> PathBuf {
if cfg!(unix) {
self.venv
.join("lib")
.join(format!("{}{}", self.python_kind(), self.python_version))
.join("site-packages")
venv.join("lib").join(python).join("site-packages")
} else if cfg!(windows) {
self.venv.join("Lib").join("site-packages")
venv.join("Lib").join("site-packages")
} else {
unimplemented!("Only Windows and Unix are supported")
}
}
}
pub fn venv_to_interpreter(venv: &Path) -> PathBuf {
@ -253,8 +309,8 @@ pub fn bootstrapped_pythons() -> Option<Vec<PathBuf>> {
/// Create a virtual environment named `.venv` in a temporary directory with the given
/// Python version. Expected format for `python` is "python<version>".
pub fn create_venv(
temp_dir: &assert_fs::TempDir,
pub fn create_venv<Parent: assert_fs::prelude::PathChild + AsRef<std::path::Path>>(
temp_dir: &Parent,
cache_dir: &assert_fs::TempDir,
python: &str,
) -> PathBuf {

View File

@ -12,7 +12,7 @@ use assert_fs::TempDir;
use indoc::indoc;
use url::Url;
use common::{uv_snapshot, TestContext, INSTA_FILTERS};
use common::{uv_snapshot, TestContext};
use uv_fs::Simplified;
use crate::common::{get_bin, EXCLUDE_NEWER};
@ -629,13 +629,7 @@ dependencies = [
"#,
)?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("pyproject.toml"), @r###"
success: false
exit_code: 2
@ -862,7 +856,7 @@ fn compile_python_37() -> Result<()> {
),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect();
uv_snapshot!(filters, context.compile()
@ -1083,7 +1077,7 @@ fn compile_git_https_dependency() -> Result<()> {
// In addition to the standard filters, remove the `main` commit, which will change frequently.
let filters: Vec<_> = [(r"@(\d|\w){40}", "@[COMMIT]")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect();
uv_snapshot!(filters, context.compile()
@ -2096,13 +2090,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
Url::from_file_path(flask_wheel.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2229,14 +2217,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str(&format!("flask @ {}", flask_wheel.path().display()))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filter_path = regex::escape(&flask_wheel.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "/[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2247,7 +2228,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
# via flask
click==8.1.7
# via flask
flask @ /[TEMP_DIR]/
flask @ [TEMP_DIR]/flask-3.0.0-py3-none-any.whl
itsdangerous==2.1.2
# via flask
jinja2==3.1.3
@ -2269,14 +2250,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str(&format!("flask @ file://{}", flask_wheel.path().display()))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filter_path = regex::escape(&flask_wheel.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "/[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2287,7 +2261,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
# via flask
click==8.1.7
# via flask
flask @ file:///[TEMP_DIR]/
flask @ file://[TEMP_DIR]/flask-3.0.0-py3-none-any.whl
itsdangerous==2.1.2
# via flask
jinja2==3.1.3
@ -2312,14 +2286,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
flask_wheel.path().display()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filter_path = regex::escape(&flask_wheel.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "/[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2330,7 +2297,7 @@ fn compile_wheel_path_dependency() -> Result<()> {
# via flask
click==8.1.7
# via flask
flask @ file://localhost//[TEMP_DIR]/
flask @ file://localhost/[TEMP_DIR]/flask-3.0.0-py3-none-any.whl
itsdangerous==2.1.2
# via flask
jinja2==3.1.3
@ -2366,13 +2333,7 @@ fn compile_source_distribution_path_dependency() -> Result<()> {
Url::from_file_path(flask_wheel.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2407,15 +2368,15 @@ fn compile_source_distribution_path_dependency() -> Result<()> {
fn compile_wheel_path_dependency_missing() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flask @ file:///path/to/flask-3.0.0-py3-none-any.whl")?;
requirements_in.write_str(&format!(
"flask @ {}",
context
.temp_dir
.join("flask-3.0.0-py3-none-any.whl")
.simplified_display()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: false
exit_code: 2
@ -2892,20 +2853,14 @@ fn compile_editable() -> Result<()> {
"
})?;
let filter_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.current_dir(current_dir()?), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in
-e ${PROJECT_ROOT}/../../scripts/packages/maturin_editable
-e ../../scripts/packages/poetry_editable
-e file://../../scripts/packages/black_editable
@ -2951,12 +2906,6 @@ fn recursive_extras_direct_url() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("black[dev] @ ../../scripts/packages/black_editable")?;
let filter_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let mut command = Command::new(get_bin());
if cfg!(all(windows, debug_assertions)) {
// TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
@ -2964,7 +2913,7 @@ fn recursive_extras_direct_url() -> Result<()> {
command.env("UV_STACK_SIZE", (2 * 1024 * 1024).to_string());
}
uv_snapshot!(filters, command
uv_snapshot!(context.filters(), command
.arg("pip")
.arg("compile")
.arg(requirements_in.path())
@ -2977,7 +2926,7 @@ fn recursive_extras_direct_url() -> Result<()> {
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z
# uv pip compile [TEMP_DIR]/requirements.in --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z
aiohttp==3.9.3
# via black
aiosignal==1.3.1
@ -3014,20 +2963,14 @@ fn compile_editable_url_requirement() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("-e ../../scripts/packages/hatchling_editable")?;
let filter_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.current_dir(current_dir()?), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in
-e ../../scripts/packages/hatchling_editable
iniconfig @ git+https://github.com/pytest-dev/iniconfig@9cae43103df70bac6fde7b9f35ad11a9f1be0cb4
# via hatchling-editable
@ -3296,7 +3239,7 @@ fn generate_hashes() -> Result<()> {
vec![]
}
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect();
uv_snapshot!(filters, context.compile()
@ -3414,24 +3357,10 @@ fn find_links_directory() -> Result<()> {
werkzeug @ https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl
"})?;
let project_root = fs_err::canonicalize(std::env::current_dir()?.join("..").join(".."))?;
let project_root_string = regex::escape(&project_root.user_display().to_string());
let filters: Vec<_> = [
(project_root_string.as_str(), "[PROJECT_ROOT]"),
// Unify trailing (back)slash between Windows and Unix.
(
"[PROJECT_ROOT]/scripts/wheels/",
"[PROJECT_ROOT]/scripts/wheels",
),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in")
.arg("--find-links")
.arg(project_root.join("scripts").join("wheels")), @r###"
.arg(context.workspace_root.join("scripts").join("wheels")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -3708,7 +3637,7 @@ fn missing_path_requirement() -> Result<()> {
let filters: Vec<_> = [(r"/C:/", "/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect();
uv_snapshot!(filters, context.compile()
@ -3718,7 +3647,7 @@ fn missing_path_requirement() -> Result<()> {
----- stdout -----
----- stderr -----
error: Distribution not found at: file:///tmp/anyio-3.7.0.tar.gz
error: Distribution not found at: file://tmp/anyio-3.7.0.tar.gz
"###);
Ok(())
@ -3729,19 +3658,9 @@ fn missing_path_requirement() -> Result<()> {
fn missing_editable_requirement() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("-e ../tmp/anyio-3.7.0.tar.gz")?;
requirements_in.write_str("-e foo/anyio-3.7.0.tar.gz")?;
// File url, absolute Unix path or absolute Windows path
let filters: Vec<_> = [
(r" file://.*/", " file://[TEMP_DIR]/"),
(r" /.*/", " /[TEMP_DIR]/"),
(r" [A-Z]:\\.*\\", " /[TEMP_DIR]/"),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in"), @r###"
success: false
exit_code: 2
@ -3749,7 +3668,7 @@ fn missing_editable_requirement() -> Result<()> {
----- stderr -----
error: Failed to build editables
Caused by: Source distribution not found at: /[TEMP_DIR]/anyio-3.7.0.tar.gz
Caused by: Source distribution not found at: [TEMP_DIR]/foo/anyio-3.7.0.tar.gz
"###);
Ok(())
@ -4612,29 +4531,20 @@ fn editable_invalid_extra() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("-e ../../scripts/packages/black_editable[empty]")?;
let requirements_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [
(r" file://.*/", " file://[TEMP_DIR]/"),
(requirements_path.as_str(), "requirements.in"),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.current_dir(current_dir()?), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in
-e ../../scripts/packages/black_editable
----- stderr -----
Built 1 editable in [TIME]
Resolved 1 package in [TIME]
warning: The package `black @ file://[TEMP_DIR]/black_editable` does not have an extra named `empty`.
warning: The package `black @ file://[WORKSPACE]/scripts/packages/black_editable` does not have an extra named `empty`.
"###);
Ok(())
@ -4930,17 +4840,7 @@ fn override_editable() -> Result<()> {
let overrides_txt = context.temp_dir.child("overrides.txt");
overrides_txt.write_str("black==23.10.1")?;
let requirements_path = regex::escape(&requirements_in.user_display().to_string());
let overrides_path = regex::escape(&overrides_txt.user_display().to_string());
let filters: Vec<_> = [
(requirements_path.as_str(), "requirements.in"),
(overrides_path.as_str(), "overrides.txt"),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.arg("--override")
.arg(overrides_txt.path())
@ -4949,7 +4849,7 @@ fn override_editable() -> Result<()> {
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in --override overrides.txt
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in --override [TEMP_DIR]/overrides.txt
-e ../../scripts/packages/black_editable
----- stderr -----
@ -5278,16 +5178,7 @@ fn editable_direct_dependency() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("-e ../../scripts/packages/setuptools_editable")?;
let requirements_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [
(r" file://.*/", " file://[TEMP_DIR]/"),
(requirements_path.as_str(), "requirements.in"),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.arg("--resolution")
.arg("lowest-direct")
@ -5296,7 +5187,7 @@ fn editable_direct_dependency() -> Result<()> {
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in --resolution lowest-direct
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in --resolution lowest-direct
-e ../../scripts/packages/setuptools_editable
iniconfig==0.1
# via setuptools-editable
@ -5468,7 +5359,8 @@ fn requires_python_editable() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -5505,7 +5397,8 @@ fn requires_python_editable_target_version() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -5530,7 +5423,7 @@ requires-python = "<=3.8"
),
]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect();
uv_snapshot!(filters, context.compile()
@ -5720,7 +5613,8 @@ fn requires_python_direct_url() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -5764,14 +5658,8 @@ fn compile_root_uri_editable() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("-e ${ROOT_PATH}")?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let root_path = current_dir()?.join("../../scripts/packages/root_editable");
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in")
.env("ROOT_PATH", root_path.as_os_str()), @r###"
success: true
@ -5780,7 +5668,7 @@ fn compile_root_uri_editable() -> Result<()> {
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
-e ${ROOT_PATH}
black @ file://[TEMP_DIR]/black_editable
black @ file://[WORKSPACE]/scripts/packages/root_editable/../black_editable
# via root-editable
----- stderr -----
@ -5800,15 +5688,9 @@ fn compile_root_uri_non_editable() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("${ROOT_PATH}\n${BLACK_PATH}")?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let root_path = current_dir()?.join("../../scripts/packages/root_editable");
let black_path = current_dir()?.join("../../scripts/packages/black_editable");
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg("requirements.in")
.env("ROOT_PATH", root_path.as_os_str())
.env("BLACK_PATH", black_path.as_os_str()), @r###"
@ -6098,20 +5980,14 @@ fn unnamed_path_requirement() -> Result<()> {
"
})?;
let filter_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.current_dir(current_dir()?), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in
anyio==4.3.0
# via
# httpx
@ -6236,20 +6112,14 @@ fn dynamic_dependencies() -> Result<()> {
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("hatchling-dynamic @ ../../scripts/packages/hatchling_dynamic")?;
let filter_path = regex::escape(&requirements_in.user_display().to_string());
let filters: Vec<_> = [(filter_path.as_str(), "requirements.in")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, context.compile()
uv_snapshot!(context.filters(), context.compile()
.arg(requirements_in.path())
.current_dir(current_dir()?), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z requirements.in
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2024-03-25T00:00:00Z [TEMP_DIR]/requirements.in
anyio==4.3.0
# via hatchling-dynamic
hatchling-dynamic @ ../../scripts/packages/hatchling_dynamic

View File

@ -13,7 +13,7 @@ use assert_cmd::assert::OutputAssertExt;
use assert_fs::fixture::{FileWriteStr, PathChild};
use predicates::prelude::predicate;
use common::{create_bin_with_executables, get_bin, uv_snapshot, TestContext, INSTA_FILTERS};
use common::{create_bin_with_executables, get_bin, uv_snapshot, TestContext};
mod common;
@ -67,7 +67,7 @@ fn incompatible_python_compatible_override() -> Result<()> {
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"incompatible-python-compatible-override-", "package-"));
let requirements_in = context.temp_dir.child("requirements.in");
@ -116,7 +116,7 @@ fn compatible_python_incompatible_override() -> Result<()> {
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"compatible-python-incompatible-override-", "package-"));
let requirements_in = context.temp_dir.child("requirements.in");
@ -163,7 +163,7 @@ fn incompatible_python_compatible_override_unavailable_no_wheels() -> Result<()>
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"incompatible-python-compatible-override-unavailable-no-wheels-",
"package-",
@ -219,7 +219,7 @@ fn incompatible_python_compatible_override_available_no_wheels() -> Result<()> {
let python_versions = &["3.11"];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"incompatible-python-compatible-override-available-no-wheels-",
"package-",
@ -274,7 +274,7 @@ fn incompatible_python_compatible_override_no_compatible_wheels() -> Result<()>
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"incompatible-python-compatible-override-no-compatible-wheels-",
"package-",
@ -332,7 +332,7 @@ fn incompatible_python_compatible_override_other_wheel() -> Result<()> {
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"incompatible-python-compatible-override-other-wheel-",
"package-",
@ -392,7 +392,7 @@ fn python_patch_override_no_patch() -> Result<()> {
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-patch-override-no-patch-", "package-"));
let requirements_in = context.temp_dir.child("requirements.in");
@ -439,7 +439,7 @@ fn python_patch_override_patch_compatible() -> Result<()> {
let python_versions = &[];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-patch-override-patch-compatible-", "package-"));
let requirements_in = context.temp_dir.child("requirements.in");

View File

@ -77,7 +77,7 @@ fn freeze_many() -> Result<()> {
#[test]
#[cfg(unix)]
fn freeze_duplicate() -> Result<()> {
use crate::common::{copy_dir_all, INSTA_FILTERS};
use crate::common::copy_dir_all;
// Sync a version of `pip` into a virtual environment.
let context1 = TestContext::new("3.12");
@ -103,31 +103,12 @@ fn freeze_duplicate() -> Result<()> {
// Copy the virtual environment to a new location.
copy_dir_all(
context2
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context1
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context2.site_packages().join("pip-22.1.1.dist-info"),
context1.site_packages().join("pip-22.1.1.dist-info"),
)?;
// Run `pip freeze`.
let filters = INSTA_FILTERS
.iter()
.chain(&[
(
".*/lib/python3.12/site-packages/pip-22.1.1.dist-info",
"/pip-22.1.1.dist-info",
),
(
".*/lib/python3.12/site-packages/pip-21.3.1.dist-info",
"/pip-21.3.1.dist-info",
),
])
.copied()
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context1).arg("--strict"), @r###"
uv_snapshot!(context1.filters(), command(&context1).arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -136,8 +117,8 @@ fn freeze_duplicate() -> Result<()> {
----- stderr -----
warning: The package `pip` has multiple installed distributions:
/pip-21.3.1.dist-info
/pip-22.1.1.dist-info
- [SITE_PACKAGES]/pip-21.3.1.dist-info
- [SITE_PACKAGES]/pip-22.1.1.dist-info
"###
);

View File

@ -6,11 +6,10 @@ use assert_fs::prelude::*;
use base64::{prelude::BASE64_STANDARD as base64, Engine};
use indoc::indoc;
use itertools::Itertools;
use std::env::current_dir;
use std::process::Command;
use url::Url;
use common::{uv_snapshot, TestContext, EXCLUDE_NEWER, INSTA_FILTERS};
use std::process::Command;
use common::{uv_snapshot, TestContext, EXCLUDE_NEWER};
use uv_fs::Simplified;
use crate::common::get_bin;
@ -215,13 +214,9 @@ dependencies = ["flask==1.0.x"]
"#,
)?;
let filters = [
(r"file://.*", "[SOURCE_DIR]"),
(r#"File ".*[/\\]site-packages"#, "File \"[SOURCE_DIR]"),
("exit status", "exit code"),
]
let filters = [("exit status", "exit code")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
@ -232,7 +227,7 @@ dependencies = ["flask==1.0.x"]
----- stdout -----
----- stderr -----
error: Failed to build: [SOURCE_DIR]
error: Failed to build: file://[TEMP_DIR]/
Caused by: Build backend failed to determine extra requires with `build_wheel()` with exit code: 1
--- stdout:
configuration error: `project.dependencies[0]` must be pep508
@ -254,32 +249,32 @@ dependencies = ["flask==1.0.x"]
--- stderr:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "[SOURCE_DIR]/setuptools/build_meta.py", line 325, in get_requires_for_build_wheel
File "[CACHE_DIR]/[TMP]/build_meta.py", line 325, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[SOURCE_DIR]/setuptools/build_meta.py", line 295, in _get_build_requires
File "[CACHE_DIR]/[TMP]/build_meta.py", line 295, in _get_build_requires
self.run_setup()
File "[SOURCE_DIR]/setuptools/build_meta.py", line 487, in run_setup
File "[CACHE_DIR]/[TMP]/build_meta.py", line 487, in run_setup
super().run_setup(setup_script=setup_script)
File "[SOURCE_DIR]/setuptools/build_meta.py", line 311, in run_setup
File "[CACHE_DIR]/[TMP]/build_meta.py", line 311, in run_setup
exec(code, locals())
File "<string>", line 1, in <module>
File "[SOURCE_DIR]/setuptools/__init__.py", line 104, in setup
File "[CACHE_DIR]/[TMP]/__init__.py", line 104, in setup
return distutils.core.setup(**attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[SOURCE_DIR]/setuptools/_distutils/core.py", line 159, in setup
File "[CACHE_DIR]/[TMP]/core.py", line 159, in setup
dist.parse_config_files()
File "[SOURCE_DIR]/_virtualenv.py", line 22, in parse_config_files
File "[CACHE_DIR]/[TMP]/_virtualenv.py", line 22, in parse_config_files
result = old_parse_config_files(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[SOURCE_DIR]/setuptools/dist.py", line 631, in parse_config_files
File "[CACHE_DIR]/[TMP]/dist.py", line 631, in parse_config_files
pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
File "[SOURCE_DIR]/setuptools/config/pyprojecttoml.py", line 68, in apply_configuration
File "[CACHE_DIR]/[TMP]/pyprojecttoml.py", line 68, in apply_configuration
config = read_configuration(filepath, True, ignore_option_errors, dist)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[SOURCE_DIR]/setuptools/config/pyprojecttoml.py", line 129, in read_configuration
File "[CACHE_DIR]/[TMP]/pyprojecttoml.py", line 129, in read_configuration
validate(subset, filepath)
File "[SOURCE_DIR]/setuptools/config/pyprojecttoml.py", line 57, in validate
File "[CACHE_DIR]/[TMP]/pyprojecttoml.py", line 57, in validate
raise ValueError(f"{error}/n{summary}") from None
ValueError: invalid pyproject.toml config: `project.dependencies[0]`.
configuration error: `project.dependencies[0]` must be pep508
@ -458,13 +453,13 @@ fn respect_installed_and_reinstall() -> Result<()> {
let filters = if cfg!(windows) {
// Remove the colorama count on windows
INSTA_FILTERS
.iter()
.copied()
context
.filters()
.into_iter()
.chain([("Resolved 8 packages", "Resolved 7 packages")])
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters, command(&context)
.arg("-r")
@ -596,7 +591,6 @@ fn reinstall_extras() -> Result<()> {
/// Warn, but don't fail, when uninstalling incomplete packages.
#[test]
#[cfg(unix)]
fn reinstall_incomplete() -> Result<()> {
let context = TestContext::new("3.12");
@ -623,23 +617,14 @@ fn reinstall_incomplete() -> Result<()> {
);
// Manually remove the `RECORD` file.
fs_err::remove_file(
context
.venv
.join("lib/python3.12/site-packages/anyio-3.7.0.dist-info/RECORD"),
)?;
fs_err::remove_file(context.site_packages().join("anyio-3.7.0.dist-info/RECORD"))?;
// Re-install anyio.
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.touch()?;
requirements_txt.write_str("anyio==4.0.0")?;
let filters = [(r"Failed to uninstall package at .* due to missing RECORD", "Failed to uninstall package at .venv/lib/python3.12/site-packages/anyio-3.7.0.dist-info due to missing RECORD")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("-r")
.arg("requirements.txt"), @r###"
success: true
@ -649,7 +634,7 @@ fn reinstall_incomplete() -> Result<()> {
----- stderr -----
Resolved 3 packages in [TIME]
Downloaded 1 package in [TIME]
warning: Failed to uninstall package at .venv/lib/python3.12/site-packages/anyio-3.7.0.dist-info due to missing RECORD file. Installation may result in an incomplete environment.
warning: Failed to uninstall package at [SITE_PACKAGES]/anyio-3.7.0.dist-info due to missing RECORD file. Installation may result in an incomplete environment.
Installed 1 package in [TIME]
- anyio==3.7.0
+ anyio==4.0.0
@ -723,28 +708,13 @@ fn allow_incompatibilities() -> Result<()> {
}
#[test]
#[cfg(feature = "maturin")]
fn install_editable() -> Result<()> {
fn install_editable() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -756,24 +726,15 @@ fn install_editable() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
// Install it again (no-op).
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("install")
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.arg("--strict")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -784,19 +745,10 @@ fn install_editable() -> Result<()> {
);
// Add another, non-editable dependency.
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("install")
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.arg("black")
.arg("--strict")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable"))
.arg("black"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -812,35 +764,19 @@ fn install_editable() -> Result<()> {
+ packaging==24.0
+ pathspec==0.12.1
+ platformdirs==4.2.0
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
- poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
Ok(())
}
#[test]
fn install_editable_and_registry() -> Result<()> {
fn install_editable_and_registry() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters: Vec<_> = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
// Install the registry-based version of Black.
uv_snapshot!(filters, command(&context)
.arg("black")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(context.filters(), command(&context)
.arg("black"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -859,11 +795,9 @@ fn install_editable_and_registry() -> Result<()> {
);
// Install the editable version of Black. This should remove the registry-based version.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/black_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/black_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -873,17 +807,15 @@ fn install_editable_and_registry() -> Result<()> {
Resolved 1 package in [TIME]
Installed 1 package in [TIME]
- black==24.3.0
+ black==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/black_editable)
+ black==0.1.0 (from file://[WORKSPACE]/scripts/packages/black_editable)
"###
);
// Re-install the registry-based version of Black. This should be a no-op, since we have a
// version of Black installed (the editable version) that satisfies the requirements.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("black")
.arg("--strict")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -893,7 +825,8 @@ fn install_editable_and_registry() -> Result<()> {
"###
);
let filters2: Vec<_> = filters
let filters: Vec<_> = context
.filters()
.into_iter()
.chain([
// Remove colorama
@ -902,10 +835,8 @@ fn install_editable_and_registry() -> Result<()> {
.collect();
// Re-install Black at a specific version. This should replace the editable version.
uv_snapshot!(filters2, command(&context)
.arg("black==23.10.0")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(filters, command(&context)
.arg("black==23.10.0"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -914,38 +845,22 @@ fn install_editable_and_registry() -> Result<()> {
Resolved 6 packages in [TIME]
Downloaded 1 package in [TIME]
Installed 1 package in [TIME]
- black==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/black_editable)
- black==0.1.0 (from file://[WORKSPACE]/scripts/packages/black_editable)
+ black==23.10.0
"###
);
Ok(())
}
#[test]
fn install_editable_no_binary() -> Result<()> {
fn install_editable_no_binary() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package with no-binary enabled
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/black_editable")
.arg(context.workspace_root.join("scripts/packages/black_editable"))
.arg("--no-binary")
.arg(":all:")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(":all:"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -954,11 +869,9 @@ fn install_editable_no_binary() -> Result<()> {
Built 1 editable in [TIME]
Resolved 1 package in [TIME]
Installed 1 package in [TIME]
+ black==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/black_editable)
+ black==0.1.0 (from file://[WORKSPACE]/scripts/packages/black_editable)
"###
);
Ok(())
}
/// Install a source distribution that uses the `flit` build system, along with `flit`
@ -1198,15 +1111,16 @@ fn install_git_private_https_pat() {
let context = TestContext::new("3.8");
let token = decode_token(READ_ONLY_GITHUB_TOKEN);
let mut filters = INSTA_FILTERS.to_vec();
filters.insert(0, (&token, "***"));
let filters: Vec<_> = [(token.as_str(), "***")]
.into_iter()
.chain(context.filters())
.collect();
let mut command = command(&context);
command.arg(format!(
let package = format!(
"uv-private-pypackage @ git+https://{token}@github.com/astral-test/uv-private-pypackage"
));
);
uv_snapshot!(filters, command
uv_snapshot!(filters, command(&context).arg(package)
, @r###"
success: true
exit_code: 0
@ -1229,8 +1143,11 @@ fn install_git_private_https_pat_at_ref() {
let context = TestContext::new("3.8");
let token = decode_token(READ_ONLY_GITHUB_TOKEN);
let mut filters = INSTA_FILTERS.to_vec();
filters.insert(0, (&token, "***"));
let mut filters: Vec<_> = [(token.as_str(), "***")]
.into_iter()
.chain(context.filters())
.collect();
filters.push((r"git\+https://", ""));
// A user is _required_ on Windows
@ -1241,10 +1158,9 @@ fn install_git_private_https_pat_at_ref() {
""
};
let mut command = command(&context);
command.arg(format!("uv-private-pypackage @ git+https://{user}{token}@github.com/astral-test/uv-private-pypackage@6c09ce9ae81f50670a60abd7d95f30dd416d00ac"));
uv_snapshot!(filters, command, @r###"
let package = format!("uv-private-pypackage @ git+https://{user}{token}@github.com/astral-test/uv-private-pypackage@6c09ce9ae81f50670a60abd7d95f30dd416d00ac");
uv_snapshot!(filters, command(&context)
.arg(package), @r###"
success: true
exit_code: 0
----- stdout -----
@ -1272,13 +1188,12 @@ fn install_git_private_https_pat_and_username() {
let token = decode_token(READ_ONLY_GITHUB_TOKEN);
let user = "astral-test-bot";
let mut filters = INSTA_FILTERS.to_vec();
filters.insert(0, (&token, "***"));
let filters: Vec<_> = [(token.as_str(), "***")]
.into_iter()
.chain(context.filters())
.collect();
let mut command = command(&context);
command.arg(format!("uv-private-pypackage @ git+https://{user}:{token}@github.com/astral-test/uv-private-pypackage"));
uv_snapshot!(filters, command
uv_snapshot!(filters, command(&context).arg(format!("uv-private-pypackage @ git+https://{user}:{token}@github.com/astral-test/uv-private-pypackage"))
, @r###"
success: true
exit_code: 0
@ -1376,14 +1291,15 @@ fn reinstall_no_binary() {
// With `--reinstall`, `--no-binary` should have an affect
let filters = if cfg!(windows) {
// Remove the colorama count on windows
INSTA_FILTERS
.iter()
.copied()
context
.filters()
.into_iter()
.chain([("Resolved 8 packages", "Resolved 7 packages")])
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
let mut command = crate::command(&context);
command
.arg("anyio")
@ -2012,34 +1928,13 @@ fn launcher_with_symlink() -> Result<()> {
}
#[test]
#[cfg(unix)]
fn config_settings() -> Result<()> {
fn config_settings() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("install")
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/setuptools_editable")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/setuptools_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2050,45 +1945,25 @@ fn config_settings() -> Result<()> {
Downloaded 1 package in [TIME]
Installed 2 packages in [TIME]
+ iniconfig==2.0.0
+ setuptools-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/setuptools_editable)
+ setuptools-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/setuptools_editable)
"###
);
// When installed without `--editable_mode=compat`, the `finder.py` file should be present.
let finder = context
.venv
.join("lib/python3.12/site-packages")
.site_packages()
.join("__editable___setuptools_editable_0_1_0_finder.py");
assert!(finder.exists());
// Install the editable package with `--editable_mode=compat`.
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
.arg("pip")
.arg("install")
uv_snapshot!(context.filters(), command(&context)
.arg("-e")
.arg("../../scripts/packages/setuptools_editable")
.arg(context.workspace_root.join("scripts/packages/setuptools_editable"))
.arg("-C")
.arg("editable_mode=compat")
.arg("--cache-dir")
.arg(context.cache_dir.path())
.arg("--exclude-newer")
.arg(EXCLUDE_NEWER)
.env("VIRTUAL_ENV", context.venv.as_os_str())
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
, @r###"
success: true
exit_code: 0
----- stdout -----
@ -2099,23 +1974,19 @@ fn config_settings() -> Result<()> {
Downloaded 1 package in [TIME]
Installed 2 packages in [TIME]
+ iniconfig==2.0.0
+ setuptools-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/setuptools_editable)
+ setuptools-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/setuptools_editable)
"###
);
// When installed without `--editable_mode=compat`, the `finder.py` file should _not_ be present.
let finder = context
.venv
.join("lib/python3.12/site-packages")
.site_packages()
.join("__editable___setuptools_editable_0_1_0_finder.py");
assert!(!finder.exists());
Ok(())
}
/// Reinstall a duplicate package in a virtual environment.
#[test]
#[cfg(unix)]
fn reinstall_duplicate() -> Result<()> {
use crate::common::copy_dir_all;
@ -2153,12 +2024,8 @@ fn reinstall_duplicate() -> Result<()> {
// Copy the virtual environment to a new location.
copy_dir_all(
context2
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context1
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context2.site_packages().join("pip-22.1.1.dist-info"),
context1.site_packages().join("pip-22.1.1.dist-info"),
)?;
// Run `pip install`.
@ -2223,7 +2090,8 @@ fn invalidate_editable_on_change() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -2236,12 +2104,7 @@ requires-python = ">=3.8"
"#,
)?;
let filters = [(r"\(from file://.*\)", "(from [WORKSPACE_DIR])")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2254,14 +2117,14 @@ requires-python = ">=3.8"
Downloaded 3 packages in [TIME]
Installed 4 packages in [TIME]
+ anyio==4.0.0
+ example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
+ idna==3.6
+ sniffio==1.3.1
"###
);
// Re-installing should be a no-op.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2286,7 +2149,7 @@ requires-python = ">=3.8"
)?;
// Re-installing should update the package.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2300,8 +2163,8 @@ requires-python = ">=3.8"
Installed 2 packages in [TIME]
- anyio==4.0.0
+ anyio==3.7.1
- example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from [WORKSPACE_DIR])
- example==0.0.0 (from file://[TEMP_DIR]/editable)
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
"###
);
@ -2313,7 +2176,8 @@ fn invalidate_editable_dynamic() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with dynamic metadata
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
@ -2331,12 +2195,7 @@ dependencies = {file = ["requirements.txt"]}
let requirements_txt = editable_dir.child("requirements.txt");
requirements_txt.write_str("anyio==4.0.0")?;
let filters = [(r"\(from file://.*\)", "(from [WORKSPACE_DIR])")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2349,14 +2208,14 @@ dependencies = {file = ["requirements.txt"]}
Downloaded 3 packages in [TIME]
Installed 4 packages in [TIME]
+ anyio==4.0.0
+ example==0.1.0 (from [WORKSPACE_DIR])
+ example==0.1.0 (from file://[TEMP_DIR]/editable)
+ idna==3.6
+ sniffio==1.3.1
"###
);
// Re-installing should re-install.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2367,8 +2226,8 @@ dependencies = {file = ["requirements.txt"]}
Built 1 editable in [TIME]
Resolved 4 packages in [TIME]
Installed 1 package in [TIME]
- example==0.1.0 (from [WORKSPACE_DIR])
+ example==0.1.0 (from [WORKSPACE_DIR])
- example==0.1.0 (from file://[TEMP_DIR]/editable)
+ example==0.1.0 (from file://[TEMP_DIR]/editable)
"###
);
@ -2376,7 +2235,7 @@ dependencies = {file = ["requirements.txt"]}
requirements_txt.write_str("anyio==3.7.1")?;
// Re-installing should update the package.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2390,8 +2249,8 @@ dependencies = {file = ["requirements.txt"]}
Installed 2 packages in [TIME]
- anyio==4.0.0
+ anyio==3.7.1
- example==0.1.0 (from [WORKSPACE_DIR])
+ example==0.1.0 (from [WORKSPACE_DIR])
- example==0.1.0 (from file://[TEMP_DIR]/editable)
+ example==0.1.0 (from file://[TEMP_DIR]/editable)
"###
);
@ -2403,7 +2262,8 @@ fn invalidate_path_on_change() -> Result<()> {
let context = TestContext::new("3.12");
// Create a local package.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -2416,12 +2276,7 @@ requires-python = ">=3.8"
"#,
)?;
let filters = [(r"\(from file://.*\)", "(from [WORKSPACE_DIR])")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("example @ .")
.current_dir(editable_dir.path()), @r###"
success: true
@ -2433,14 +2288,14 @@ requires-python = ">=3.8"
Downloaded 4 packages in [TIME]
Installed 4 packages in [TIME]
+ anyio==4.0.0
+ example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
+ idna==3.6
+ sniffio==1.3.1
"###
);
// Re-installing should be a no-op.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("example @ .")
.current_dir(editable_dir.path()), @r###"
success: true
@ -2465,7 +2320,7 @@ requires-python = ">=3.8"
)?;
// Re-installing should update the package.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("example @ .")
.current_dir(editable_dir.path()), @r###"
success: true
@ -2478,8 +2333,8 @@ requires-python = ">=3.8"
Installed 2 packages in [TIME]
- anyio==4.0.0
+ anyio==3.7.1
- example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from [WORKSPACE_DIR])
- example==0.0.0 (from file://[TEMP_DIR]/editable)
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
"###
);
@ -2491,7 +2346,8 @@ requires-python = ">=3.8"
fn editable_url_with_marker() -> Result<()> {
let context = TestContext::new("3.12");
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
@ -2506,12 +2362,7 @@ requires-python = ">=3.11,<3.13"
"#,
)?;
let filters = [(r"\(from file://.*\)", "(from [WORKSPACE_DIR])")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("--editable")
.arg(editable_dir.path()), @r###"
success: true
@ -2524,7 +2375,7 @@ requires-python = ">=3.11,<3.13"
Downloaded 3 packages in [TIME]
Installed 4 packages in [TIME]
+ anyio==4.0.0
+ example==0.1.0 (from [WORKSPACE_DIR])
+ example==0.1.0 (from file://[TEMP_DIR]/editable)
+ idna==3.6
+ sniffio==1.3.1
"###
@ -2539,7 +2390,8 @@ fn requires_python_editable() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -2576,7 +2428,7 @@ fn no_build_isolation() -> Result<()> {
// We expect the build to fail, because `setuptools` is not installed.
let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
.arg("-r")
@ -2987,7 +2839,8 @@ fn requires_python_direct_url() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -3149,32 +3002,15 @@ fn install_site_packages_mtime_updated() -> Result<()> {
/// entry (because we want to ignore the entire cache from outside), ignoring all python source
/// files.
#[test]
fn deptry_gitignore() -> Result<()> {
fn deptry_gitignore() {
let context = TestContext::new("3.12");
let project_root = current_dir()?
.parent()
.unwrap()
.parent()
.unwrap()
.to_path_buf();
let source_dist_dir = project_root
.join("scripts")
.join("packages")
.join("deptry_reproducer");
let filter_path = regex::escape(
Url::from_directory_path(source_dist_dir.simplified_display().to_string())
.unwrap()
.to_string()
.trim_end_matches('/'),
);
let filters: Vec<_> = [(filter_path.as_str(), "[SOURCE_DIST_DIR]")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let source_dist_dir = context
.workspace_root
.join("scripts/packages/deptry_reproducer");
uv_snapshot!(filters, command(&context)
.arg(format!("deptry_reproducer @ {}/deptry_reproducer-0.1.0.tar.gz", source_dist_dir.simplified_display()))
uv_snapshot!(context.filters(), command(&context)
.arg(format!("deptry_reproducer @ {}", source_dist_dir.join("deptry_reproducer-0.1.0.tar.gz").simplified_display()))
.arg("--strict")
.current_dir(source_dist_dir), @r###"
success: true
@ -3186,7 +3022,7 @@ fn deptry_gitignore() -> Result<()> {
Downloaded 3 packages in [TIME]
Installed 3 packages in [TIME]
+ cffi==1.16.0
+ deptry-reproducer==0.1.0 (from [SOURCE_DIST_DIR]/deptry_reproducer-0.1.0.tar.gz)
+ deptry-reproducer==0.1.0 (from file://[WORKSPACE]/scripts/packages/deptry_reproducer/deptry_reproducer-0.1.0.tar.gz)
+ pycparser==2.21
"###
);
@ -3195,6 +3031,4 @@ fn deptry_gitignore() -> Result<()> {
context
.assert_command("import deptry_reproducer.foo")
.success();
Ok(())
}

View File

@ -11,7 +11,7 @@ use std::process::Command;
use assert_cmd::assert::Assert;
use assert_cmd::prelude::*;
use common::{venv_to_interpreter, INSTA_FILTERS};
use common::venv_to_interpreter;
use crate::common::{get_bin, uv_snapshot, TestContext};
@ -79,7 +79,7 @@ fn requires_package_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-package-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -118,7 +118,7 @@ fn requires_exact_version_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-exact-version-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -159,7 +159,7 @@ fn requires_greater_version_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-greater-version-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -201,7 +201,7 @@ fn requires_less_version_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-less-version-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -242,7 +242,7 @@ fn transitive_requires_package_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-requires-package-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -283,7 +283,7 @@ fn excluded_only_version() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"excluded-only-version-", "package-"));
uv_snapshot!(filters, command(&context)
@ -338,7 +338,7 @@ fn excluded_only_compatible_version() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"excluded-only-compatible-version-", "package-"));
uv_snapshot!(filters, command(&context)
@ -440,7 +440,7 @@ fn dependency_excludes_range_of_compatible_versions() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"dependency-excludes-range-of-compatible-versions-",
"package-",
@ -501,7 +501,7 @@ fn dependency_excludes_range_of_compatible_versions() {
/// There is a non-contiguous range of compatible versions for the requested package
/// `a`, but another dependency `c` excludes the range. This is the same as
/// `dependency-excludes-range-of-compatible-versions` but some of the versions of
/// `a` are incompatible for another reason e.g. dependency on non-existent package
/// `a` are incompatible for another reason e.g. dependency on non-existant package
/// `d`.
///
/// ```text
@ -565,7 +565,7 @@ fn dependency_excludes_non_contiguous_range_of_compatible_versions() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"dependency-excludes-non-contiguous-range-of-compatible-versions-",
"package-",
@ -646,7 +646,7 @@ fn extra_required() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"extra-required-", "package-"));
uv_snapshot!(filters, command(&context)
@ -696,7 +696,7 @@ fn missing_extra() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"missing-extra-", "package-"));
uv_snapshot!(filters, command(&context)
@ -746,7 +746,7 @@ fn multiple_extras_required() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"multiple-extras-required-", "package-"));
uv_snapshot!(filters, command(&context)
@ -826,7 +826,7 @@ fn all_extras_required() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"all-extras-required-", "package-"));
uv_snapshot!(filters, command(&context)
@ -894,7 +894,7 @@ fn extra_incompatible_with_extra() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"extra-incompatible-with-extra-", "package-"));
uv_snapshot!(filters, command(&context)
@ -948,7 +948,7 @@ fn extra_incompatible_with_extra_not_requested() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"extra-incompatible-with-extra-not-requested-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1009,7 +1009,7 @@ fn extra_incompatible_with_root() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"extra-incompatible-with-root-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1068,7 +1068,7 @@ fn extra_does_not_exist_backtrack() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"extra-does-not-exist-backtrack-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1115,7 +1115,7 @@ fn direct_incompatible_versions() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"direct-incompatible-versions-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1168,7 +1168,7 @@ fn transitive_incompatible_with_root_version() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-incompatible-with-root-version-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1226,7 +1226,7 @@ fn transitive_incompatible_with_transitive() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-incompatible-with-transitive-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1274,7 +1274,7 @@ fn local_simple() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-simple-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1313,7 +1313,7 @@ fn local_not_used_with_sdist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-not-used-with-sdist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1360,7 +1360,7 @@ fn local_used_without_sdist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-used-without-sdist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1405,7 +1405,7 @@ fn local_not_latest() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-not-latest-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1454,7 +1454,7 @@ fn local_transitive() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1512,7 +1512,7 @@ fn local_transitive_greater_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-greater-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1565,7 +1565,7 @@ fn local_transitive_greater_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-greater-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1623,7 +1623,7 @@ fn local_transitive_less_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-less-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1676,7 +1676,7 @@ fn local_transitive_less_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-less-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1734,7 +1734,7 @@ fn local_transitive_confounding() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-confounding-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1782,7 +1782,7 @@ fn local_transitive_conflicting() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-conflicting-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1841,7 +1841,7 @@ fn local_transitive_backtrack() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-transitive-backtrack-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1892,7 +1892,7 @@ fn local_greater_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-greater-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1927,7 +1927,7 @@ fn local_greater_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-greater-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -1970,7 +1970,7 @@ fn local_less_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-less-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2005,7 +2005,7 @@ fn local_less_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"local-less-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2045,7 +2045,7 @@ fn post_simple() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-simple-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2080,7 +2080,7 @@ fn post_greater_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-greater-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2123,7 +2123,7 @@ fn post_greater_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-greater-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2160,7 +2160,7 @@ fn post_greater_than_post() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-greater-than-post-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2206,7 +2206,7 @@ fn post_greater_than_or_equal_post() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-greater-than-or-equal-post-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2249,7 +2249,7 @@ fn post_less_than_or_equal() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-less-than-or-equal-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2288,7 +2288,7 @@ fn post_less_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-less-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2325,7 +2325,7 @@ fn post_local_greater_than() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-local-greater-than-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2366,7 +2366,7 @@ fn post_local_greater_than_post() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-local-greater-than-post-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2407,7 +2407,7 @@ fn post_equal_not_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-equal-not-available-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2448,7 +2448,7 @@ fn post_equal_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-equal-available-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2494,7 +2494,7 @@ fn post_greater_than_post_not_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"post-greater-than-post-not-available-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2534,7 +2534,7 @@ fn package_only_prereleases() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-only-prereleases-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2580,7 +2580,7 @@ fn package_only_prereleases_in_range() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-only-prereleases-in-range-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2626,7 +2626,7 @@ fn requires_package_only_prereleases_in_range_global_opt_in() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"requires-package-only-prereleases-in-range-global-opt-in-",
"package-",
@ -2674,7 +2674,7 @@ fn requires_package_prerelease_and_final_any() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-package-prerelease-and-final-any-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2723,7 +2723,7 @@ fn package_prerelease_specified_only_final_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"package-prerelease-specified-only-final-available-",
"package-",
@ -2774,7 +2774,7 @@ fn package_prerelease_specified_only_prerelease_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"package-prerelease-specified-only-prerelease-available-",
"package-",
@ -2827,7 +2827,7 @@ fn package_prerelease_specified_mixed_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-prerelease-specified-mixed-available-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2876,7 +2876,7 @@ fn package_multiple_prereleases_kinds() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-multiple-prereleases-kinds-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2923,7 +2923,7 @@ fn package_multiple_prereleases_numbers() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-multiple-prereleases-numbers-", "package-"));
uv_snapshot!(filters, command(&context)
@ -2971,7 +2971,7 @@ fn transitive_package_only_prereleases() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-package-only-prereleases-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3028,7 +3028,7 @@ fn transitive_package_only_prereleases_in_range() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-package-only-prereleases-in-range-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3082,7 +3082,7 @@ fn transitive_package_only_prereleases_in_range_opt_in() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-package-only-prereleases-in-range-opt-in-",
"package-",
@ -3149,7 +3149,7 @@ fn transitive_prerelease_and_stable_dependency() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-prerelease-and-stable-dependency-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3214,7 +3214,7 @@ fn transitive_prerelease_and_stable_dependency_opt_in() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-prerelease-and-stable-dependency-opt-in-",
"package-",
@ -3313,7 +3313,7 @@ fn transitive_prerelease_and_stable_dependency_many_versions() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-prerelease-and-stable-dependency-many-versions-",
"package-",
@ -3397,7 +3397,7 @@ fn transitive_prerelease_and_stable_dependency_many_versions_holes() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-prerelease-and-stable-dependency-many-versions-holes-",
"package-",
@ -3465,7 +3465,7 @@ fn package_only_prereleases_boundary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-only-prereleases-boundary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3483,7 +3483,7 @@ fn package_only_prereleases_boundary() {
"###);
// Since there are only prerelease versions of `a` available, a prerelease is
// allowed. Since the user did not explicitly request a pre-release, pre-releases at
// allowed. Since the user did not explictly request a pre-release, pre-releases at
// the boundary should not be selected.
assert_installed(
&context.venv,
@ -3513,7 +3513,7 @@ fn package_prereleases_boundary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-prereleases-boundary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3561,7 +3561,7 @@ fn package_prereleases_global_boundary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-prereleases-global-boundary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3612,7 +3612,7 @@ fn package_prereleases_specifier_boundary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-prereleases-specifier-boundary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3657,7 +3657,7 @@ fn python_version_does_not_exist() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-version-does-not-exist-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3699,7 +3699,7 @@ fn python_less_than_current() {
let context = TestContext::new("3.9");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-less-than-current-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3741,7 +3741,7 @@ fn python_greater_than_current() {
let context = TestContext::new("3.9");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-greater-than-current-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3783,7 +3783,7 @@ fn python_greater_than_current_patch() {
let context = TestContext::new("3.8.12");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-greater-than-current-patch-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3847,7 +3847,7 @@ fn python_greater_than_current_many() {
let context = TestContext::new("3.9");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-greater-than-current-many-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3896,7 +3896,7 @@ fn python_greater_than_current_backtrack() {
let context = TestContext::new("3.9");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-greater-than-current-backtrack-", "package-"));
uv_snapshot!(filters, command(&context)
@ -3947,7 +3947,7 @@ fn python_greater_than_current_excluded() {
let context = TestContext::new("3.9");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"python-greater-than-current-excluded-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4003,7 +4003,7 @@ fn specific_tag_and_default() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"specific-tag-and-default-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4038,7 +4038,7 @@ fn only_wheels() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"only-wheels-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4073,7 +4073,7 @@ fn no_wheels() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-wheels-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4108,7 +4108,7 @@ fn no_wheels_with_matching_platform() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-wheels-with-matching-platform-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4144,7 +4144,7 @@ fn no_sdist_no_wheels_with_matching_platform() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-sdist-no-wheels-with-matching-platform-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4185,7 +4185,7 @@ fn no_sdist_no_wheels_with_matching_python() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-sdist-no-wheels-with-matching-python-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4226,7 +4226,7 @@ fn no_sdist_no_wheels_with_matching_abi() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-sdist-no-wheels-with-matching-abi-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4267,7 +4267,7 @@ fn no_wheels_no_build() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-wheels-no-build-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4306,7 +4306,7 @@ fn only_wheels_no_binary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"only-wheels-no-binary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4345,7 +4345,7 @@ fn no_build() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-build-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4385,7 +4385,7 @@ fn no_binary() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"no-binary-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4425,7 +4425,7 @@ fn package_only_yanked() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-only-yanked-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4464,7 +4464,7 @@ fn package_only_yanked_in_range() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-only-yanked-in-range-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4511,7 +4511,7 @@ fn requires_package_yanked_and_unyanked_any() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"requires-package-yanked-and-unyanked-any-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4559,7 +4559,7 @@ fn package_yanked_specified_mixed_available() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"package-yanked-specified-mixed-available-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4607,7 +4607,7 @@ fn transitive_package_only_yanked() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-package-only-yanked-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4656,7 +4656,7 @@ fn transitive_package_only_yanked_in_range() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-package-only-yanked-in-range-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4711,7 +4711,7 @@ fn transitive_package_only_yanked_in_range_opt_in() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-package-only-yanked-in-range-opt-in-",
"package-",
@ -4779,7 +4779,7 @@ fn transitive_yanked_and_unyanked_dependency() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"transitive-yanked-and-unyanked-dependency-", "package-"));
uv_snapshot!(filters, command(&context)
@ -4841,7 +4841,7 @@ fn transitive_yanked_and_unyanked_dependency_opt_in() {
let context = TestContext::new("3.8");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((
r"transitive-yanked-and-unyanked-dependency-opt-in-",
"package-",

View File

@ -3,11 +3,10 @@ use std::process::Command;
use anyhow::Result;
use assert_fs::fixture::PathChild;
use assert_fs::fixture::{FileTouch, FileWriteStr};
use url::Url;
use common::uv_snapshot;
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER, INSTA_FILTERS};
use crate::common::{get_bin, TestContext, EXCLUDE_NEWER};
mod common;
@ -101,25 +100,13 @@ fn list_single_no_editable() -> Result<()> {
}
#[test]
fn list_editable() -> Result<()> {
fn list_editable() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir =
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?).unwrap();
let workspace_dir_re = regex::escape(workspace_dir.as_str());
let filters = [(workspace_dir_re.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, install_command(&context)
uv_snapshot!(context.filters(), install_command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -131,46 +118,15 @@ fn list_editable() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
// Account for difference length workspace dir
let prefix = if cfg!(windows) { "file:///" } else { "file://" };
// Origin of lengths used below:
// - |Editable project location| = 25
// - expected length = 48
// - expected length - |Editable project location| = 23
// - |`[WORKSPACE_DIR]/`| = 16
// - |`file://`| = 7, |`file:///`| = 8 (windows)
let workspace_len_difference = workspace_dir.as_str().len() + 23 - 16 - prefix.len();
let find_divider = "-".repeat(25 + workspace_len_difference);
let replace_divider = "-".repeat(48);
let find_header = format!(
"Editable project location{0}",
" ".repeat(workspace_len_difference)
);
let replace_header = format!("Editable project location{0}", " ".repeat(23));
let find_whitespace = " ".repeat(25 + workspace_len_difference);
let replace_whitespace = " ".repeat(48);
let search_workspace = workspace_dir_re.as_str().strip_prefix(prefix).unwrap();
let replace_workspace = "[WORKSPACE_DIR]/";
let filters = INSTA_FILTERS
.iter()
.copied()
.chain(vec![
(search_workspace, replace_workspace),
(find_divider.as_str(), replace_divider.as_str()),
(find_header.as_str(), replace_header.as_str()),
(find_whitespace.as_str(), replace_whitespace.as_str()),
])
let filters = context
.filters()
.into_iter()
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
@ -184,39 +140,25 @@ fn list_editable() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version Editable project location
--------------- ------- ------------------------------------------------
[UNDERLINE]
anyio 4.3.0
idna 3.6
poetry-editable 0.1.0 [WORKSPACE_DIR]/scripts/packages/poetry_editable
poetry-editable 0.1.0 [WORKSPACE]/scripts/packages/poetry_editable
sniffio 1.3.1
----- stderr -----
"###
);
Ok(())
}
#[test]
fn list_editable_only() -> Result<()> {
fn list_editable_only() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir =
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?).unwrap();
let workspace_dir_re = regex::escape(workspace_dir.as_str());
let filters = [(workspace_dir_re.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, install_command(&context)
uv_snapshot!(context.filters(), install_command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -228,39 +170,15 @@ fn list_editable_only() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
// Account for difference length workspace dir
let prefix = if cfg!(windows) { "file:///" } else { "file://" };
let workspace_len_difference = workspace_dir.as_str().len() + 23 - 16 - prefix.len();
let find_divider = "-".repeat(25 + workspace_len_difference);
let replace_divider = "-".repeat(48);
let find_header = format!(
"Editable project location{0}",
" ".repeat(workspace_len_difference)
);
let replace_header = format!("Editable project location{0}", " ".repeat(23));
let find_whitespace = " ".repeat(25 + workspace_len_difference);
let replace_whitespace = " ".repeat(48);
let search_workspace = workspace_dir_re.as_str().strip_prefix(prefix).unwrap();
let replace_workspace = "[WORKSPACE_DIR]/";
let filters = INSTA_FILTERS
.iter()
.copied()
.chain(vec![
(search_workspace, replace_workspace),
(find_divider.as_str(), replace_divider.as_str()),
(find_header.as_str(), replace_header.as_str()),
(find_whitespace.as_str(), replace_whitespace.as_str()),
])
let filters = context
.filters()
.into_iter()
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
@ -275,8 +193,8 @@ fn list_editable_only() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version Editable project location
--------------- ------- ------------------------------------------------
poetry-editable 0.1.0 [WORKSPACE_DIR]/scripts/packages/poetry_editable
[UNDERLINE]
poetry-editable 0.1.0 [WORKSPACE]/scripts/packages/poetry_editable
----- stderr -----
"###
@ -294,7 +212,7 @@ fn list_editable_only() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version
------- -------
[UNDERLINE]
anyio 4.3.0
idna 3.6
sniffio 1.3.1
@ -319,30 +237,16 @@ fn list_editable_only() -> Result<()> {
----- stderr -----
"###
);
Ok(())
}
#[test]
fn list_exclude() -> Result<()> {
fn list_exclude() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir =
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?).unwrap();
let workspace_dir_re = regex::escape(workspace_dir.as_str());
let filters = [(workspace_dir_re.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, install_command(&context)
uv_snapshot!(context.filters(), install_command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -354,39 +258,15 @@ fn list_exclude() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
// Account for difference length workspace dir
let prefix = if cfg!(windows) { "file:///" } else { "file://" };
let workspace_len_difference = workspace_dir.as_str().len() + 23 - 16 - prefix.len();
let find_divider = "-".repeat(25 + workspace_len_difference);
let replace_divider = "-".repeat(48);
let find_header = format!(
"Editable project location{0}",
" ".repeat(workspace_len_difference)
);
let replace_header = format!("Editable project location{0}", " ".repeat(23));
let find_whitespace = " ".repeat(25 + workspace_len_difference);
let replace_whitespace = " ".repeat(48);
let search_workspace = workspace_dir_re.as_str().strip_prefix(prefix).unwrap();
let replace_workspace = "[WORKSPACE_DIR]/";
let filters = INSTA_FILTERS
.iter()
.copied()
.chain(vec![
(search_workspace, replace_workspace),
(find_divider.as_str(), replace_divider.as_str()),
(find_header.as_str(), replace_header.as_str()),
(find_whitespace.as_str(), replace_whitespace.as_str()),
])
let filters = context
.filters()
.into_iter()
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
@ -402,10 +282,10 @@ fn list_exclude() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version Editable project location
--------------- ------- ------------------------------------------------
[UNDERLINE]
anyio 4.3.0
idna 3.6
poetry-editable 0.1.0 [WORKSPACE_DIR]/scripts/packages/poetry_editable
poetry-editable 0.1.0 [WORKSPACE]/scripts/packages/poetry_editable
sniffio 1.3.1
----- stderr -----
@ -425,7 +305,7 @@ fn list_exclude() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version
------- -------
[UNDERLINE]
anyio 4.3.0
idna 3.6
sniffio 1.3.1
@ -449,7 +329,7 @@ fn list_exclude() -> Result<()> {
exit_code: 0
----- stdout -----
Package Version
------- -------
[UNDERLINE]
anyio 4.3.0
idna 3.6
sniffio 1.3.1
@ -457,33 +337,17 @@ fn list_exclude() -> Result<()> {
----- stderr -----
"###
);
Ok(())
}
#[test]
#[cfg(not(windows))]
fn list_format_json() -> Result<()> {
fn list_format_json() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, install_command(&context)
uv_snapshot!(context.filters(), install_command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -495,46 +359,15 @@ fn list_format_json() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
let workspace_dir = regex::escape(
current_dir
.join("..")
.join("..")
.canonicalize()?
.to_str()
.unwrap(),
);
let workspace_len_difference = workspace_dir.as_str().len() + 23 - 16;
let find_divider = "-".repeat(25 + workspace_len_difference);
let replace_divider = "-".repeat(48);
let find_header = format!(
"Editable project location{0}",
" ".repeat(workspace_len_difference)
);
let replace_header = format!("Editable project location{0}", " ".repeat(23));
let find_whitespace = " ".repeat(25 + workspace_len_difference);
let replace_whitespace = " ".repeat(48);
let search_workspace = workspace_dir.as_str();
let search_workspace_escaped = search_workspace.replace('/', "\\\\");
let replace_workspace = "[WORKSPACE_DIR]";
let filters: Vec<_> = [
(search_workspace, replace_workspace),
(search_workspace_escaped.as_str(), replace_workspace),
(find_divider.as_str(), replace_divider.as_str()),
(find_header.as_str(), replace_header.as_str()),
(find_whitespace.as_str(), replace_whitespace.as_str()),
]
let filters: Vec<_> = context
.filters()
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect();
uv_snapshot!(filters, Command::new(get_bin())
@ -548,7 +381,7 @@ fn list_format_json() -> Result<()> {
success: true
exit_code: 0
----- stdout -----
[{"name":"anyio","version":"4.3.0"},{"name":"idna","version":"3.6"},{"name":"poetry-editable","version":"0.1.0","editable_project_location":"[WORKSPACE_DIR]/scripts/packages/poetry_editable"},{"name":"sniffio","version":"1.3.1"}]
[{"name":"anyio","version":"4.3.0"},{"name":"idna","version":"3.6"},{"name":"poetry-editable","version":"0.1.0","editable_project_location":"[WORKSPACE]/scripts/packages/poetry_editable"},{"name":"sniffio","version":"1.3.1"}]
----- stderr -----
"###
@ -566,7 +399,7 @@ fn list_format_json() -> Result<()> {
success: true
exit_code: 0
----- stdout -----
[{"name":"poetry-editable","version":"0.1.0","editable_project_location":"[WORKSPACE_DIR]/scripts/packages/poetry_editable"}]
[{"name":"poetry-editable","version":"0.1.0","editable_project_location":"[WORKSPACE]/scripts/packages/poetry_editable"}]
----- stderr -----
"###
@ -607,32 +440,16 @@ fn list_format_json() -> Result<()> {
----- stderr -----
"###
);
Ok(())
}
#[test]
fn list_format_freeze() -> Result<()> {
fn list_format_freeze() {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
// Install the editable package.
uv_snapshot!(filters, install_command(&context)
uv_snapshot!(context.filters(), install_command(&context)
.arg("-e")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -644,39 +461,15 @@ fn list_format_freeze() -> Result<()> {
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ sniffio==1.3.1
"###
);
// Account for difference length workspace dir
let prefix = if cfg!(windows) { "file:///" } else { "file://" };
let workspace_len_difference = workspace_dir.as_str().len() + 23 - 16 - prefix.len();
let find_divider = "-".repeat(25 + workspace_len_difference);
let replace_divider = "-".repeat(48);
let find_header = format!(
"Editable project location{0}",
" ".repeat(workspace_len_difference)
);
let replace_header = format!("Editable project location{0}", " ".repeat(23));
let find_whitespace = " ".repeat(25 + workspace_len_difference);
let replace_whitespace = " ".repeat(48);
let search_workspace = workspace_dir.as_str().strip_prefix(prefix).unwrap();
let replace_workspace = "[WORKSPACE_DIR]/";
let filters = INSTA_FILTERS
.iter()
.copied()
.chain(vec![
(search_workspace, replace_workspace),
(find_divider.as_str(), replace_divider.as_str()),
(find_header.as_str(), replace_header.as_str()),
(find_whitespace.as_str(), replace_whitespace.as_str()),
])
let filters = context
.filters()
.into_iter()
.chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")])
.collect::<Vec<_>>();
uv_snapshot!(filters, Command::new(get_bin())
@ -754,6 +547,4 @@ fn list_format_freeze() -> Result<()> {
----- stderr -----
"###
);
Ok(())
}

View File

@ -85,14 +85,7 @@ fn show_requires_multiple() -> Result<()> {
);
context.assert_command("import requests").success();
let filters = [(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)]
.to_vec();
// Guards against the package names being sorted.
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("requests")
@ -105,7 +98,7 @@ fn show_requires_multiple() -> Result<()> {
----- stdout -----
Name: requests
Version: 2.31.0
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires: certifi, charset-normalizer, idna, urllib3
Required-by:
@ -144,10 +137,7 @@ fn show_python_version_marker() -> Result<()> {
context.assert_command("import click").success();
let mut filters = vec![(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)];
let mut filters = context.filters();
if cfg!(windows) {
filters.push(("Requires: colorama", "Requires:"));
}
@ -165,7 +155,7 @@ fn show_python_version_marker() -> Result<()> {
----- stdout -----
Name: click
Version: 8.1.7
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by:
@ -202,12 +192,7 @@ fn show_found_single_package() -> Result<()> {
context.assert_command("import markupsafe").success();
let filters = vec![(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)];
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("markupsafe")
@ -220,7 +205,7 @@ fn show_found_single_package() -> Result<()> {
----- stdout -----
Name: markupsafe
Version: 2.1.3
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by:
@ -262,14 +247,7 @@ fn show_found_multiple_packages() -> Result<()> {
context.assert_command("import markupsafe").success();
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters = [(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)]
.to_vec();
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("markupsafe")
@ -283,13 +261,13 @@ fn show_found_multiple_packages() -> Result<()> {
----- stdout -----
Name: markupsafe
Version: 2.1.3
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by:
---
Name: pip
Version: 21.3.1
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by:
@ -331,14 +309,7 @@ fn show_found_one_out_of_three() -> Result<()> {
context.assert_command("import markupsafe").success();
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters = [(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)]
.to_vec();
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("markupsafe")
@ -353,7 +324,7 @@ fn show_found_one_out_of_three() -> Result<()> {
----- stdout -----
Name: markupsafe
Version: 2.1.3
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by:
@ -486,20 +457,7 @@ fn show_editable() -> Result<()> {
.assert()
.success();
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters = [
(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
),
(
r"Editable project location:.*poetry_editable",
"Editable project location: [EDITABLE_INSTALLS_PREFIX]poetry_editable",
),
]
.to_vec();
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("poetry-editable")
@ -512,8 +470,8 @@ fn show_editable() -> Result<()> {
----- stdout -----
Name: poetry-editable
Version: 0.1.0
Location: [WORKSPACE_DIR]/site-packages
Editable project location: [EDITABLE_INSTALLS_PREFIX]poetry_editable
Location: [SITE_PACKAGES]/
Editable project location: [WORKSPACE]/scripts/packages/poetry_editable
Requires: anyio
Required-by:
@ -559,14 +517,9 @@ fn show_required_by_multiple() -> Result<()> {
);
context.assert_command("import requests").success();
let filters = [(
r"Location:.*site-packages",
"Location: [WORKSPACE_DIR]/site-packages",
)]
.to_vec();
// idna is required by anyio and requests
uv_snapshot!(filters, Command::new(get_bin())
uv_snapshot!(context.filters(), Command::new(get_bin())
.arg("pip")
.arg("show")
.arg("idna")
@ -579,7 +532,7 @@ fn show_required_by_multiple() -> Result<()> {
----- stdout -----
Name: idna
Version: 3.6
Location: [WORKSPACE_DIR]/site-packages
Location: [SITE_PACKAGES]/
Requires:
Required-by: anyio, requests

View File

@ -10,6 +10,7 @@ use assert_cmd::prelude::*;
use assert_fs::fixture::ChildPath;
use assert_fs::prelude::*;
use indoc::indoc;
use predicates::Predicate;
use url::Url;
use common::{
@ -17,7 +18,7 @@ use common::{
};
use uv_fs::Simplified;
use crate::common::{get_bin, TestContext};
use crate::common::{copy_dir_all, get_bin, TestContext};
mod common;
@ -114,29 +115,22 @@ fn missing_requirements_txt() {
#[test]
fn missing_venv() -> Result<()> {
let temp_dir = assert_fs::TempDir::new()?;
let cache_dir = assert_fs::TempDir::new()?;
let venv = temp_dir.child(".venv");
let context = TestContext::new("3.12");
let requirements = context.temp_dir.child("requirements.txt");
requirements.write_str("anyio")?;
fs::remove_dir_all(&context.venv)?;
uv_snapshot!(Command::new(get_bin())
.arg("pip")
.arg("sync")
.arg("requirements.txt")
.arg("--strict")
.arg("--cache-dir")
.arg(cache_dir.path())
.env("VIRTUAL_ENV", venv.as_os_str())
.current_dir(&temp_dir), @r###"
uv_snapshot!(context.filters(), command(&context).arg("requirements.txt"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: failed to read from file `requirements.txt`
error: failed to canonicalize path `[VENV]/`
Caused by: No such file or directory (os error 2)
"###);
venv.assert(predicates::path::missing());
assert!(predicates::path::missing().eval(&context.venv));
Ok(())
}
@ -919,7 +913,7 @@ fn warn_on_yanked_version() -> Result<()> {
// This version is yanked.
requirements_in.write_str("colorama==0.4.2")?;
uv_snapshot!(INSTA_FILTERS, windows_filters=false, command(&context)
uv_snapshot!(context.filters(), windows_filters=false, command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -955,13 +949,7 @@ fn install_local_wheel() -> Result<()> {
Url::from_file_path(archive.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -982,7 +970,7 @@ fn install_local_wheel() -> Result<()> {
let venv = create_venv(&context.temp_dir, &context.cache_dir, "3.12");
// Reinstall. The wheel should come from the cache, so there shouldn't be a "download".
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1006,7 +994,7 @@ fn install_local_wheel() -> Result<()> {
filetime::set_file_mtime(&archive, filetime::FileTime::now()).unwrap();
// Reinstall. The wheel should be "downloaded" again.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1028,7 +1016,7 @@ fn install_local_wheel() -> Result<()> {
filetime::set_file_mtime(&archive, filetime::FileTime::now()).unwrap();
// Reinstall into the same virtual environment. The wheel should be reinstalled.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -1067,13 +1055,7 @@ fn mismatched_version() -> Result<()> {
Url::from_file_path(archive.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: false
@ -1108,13 +1090,7 @@ fn mismatched_name() -> Result<()> {
Url::from_file_path(archive.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: false
@ -1149,13 +1125,7 @@ fn install_local_source_distribution() -> Result<()> {
Url::from_file_path(archive.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -1267,10 +1237,10 @@ fn install_url_source_dist_cached() -> Result<()> {
let filters = if cfg!(windows) {
[("warning: The package `tqdm` requires `colorama ; platform_system == 'Windows'`, but it's not installed.\n", "")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters, command(&context)
.arg("requirements.txt")
@ -1290,7 +1260,8 @@ fn install_url_source_dist_cached() -> Result<()> {
context.assert_command("import tqdm").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(filters, command(&context)
@ -1310,7 +1281,8 @@ fn install_url_source_dist_cached() -> Result<()> {
context.assert_command("import tqdm").success();
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(Command::new(get_bin())
@ -1378,7 +1350,8 @@ fn install_git_source_dist_cached() -> Result<()> {
context.assert_command("import werkzeug").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(command(&context)
@ -1398,16 +1371,17 @@ fn install_git_source_dist_cached() -> Result<()> {
check_command(&venv, "import werkzeug", &context.temp_dir);
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
let filters = if cfg!(windows) {
[("Removed 2 files", "Removed 3 files")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters, Command::new(get_bin())
.arg("clean")
@ -1473,7 +1447,8 @@ fn install_registry_source_dist_cached() -> Result<()> {
context.assert_command("import future").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(command(&context)
@ -1493,16 +1468,17 @@ fn install_registry_source_dist_cached() -> Result<()> {
context.assert_command("import future").success();
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
let filters = if cfg!(windows) {
[("Removed 615 files", "Removed 616 files")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters, Command::new(get_bin())
.arg("clean")
@ -1558,13 +1534,7 @@ fn install_path_source_dist_cached() -> Result<()> {
Url::from_file_path(archive.path()).unwrap()
))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let filters: Vec<_> = [(r"file://.*/", "file://[TEMP_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -1582,10 +1552,11 @@ fn install_path_source_dist_cached() -> Result<()> {
context.assert_command("import wheel").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1602,18 +1573,19 @@ fn install_path_source_dist_cached() -> Result<()> {
context.assert_command("import wheel").success();
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
let filters2 = if cfg!(windows) {
let filters = if cfg!(windows) {
[("Removed 3 files", "Removed 4 files")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters2, Command::new(get_bin())
uv_snapshot!(filters, Command::new(get_bin())
.arg("clean")
.arg("wheel")
.arg("--cache-dir")
@ -1629,7 +1601,7 @@ fn install_path_source_dist_cached() -> Result<()> {
"###
);
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1665,17 +1637,7 @@ fn install_path_built_dist_cached() -> Result<()> {
let url = Url::from_file_path(archive.path()).unwrap();
requirements_txt.write_str(&format!("tomli @ {url}"))?;
// In addition to the standard filters, remove the temporary directory from the snapshot.
let url_escaped = regex::escape(url.as_str());
let filters: Vec<_> = [(
url_escaped.as_str(),
"file://[TEMP_DIR]/tomli-2.0.1-py3-none-any.whl",
)]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: true
@ -1693,10 +1655,11 @@ fn install_path_built_dist_cached() -> Result<()> {
context.assert_command("import tomli").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&context.temp_dir, &context.cache_dir, "3.12");
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1713,21 +1676,23 @@ fn install_path_built_dist_cached() -> Result<()> {
check_command(&venv, "import tomli", &parent);
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
let filters2 = if cfg!(windows) {
let filters = if cfg!(windows) {
// We do not display sizes on Windows
[(
"Removed 1 file for tomli",
"Removed 1 file for tomli ([SIZE])",
)]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters2, Command::new(get_bin())
uv_snapshot!(filters, Command::new(get_bin())
.arg("clean")
.arg("tomli")
.arg("--cache-dir")
@ -1743,7 +1708,7 @@ fn install_path_built_dist_cached() -> Result<()> {
"###
);
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict")
.env("VIRTUAL_ENV", venv.as_os_str()), @r###"
@ -1776,10 +1741,10 @@ fn install_url_built_dist_cached() -> Result<()> {
let filters = if cfg!(windows) {
[("warning: The package `tqdm` requires `colorama ; platform_system == 'Windows'`, but it's not installed.\n", "")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain(context.filters())
.collect()
} else {
INSTA_FILTERS.to_vec()
context.filters()
};
uv_snapshot!(filters, command(&context)
.arg("requirements.txt")
@ -1799,7 +1764,8 @@ fn install_url_built_dist_cached() -> Result<()> {
context.assert_command("import tqdm").success();
// Re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(filters, command(&context)
@ -1819,7 +1785,8 @@ fn install_url_built_dist_cached() -> Result<()> {
check_command(&venv, "import tqdm", &context.temp_dir);
// Clear the cache, then re-run the installation in a new virtual environment.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(Command::new(get_bin())
@ -2096,7 +2063,8 @@ fn refresh() -> Result<()> {
// Re-run the installation into with `--refresh`. Ensure that we resolve and download the
// latest versions of the packages.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(command(&context)
@ -2153,7 +2121,8 @@ fn refresh_package() -> Result<()> {
// Re-run the installation into with `--refresh`. Ensure that we resolve and download the
// latest versions of the packages.
let parent = assert_fs::TempDir::new()?;
let parent = context.temp_dir.child("parent");
parent.create_dir_all()?;
let venv = create_venv(&parent, &context.cache_dir, "3.12");
uv_snapshot!(command(&context)
@ -2186,40 +2155,20 @@ fn refresh_package() -> Result<()> {
fn sync_editable() -> Result<()> {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_url = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str()
.trim_end_matches(['\\', '/']),
);
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(&indoc::formatdoc! {r"
boltons==23.1.1
-e ../../scripts/packages/maturin_editable
-e {workspace_root}/scripts/packages/maturin_editable
numpy==1.26.2
# via poetry-editable
-e file://{current_dir}/../../scripts/packages/poetry_editable
-e file://{workspace_root}/scripts/packages/poetry_editable
",
current_dir = current_dir.simplified_display(),
workspace_root = context.workspace_root.simplified_display(),
})?;
let filter_path = regex::escape(&requirements_txt.user_display().to_string());
let filters = INSTA_FILTERS
.iter()
.chain(&[
(filter_path.as_str(), "requirements.txt"),
(&workspace_url, "file://[WORKSPACE_DIR]"),
])
.copied()
.collect::<Vec<_>>();
// Install the editable packages.
uv_snapshot!(filters, command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path()), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2230,19 +2179,17 @@ fn sync_editable() -> Result<()> {
Downloaded 2 packages in [TIME]
Installed 4 packages in [TIME]
+ boltons==23.1.1
+ maturin-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/maturin_editable)
+ maturin-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/maturin_editable)
+ numpy==1.26.2
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
// Reinstall the editable packages.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path())
.arg("--reinstall-package")
.arg("poetry-editable")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2251,20 +2198,21 @@ fn sync_editable() -> Result<()> {
Built 1 editable in [TIME]
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
- poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
+ poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
// Make sure we have the right base case.
let python_source_file =
"../../scripts/packages/maturin_editable/python/maturin_editable/__init__.py";
let python_source_file = context
.workspace_root
.join("scripts/packages/maturin_editable/python/maturin_editable/__init__.py");
let python_version_1 = indoc::indoc! {r"
from .maturin_editable import *
version = 1
"};
fs_err::write(python_source_file, python_version_1)?;
fs_err::write(&python_source_file, python_version_1)?;
let check_installed = indoc::indoc! {r#"
from maturin_editable import sum_as_string, version
@ -2280,7 +2228,7 @@ fn sync_editable() -> Result<()> {
version = 2
"};
fs_err::write(python_source_file, python_version_2)?;
fs_err::write(&python_source_file, python_version_2)?;
let check_installed = indoc::indoc! {r#"
from maturin_editable import sum_as_string, version
@ -2292,12 +2240,10 @@ fn sync_editable() -> Result<()> {
context.assert_command(check_installed).success();
// Don't create a git diff.
fs_err::write(python_source_file, python_version_1)?;
fs_err::write(&python_source_file, python_version_1)?;
uv_snapshot!(filters, command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path()), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2314,12 +2260,13 @@ fn sync_editable() -> Result<()> {
fn sync_editable_and_registry() -> Result<()> {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_url = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
// Copy the black test editable into the "current" directory
copy_dir_all(
context
.workspace_root
.join("scripts/packages/black_editable"),
context.temp_dir.join("black_editable"),
)?;
// Install the registry-based version of Black.
let requirements_txt = context.temp_dir.child("requirements.txt");
@ -2328,20 +2275,9 @@ fn sync_editable_and_registry() -> Result<()> {
"
})?;
let filter_path = regex::escape(&requirements_txt.user_display().to_string());
let filters = INSTA_FILTERS
.iter()
.chain(&[
(filter_path.as_str(), "requirements.txt"),
(workspace_url.as_str(), "file://[WORKSPACE_DIR]/"),
])
.copied()
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path())
.arg("--strict")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2363,23 +2299,12 @@ fn sync_editable_and_registry() -> Result<()> {
// Use the `file:` syntax for extra coverage.
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(indoc::indoc! {r"
-e file:../../scripts/packages/black_editable
-e file:./black_editable
"
})?;
let filter_path = regex::escape(&requirements_txt.user_display().to_string());
let filters = INSTA_FILTERS
.iter()
.chain(&[
(filter_path.as_str(), "requirements.txt"),
(workspace_url.as_str(), "file://[WORKSPACE_DIR]/"),
])
.copied()
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path()), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2389,7 +2314,7 @@ fn sync_editable_and_registry() -> Result<()> {
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
- black==24.1.0
+ black==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/black_editable)
+ black==0.1.0 (from file://[TEMP_DIR]/black_editable)
"###
);
@ -2401,19 +2326,8 @@ fn sync_editable_and_registry() -> Result<()> {
"
})?;
let filter_path = regex::escape(&requirements_txt.user_display().to_string());
let filters = INSTA_FILTERS
.iter()
.chain(&[
(filter_path.as_str(), "requirements.txt"),
(workspace_url.as_str(), "file://[WORKSPACE_DIR]/"),
])
.copied()
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path()), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2430,20 +2344,9 @@ fn sync_editable_and_registry() -> Result<()> {
"
})?;
let filter_path = regex::escape(&requirements_txt.user_display().to_string());
let filters = INSTA_FILTERS
.iter()
.chain(&[
(filter_path.as_str(), "requirements.txt"),
(workspace_url.as_str(), "file://[WORKSPACE_DIR]/"),
])
.copied()
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg(requirements_txt.path())
.arg("--strict")
.current_dir(&current_dir)
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
.arg("--strict"), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2453,7 +2356,7 @@ fn sync_editable_and_registry() -> Result<()> {
Downloaded 1 package in [TIME]
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
- black==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/black_editable)
- black==0.1.0 (from file://[TEMP_DIR]/black_editable)
+ black==23.10.0
warning: The package `black` requires `click>=8.0.0`, but it's not installed.
warning: The package `black` requires `mypy-extensions>=0.4.3`, but it's not installed.
@ -2469,24 +2372,13 @@ fn sync_editable_and_registry() -> Result<()> {
#[test]
fn incompatible_wheel() -> Result<()> {
let context = TestContext::new("3.12");
let wheel_dir = assert_fs::TempDir::new()?;
let wheel = wheel_dir.child("foo-1.2.3-not-compatible-wheel.whl");
let wheel = context.temp_dir.child("foo-1.2.3-not-compatible-wheel.whl");
wheel.touch()?;
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(&format!(
"foo @ {}",
Url::from_file_path(wheel.path()).unwrap()
))?;
requirements_txt.write_str(&format!("foo @ {}", wheel.path().simplified_display()))?;
let wheel_dir = regex::escape(&wheel_dir.path().canonicalize()?.user_display().to_string());
let filters: Vec<_> = [(wheel_dir.as_str(), "[TEMP_DIR]")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--strict"), @r###"
success: false
@ -2495,7 +2387,7 @@ fn incompatible_wheel() -> Result<()> {
----- stderr -----
error: Failed to determine installation plan
Caused by: A path dependency is incompatible with the current platform: [TEMP_DIR]/foo-1.2.3-not-compatible-wheel.whl
Caused by: A path dependency is incompatible with the current platform: foo-1.2.3-not-compatible-wheel.whl
"###
);
@ -2566,17 +2458,10 @@ fn find_links() -> Result<()> {
werkzeug @ https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl
"})?;
let project_root = fs_err::canonicalize(std::env::current_dir()?.join("../.."))?;
let project_root_string = regex::escape(&project_root.user_display().to_string());
let filters: Vec<_> = [(project_root_string.as_str(), "[PROJECT_ROOT]")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.txt")
.arg("--find-links")
.arg(project_root.join("scripts/wheels/")), @r###"
.arg(context.workspace_root.join("scripts/wheels/")), @r###"
success: true
exit_code: 0
----- stdout -----
@ -2785,7 +2670,8 @@ fn invalidate_on_change() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -2802,12 +2688,7 @@ requires-python = ">=3.8"
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str(&format!("-e {}", editable_dir.path().display()))?;
let filters = [(r"\(from file://.*\)", "(from [WORKSPACE_DIR])")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect::<Vec<_>>();
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2816,12 +2697,12 @@ requires-python = ">=3.8"
----- stderr -----
Built 1 editable in [TIME]
Installed 1 package in [TIME]
+ example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
"###
);
// Re-installing should be a no-op.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2845,7 +2726,7 @@ requires-python = ">=3.8"
)?;
// Re-installing should update the package.
uv_snapshot!(filters, command(&context)
uv_snapshot!(context.filters(), command(&context)
.arg("requirements.in"), @r###"
success: true
exit_code: 0
@ -2855,8 +2736,8 @@ requires-python = ">=3.8"
Built 1 editable in [TIME]
Uninstalled 1 package in [TIME]
Installed 1 package in [TIME]
- example==0.0.0 (from [WORKSPACE_DIR])
+ example==0.0.0 (from [WORKSPACE_DIR])
- example==0.0.0 (from file://[TEMP_DIR]/editable)
+ example==0.0.0 (from file://[TEMP_DIR]/editable)
"###
);
@ -2907,28 +2788,18 @@ fn compile_invalid_pyc_invalidation_mode() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.touch()?;
requirements_txt.write_str("MarkupSafe==2.1.3")?;
let site_packages = regex::escape(
&context
.site_packages()
.canonicalize()
.unwrap()
.user_display()
.to_string(),
);
let filters: Vec<_> = [
(site_packages.as_str(), "[SITE-PACKAGES]"),
(r"\.venv/lib/python3.12/site-packages", "[SITE-PACKAGES]"),
(r"\.venv/Lib/site-packages", "[SITE-PACKAGES]"),
(
r#"\[SITE-PACKAGES\].*.py", received: "#,
r#"[SITE-PACKAGES]/[FIRST-FILE]", received: "#,
),
]
let filters: Vec<_> = context
.filters()
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.chain([
// The first file can vary so we capture it here
(
r#"\[SITE_PACKAGES\].*\.py", received: "#,
r#"[SITE_PACKAGES]/[FILE].py", received: "#,
),
])
.collect();
uv_snapshot!(filters, command(&context)
@ -2944,10 +2815,10 @@ fn compile_invalid_pyc_invalidation_mode() -> Result<()> {
Resolved 1 package in [TIME]
Downloaded 1 package in [TIME]
Installed 1 package in [TIME]
error: Failed to bytecode-compile Python file in: [SITE-PACKAGES]
error: Failed to bytecode-compile Python file in: [SITE_PACKAGES]/
Caused by: Python process stderr:
Invalid value for PYC_INVALIDATION_MODE "bogus", valid are "TIMESTAMP", "CHECKED_HASH", "UNCHECKED_HASH":
Caused by: Bytecode compilation failed, expected "[SITE-PACKAGES]/[FIRST-FILE]", received: ""
Caused by: Bytecode compilation failed, expected "[SITE_PACKAGES]/[FILE].py", received: ""
"###
);
@ -2960,7 +2831,8 @@ fn requires_python_editable() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]
@ -3031,7 +2903,8 @@ fn requires_python_direct_url() -> Result<()> {
let context = TestContext::new("3.12");
// Create an editable package with a `Requires-Python` constraint that is not met.
let editable_dir = assert_fs::TempDir::new()?;
let editable_dir = context.temp_dir.child("editable");
editable_dir.create_dir_all()?;
let pyproject_toml = editable_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"[project]

View File

@ -3,9 +3,8 @@ use std::process::Command;
use anyhow::Result;
use assert_cmd::prelude::*;
use assert_fs::prelude::*;
use url::Url;
use common::{uv_snapshot, INSTA_FILTERS};
use common::uv_snapshot;
use crate::common::{get_bin, venv_to_interpreter, TestContext};
@ -212,41 +211,17 @@ fn missing_record() -> Result<()> {
.success();
// Delete the RECORD file.
let dist_info = fs_err::canonicalize(if cfg!(unix) {
context
.venv
.join("lib")
.join("python3.12")
.join("site-packages")
.join("MarkupSafe-2.1.3.dist-info")
} else if cfg!(windows) {
context
.venv
.join("Lib")
.join("site-packages")
.join("MarkupSafe-2.1.3.dist-info")
} else {
unimplemented!("Only Windows and Unix are supported")
})
.unwrap();
let dist_info = context.site_packages().join("MarkupSafe-2.1.3.dist-info");
fs_err::remove_file(dist_info.join("RECORD"))?;
let filters: Vec<_> = [(
r"RECORD file not found at: .*",
"RECORD file not found at: [RECORD]",
)]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
uv_snapshot!(filters, uninstall_command(&context)
uv_snapshot!(context.filters(), uninstall_command(&context)
.arg("MarkupSafe"), @r###"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
error: Cannot uninstall package; RECORD file not found at: [RECORD]
error: Cannot uninstall package; RECORD file not found at: [SITE_PACKAGES]/MarkupSafe-2.1.3.dist-info/RECORD
"###
);
@ -257,25 +232,19 @@ fn missing_record() -> Result<()> {
fn uninstall_editable_by_name() -> Result<()> {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters: Vec<_> = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.touch()?;
requirements_txt.write_str("-e ../../scripts/packages/poetry_editable")?;
requirements_txt.write_str(&format!(
"-e {}",
context
.workspace_root
.join("scripts/packages/poetry_editable")
.as_os_str()
.to_str()
.expect("Path is valid unicode")
))?;
sync_command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.assert()
.success();
@ -286,7 +255,7 @@ fn uninstall_editable_by_name() -> Result<()> {
.success();
// Uninstall the editable by name.
uv_snapshot!(filters, uninstall_command(&context)
uv_snapshot!(context.filters(), uninstall_command(&context)
.arg("poetry-editable"), @r###"
success: true
exit_code: 0
@ -294,7 +263,7 @@ fn uninstall_editable_by_name() -> Result<()> {
----- stderr -----
Uninstalled 1 package in [TIME]
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
- poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
@ -311,25 +280,19 @@ fn uninstall_editable_by_name() -> Result<()> {
fn uninstall_by_path() -> Result<()> {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters: Vec<_> = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.touch()?;
requirements_txt.write_str("../../scripts/packages/poetry_editable")?;
requirements_txt.write_str(
context
.workspace_root
.join("scripts/packages/poetry_editable")
.as_os_str()
.to_str()
.expect("Path is valid unicode"),
)?;
sync_command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.assert()
.success();
@ -340,16 +303,15 @@ fn uninstall_by_path() -> Result<()> {
.success();
// Uninstall the editable by path.
uv_snapshot!(filters, uninstall_command(&context)
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir), @r###"
uv_snapshot!(context.filters(), uninstall_command(&context)
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Uninstalled 1 package in [TIME]
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
- poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
@ -366,25 +328,19 @@ fn uninstall_by_path() -> Result<()> {
fn uninstall_duplicate_by_path() -> Result<()> {
let context = TestContext::new("3.12");
let current_dir = std::env::current_dir()?;
let workspace_dir = regex::escape(
Url::from_directory_path(current_dir.join("..").join("..").canonicalize()?)
.unwrap()
.as_str(),
);
let filters: Vec<_> = [(workspace_dir.as_str(), "file://[WORKSPACE_DIR]/")]
.into_iter()
.chain(INSTA_FILTERS.to_vec())
.collect();
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.touch()?;
requirements_txt.write_str("../../scripts/packages/poetry_editable")?;
requirements_txt.write_str(
context
.workspace_root
.join("scripts/packages/poetry_editable")
.as_os_str()
.to_str()
.expect("Path is valid unicode"),
)?;
sync_command(&context)
.arg(requirements_txt.path())
.current_dir(&current_dir)
.assert()
.success();
@ -395,17 +351,16 @@ fn uninstall_duplicate_by_path() -> Result<()> {
.success();
// Uninstall the editable by both path and name.
uv_snapshot!(filters, uninstall_command(&context)
uv_snapshot!(context.filters(), uninstall_command(&context)
.arg("poetry-editable")
.arg("../../scripts/packages/poetry_editable")
.current_dir(&current_dir), @r###"
.arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Uninstalled 1 package in [TIME]
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/packages/poetry_editable)
- poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable)
"###
);
@ -420,7 +375,6 @@ fn uninstall_duplicate_by_path() -> Result<()> {
/// Uninstall a duplicate package in a virtual environment.
#[test]
#[cfg(unix)]
fn uninstall_duplicate() -> Result<()> {
use crate::common::copy_dir_all;
@ -450,12 +404,8 @@ fn uninstall_duplicate() -> Result<()> {
// Copy the virtual environment to a new location.
copy_dir_all(
context2
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context1
.venv
.join("lib/python3.12/site-packages/pip-22.1.1.dist-info"),
context2.site_packages().join("pip-22.1.1.dist-info"),
context1.site_packages().join("pip-22.1.1.dist-info"),
)?;
// Run `pip uninstall`.

View File

@ -64,7 +64,7 @@ fn {{module_name}}() -> Result<()> {
let python_versions = &[{{#environment.additional_python}}"{{.}}", {{/environment.additional_python}}];
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"{{name}}-", "package-"));
let requirements_in = context.temp_dir.child("requirements.in");

View File

@ -82,7 +82,7 @@ fn {{module_name}}() {
let context = TestContext::new("{{environment.python}}");
// In addition to the standard filters, swap out package names for shorter messages
let mut filters = INSTA_FILTERS.to_vec();
let mut filters = context.filters();
filters.push((r"{{name}}-", "package-"));
uv_snapshot!(filters, command(&context)