93d3093a2a
Closes #810 Closes https://github.com/astral-sh/puffin/issues/812 Requires https://github.com/zanieb/pubgrub/pull/19 and https://github.com/zanieb/pubgrub/pull/18 - Always pair package ranges with names e.g. `... of a matching a<1.0` instead of `... of a matching <1.0` - Split range segments onto multiple lines when not a singleton as suggested in [#850](https://github.com/astral-sh/puffin/pull/850#discussion_r1446419610) - Improve formatting when ranges are split across multiple lines e.g. by avoiding extra spaces and improving wording Note review will require expanding the hidden files as there are significant changes to the report formatter and snapshots. Bear with me here as these are definitely not perfect still. The following changes build on top of this independently for further improvements: - #868 - #867 - #866 - #871
704 lines
22 KiB
Rust
704 lines
22 KiB
Rust
#![cfg(all(feature = "python", feature = "pypi"))]
|
||
|
||
use std::iter;
|
||
use std::path::Path;
|
||
use std::process::Command;
|
||
|
||
use anyhow::Result;
|
||
use assert_cmd::assert::Assert;
|
||
use assert_cmd::prelude::*;
|
||
use assert_fs::prelude::*;
|
||
use insta_cmd::_macro_support::insta;
|
||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||
|
||
use common::{create_venv_py312, BIN_NAME, INSTA_FILTERS};
|
||
|
||
mod common;
|
||
|
||
// Exclude any packages uploaded after this date.
|
||
static EXCLUDE_NEWER: &str = "2023-11-18T12:00:00Z";
|
||
|
||
fn assert_command(venv: &Path, command: &str, temp_dir: &Path) -> Assert {
|
||
Command::new(venv.join("bin").join("python"))
|
||
.arg("-c")
|
||
.arg(command)
|
||
.current_dir(temp_dir)
|
||
.assert()
|
||
}
|
||
|
||
#[test]
|
||
fn missing_requirements_txt() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: false
|
||
exit_code: 2
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
error: failed to open file `requirements.txt`
|
||
Caused by: No such file or directory (os error 2)
|
||
"###);
|
||
|
||
requirements_txt.assert(predicates::path::missing());
|
||
|
||
Ok(())
|
||
}
|
||
|
||
#[test]
|
||
fn no_solution() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("flask>=3.0.0")
|
||
.arg("WerkZeug<1.0.0")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: false
|
||
exit_code: 1
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
× No solution found when resolving dependencies:
|
||
╰─▶ Because there are no versions of flask that satisfy flask>3.0.0
|
||
and flask==3.0.0 depends on werkzeug>=3.0.0, we can conclude that
|
||
flask>=3.0.0 depends on werkzeug>=3.0.0.
|
||
And because root depends on flask>=3.0.0 and root depends on
|
||
werkzeug<1.0.0, we can conclude that the requirements are unsatisfiable.
|
||
"###);
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// Install a package from the command line into a virtual environment.
|
||
#[test]
|
||
fn install_package() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
// Install Flask.
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("Flask")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 7 packages in [TIME]
|
||
Installed 7 packages in [TIME]
|
||
+ blinker==1.7.0
|
||
+ click==8.1.7
|
||
+ flask==3.0.0
|
||
+ itsdangerous==2.1.2
|
||
+ jinja2==3.1.2
|
||
+ markupsafe==2.1.3
|
||
+ werkzeug==3.0.1
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// Install a package from a `requirements.txt` into a virtual environment.
|
||
#[test]
|
||
fn install_requirements_txt() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
// Install Flask.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.write_str("Flask")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 7 packages in [TIME]
|
||
Installed 7 packages in [TIME]
|
||
+ blinker==1.7.0
|
||
+ click==8.1.7
|
||
+ flask==3.0.0
|
||
+ itsdangerous==2.1.2
|
||
+ jinja2==3.1.2
|
||
+ markupsafe==2.1.3
|
||
+ werkzeug==3.0.1
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
// Install Jinja2 (which should already be installed, but shouldn't remove other packages).
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.write_str("Jinja2")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Audited 1 package in [TIME]
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// Respect installed versions when resolving.
|
||
#[test]
|
||
fn respect_installed() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
// Install Flask.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("Flask==2.3.2")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 7 packages in [TIME]
|
||
Installed 7 packages in [TIME]
|
||
+ blinker==1.7.0
|
||
+ click==8.1.7
|
||
+ flask==2.3.2
|
||
+ itsdangerous==2.1.2
|
||
+ jinja2==3.1.2
|
||
+ markupsafe==2.1.3
|
||
+ werkzeug==3.0.1
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
// Re-install Flask. We should respect the existing version.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("Flask")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Audited 1 package in [TIME]
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
// Install a newer version of Flask. We should upgrade it.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("Flask==2.3.3")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 1 package in [TIME]
|
||
Installed 1 package in [TIME]
|
||
- flask==2.3.2
|
||
+ flask==2.3.3
|
||
"###);
|
||
});
|
||
|
||
// Re-install Flask. We should upgrade it.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("Flask")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--reinstall-package")
|
||
.arg("Flask")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 1 package in [TIME]
|
||
Installed 1 package in [TIME]
|
||
- flask==2.3.3
|
||
+ flask==3.0.0
|
||
"###);
|
||
});
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// Like `pip`, we (unfortunately) allow incompatible environments.
|
||
#[test]
|
||
fn allow_incompatibilities() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
// Install Flask, which relies on `Werkzeug>=3.0.0`.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("Flask")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 7 packages in [TIME]
|
||
Downloaded 7 packages in [TIME]
|
||
Installed 7 packages in [TIME]
|
||
+ blinker==1.7.0
|
||
+ click==8.1.7
|
||
+ flask==3.0.0
|
||
+ itsdangerous==2.1.2
|
||
+ jinja2==3.1.2
|
||
+ markupsafe==2.1.3
|
||
+ werkzeug==3.0.1
|
||
"###);
|
||
});
|
||
|
||
assert_command(&venv, "import flask", &temp_dir).success();
|
||
|
||
// Install an incompatible version of Jinja2.
|
||
let requirements_txt = temp_dir.child("requirements.txt");
|
||
requirements_txt.touch()?;
|
||
requirements_txt.write_str("jinja2==2.11.3")?;
|
||
|
||
insta::with_settings!({
|
||
filters => INSTA_FILTERS.to_vec()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-r")
|
||
.arg("requirements.txt")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.current_dir(&temp_dir), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 2 packages in [TIME]
|
||
Downloaded 1 package in [TIME]
|
||
Installed 1 package in [TIME]
|
||
- jinja2==3.1.2
|
||
+ jinja2==2.11.3
|
||
warning: The package `flask` requires `jinja2 >=3.1.2`, but `2.11.3` is installed.
|
||
"###);
|
||
});
|
||
|
||
// This no longer works, since we have an incompatible version of Jinja2.
|
||
assert_command(&venv, "import flask", &temp_dir).failure();
|
||
|
||
Ok(())
|
||
}
|
||
|
||
#[test]
|
||
#[cfg(feature = "maturin")]
|
||
fn install_editable() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
let current_dir = std::env::current_dir()?;
|
||
let workspace_dir = current_dir.join("..").join("..").canonicalize()?;
|
||
|
||
let filters = iter::once((workspace_dir.to_str().unwrap(), "[WORKSPACE_DIR]"))
|
||
.chain(INSTA_FILTERS.to_vec())
|
||
.collect::<Vec<_>>();
|
||
|
||
// Install the editable package.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/poetry_editable")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Built 1 editable in [TIME]
|
||
Resolved 2 packages in [TIME]
|
||
Downloaded 1 package in [TIME]
|
||
Installed 2 packages in [TIME]
|
||
+ numpy==1.26.2
|
||
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/poetry_editable/)
|
||
"###);
|
||
});
|
||
|
||
// Install it again (no-op).
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/poetry_editable")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Audited 1 package in [TIME]
|
||
"###);
|
||
});
|
||
|
||
// Add another, non-editable dependency.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/poetry_editable")
|
||
.arg("black")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Built 1 editable in [TIME]
|
||
Resolved 8 packages in [TIME]
|
||
Downloaded 6 packages in [TIME]
|
||
Installed 7 packages in [TIME]
|
||
+ black==23.11.0
|
||
+ click==8.1.7
|
||
+ mypy-extensions==1.0.0
|
||
+ packaging==23.2
|
||
+ pathspec==0.11.2
|
||
+ platformdirs==4.0.0
|
||
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/poetry_editable/)
|
||
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/poetry_editable/)
|
||
"###);
|
||
});
|
||
|
||
// Add another, editable dependency.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/poetry_editable")
|
||
.arg("black")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/maturin_editable")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Built 2 editables in [TIME]
|
||
Resolved 9 packages in [TIME]
|
||
Installed 2 packages in [TIME]
|
||
+ maturin-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/maturin_editable/)
|
||
- poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/poetry_editable/)
|
||
+ poetry-editable==0.1.0 (from file://[WORKSPACE_DIR]/scripts/editable-installs/poetry_editable/)
|
||
"###);
|
||
});
|
||
|
||
Ok(())
|
||
}
|
||
|
||
#[test]
|
||
fn install_editable_and_registry() -> Result<()> {
|
||
let temp_dir = assert_fs::TempDir::new()?;
|
||
let cache_dir = assert_fs::TempDir::new()?;
|
||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||
|
||
let current_dir = std::env::current_dir()?;
|
||
let workspace_dir = current_dir.join("..").join("..").canonicalize()?;
|
||
|
||
let filters: Vec<_> = iter::once((workspace_dir.to_str().unwrap(), "[WORKSPACE_DIR]"))
|
||
.chain(INSTA_FILTERS.to_vec())
|
||
.collect();
|
||
|
||
// Install the registry-based version of Black.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("black")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 6 packages in [TIME]
|
||
Downloaded 6 packages in [TIME]
|
||
Installed 6 packages in [TIME]
|
||
+ black==23.11.0
|
||
+ click==8.1.7
|
||
+ mypy-extensions==1.0.0
|
||
+ packaging==23.2
|
||
+ pathspec==0.11.2
|
||
+ platformdirs==4.0.0
|
||
"###);
|
||
});
|
||
|
||
// Install the editable version of Black. This should remove the registry-based version.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("-e")
|
||
.arg("../../scripts/editable-installs/black_editable")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Built 1 editable in [TIME]
|
||
Resolved 1 package in [TIME]
|
||
Installed 1 package in [TIME]
|
||
- black==23.11.0
|
||
+ black==0.1.0+editable (from file://[WORKSPACE_DIR]/scripts/editable-installs/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.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("black")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Audited 1 package in [TIME]
|
||
"###);
|
||
});
|
||
|
||
// Re-install Black at a specific version. This should replace the editable version.
|
||
insta::with_settings!({
|
||
filters => filters.clone()
|
||
}, {
|
||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||
.arg("pip-install")
|
||
.arg("black==23.10.0")
|
||
.arg("--strict")
|
||
.arg("--cache-dir")
|
||
.arg(cache_dir.path())
|
||
.arg("--exclude-newer")
|
||
.arg(EXCLUDE_NEWER)
|
||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||
.env("CARGO_TARGET_DIR", "../../../target/target_install_editable"), @r###"
|
||
success: true
|
||
exit_code: 0
|
||
----- stdout -----
|
||
|
||
----- stderr -----
|
||
Resolved 6 packages in [TIME]
|
||
Downloaded 1 package in [TIME]
|
||
Installed 1 package in [TIME]
|
||
- black==0.1.0+editable (from file://[WORKSPACE_DIR]/scripts/editable-installs/black_editable/)
|
||
+ black==23.10.0
|
||
"###);
|
||
});
|
||
|
||
Ok(())
|
||
}
|