mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-03 18:38:21 +00:00

This PR adds caching support for built wheels in the installer. Specifically, the `RegistryWheelIndex` now indexes both downloaded and built wheels (from registries), and we have a new `BuiltWheelIndex` that takes a subdirectory and returns the "best-matching" compatible wheel. Closes #570.
1342 lines
44 KiB
Rust
1342 lines
44 KiB
Rust
#![cfg(all(feature = "python", feature = "pypi"))]
|
|
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
|
|
use anyhow::{Context, Result};
|
|
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;
|
|
|
|
fn check_command(venv: &Path, command: &str, temp_dir: &Path) {
|
|
Command::new(venv.join("bin").join("python"))
|
|
.arg("-c")
|
|
.arg(command)
|
|
.current_dir(temp_dir)
|
|
.assert()
|
|
.success();
|
|
}
|
|
|
|
#[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-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.current_dir(&temp_dir));
|
|
|
|
requirements_txt.assert(predicates::path::missing());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[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");
|
|
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
|
|
venv.assert(predicates::path::missing());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment using the default link semantics. (On macOS,
|
|
/// this using `clone` semantics.)
|
|
#[test]
|
|
fn install() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment using copy semantics.
|
|
#[test]
|
|
fn install_copy() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--link-mode")
|
|
.arg("copy")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment using hardlink semantics.
|
|
#[test]
|
|
fn install_hardlink() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--link-mode")
|
|
.arg("hardlink")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install multiple packages into a virtual environment.
|
|
#[test]
|
|
fn install_many() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3\ntomli==2.0.1")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe; import tomli", &cache_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Attempt to install an already-installed package into a virtual environment.
|
|
#[test]
|
|
fn noop() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment, then install the same package into a different
|
|
/// virtual environment.
|
|
#[test]
|
|
fn link() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv1 = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv1.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let venv2 = temp_dir.child(".venv2");
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("venv")
|
|
.arg(venv2.as_os_str())
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.arg("--python")
|
|
.arg("python3.12")
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
venv2.assert(predicates::path::is_dir());
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv2.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv2, "import markupsafe", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment, then sync the virtual environment with a
|
|
/// different requirements file.
|
|
#[test]
|
|
fn add_remove() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("tomli==2.0.1")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import tomli", &temp_dir);
|
|
|
|
Command::new(venv.join("bin").join("python"))
|
|
.arg("-c")
|
|
.arg("import markupsafe")
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.failure();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment, then install a second package into the same
|
|
/// virtual environment.
|
|
#[test]
|
|
fn install_sequential() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("MarkupSafe==2.1.3\ntomli==2.0.1")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import markupsafe; import tomli", &cache_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment, then install a second package into the same
|
|
/// virtual environment.
|
|
#[test]
|
|
fn upgrade() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("tomli==2.0.0")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("tomli==2.0.1")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import tomli", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment from a URL.
|
|
#[test]
|
|
fn install_url() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment from a Git repository.
|
|
#[test]
|
|
#[cfg(feature = "git")]
|
|
fn install_git_commit() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ git+https://github.com/pallets/werkzeug.git@af160e0b6b7ddd81c22f1652c728ff5ac72d5c74")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package into a virtual environment from a Git repository.
|
|
#[test]
|
|
#[cfg(feature = "git")]
|
|
fn install_git_tag() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ git+https://github.com/pallets/werkzeug.git@2.0.0")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install two packages from the same Git repository.
|
|
#[test]
|
|
#[cfg(feature = "git")]
|
|
fn install_git_subdirectories() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("example-pkg-a @ git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_a\nexample-pkg-b @ git+https://github.com/pypa/sample-namespace-packages.git@df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#subdirectory=pkg_resources/pkg_b")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import example_pkg", &temp_dir);
|
|
check_command(&venv, "import example_pkg.a", &temp_dir);
|
|
check_command(&venv, "import example_pkg.b", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a source distribution into a virtual environment.
|
|
#[test]
|
|
fn install_sdist() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("Werkzeug==0.9.6")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a source distribution into a virtual environment.
|
|
#[test]
|
|
fn install_sdist_url() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("Werkzeug @ https://files.pythonhosted.org/packages/63/69/5702e5eb897d1a144001e21d676676bcb87b88c0862f947509ea95ea54fc/Werkzeug-0.9.6.tar.gz")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Attempt to re-install a package into a virtual environment from a URL. The second install
|
|
/// should be a no-op.
|
|
#[test]
|
|
fn install_url_then_install_url() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package via a URL, then via a registry version. The second install _should_ remove the
|
|
/// URL-based version, but doesn't right now.
|
|
#[test]
|
|
fn install_url_then_install_version() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug==2.0.0")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a package via a registry version, then via a direct URL version. The second install
|
|
/// should remove the registry-based version.
|
|
#[test]
|
|
fn install_version_then_install_url() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug==2.0.0")?;
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ https://files.pythonhosted.org/packages/ff/1d/960bb4017c68674a1cb099534840f18d3def3ce44aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl")?;
|
|
|
|
insta::with_settings!({
|
|
filters => vec![
|
|
(r"(\d|\.)+(ms|s)", "[TIME]"),
|
|
]
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Test that we select the last 3.8 compatible numpy version instead of trying to compile an
|
|
/// incompatible sdist <https://github.com/astral-sh/puffin/issues/388>
|
|
#[test]
|
|
fn install_numpy_py38() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv = temp_dir.child(".venv");
|
|
|
|
Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("venv")
|
|
.arg(venv.as_os_str())
|
|
.arg("--python")
|
|
// TODO(konstin): Mock the venv in the installer test so we don't need this anymore
|
|
.arg(which::which("python3.8").context("python3.8 must be installed")?)
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.current_dir(&temp_dir)
|
|
.assert()
|
|
.success();
|
|
venv.assert(predicates::path::is_dir());
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("numpy")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import numpy", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn warn_on_yanked_version() -> 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 requirements_in = temp_dir.child("requirements.txt");
|
|
requirements_in.touch()?;
|
|
// This version is yanked
|
|
requirements_in.write_str("ipython==8.13.0")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Resolve a local wheel.
|
|
#[test]
|
|
fn install_local_wheel() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
// Download a wheel.
|
|
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
let archive = temp_dir.child("tomli-3.0.1-py3-none-any.whl");
|
|
let mut archive_file = std::fs::File::create(&archive)?;
|
|
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.write_str(&format!("tomli @ file://{}", archive.path().display()))?;
|
|
|
|
// In addition to the standard filters, remove the temporary directory from the snapshot.
|
|
let mut filters = INSTA_FILTERS.to_vec();
|
|
filters.push((r"file://.*/", "file://[TEMP_DIR]/"));
|
|
|
|
insta::with_settings!({
|
|
filters => filters
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import tomli", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Install a local source distribution.
|
|
#[test]
|
|
fn install_local_source_distribution() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
// Download a source distribution.
|
|
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz")?;
|
|
let archive = temp_dir.child("wheel-0.42.0.tar.gz");
|
|
let mut archive_file = std::fs::File::create(&archive)?;
|
|
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.write_str(&format!("wheel @ file://{}", archive.path().display()))?;
|
|
|
|
// In addition to the standard filters, remove the temporary directory from the snapshot.
|
|
let mut filters = INSTA_FILTERS.to_vec();
|
|
filters.push((r"file://.*/", "file://[TEMP_DIR]/"));
|
|
|
|
insta::with_settings!({
|
|
filters => filters
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import wheel", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// The `ujson` package includes a `[build-system]`, but no `build-backend`. It lists some explicit
|
|
/// build requirements, but _also_ depends on `wheel` and `setuptools`:
|
|
/// ```toml
|
|
/// [build-system]
|
|
/// requires = ["setuptools>=42", "setuptools_scm[toml]>=3.4"]
|
|
/// ```
|
|
///
|
|
/// Like `pip` and `build`, we should use PEP 517 here and respect the `requires`, but use the
|
|
/// default build backend.
|
|
#[test]
|
|
fn install_ujson() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("ujson @ https://files.pythonhosted.org/packages/43/1a/b0a027144aa5c8f4ea654f4afdd634578b450807bb70b9f8bad00d6f6d3c/ujson-5.7.0.tar.gz")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import ujson", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// The `DTLSSocket` package includes a `[build-system]`, but no `build-backend`. It lists some
|
|
/// explicit build requirements that are necessary to build the distribution:
|
|
/// ```toml
|
|
/// [build-system]
|
|
/// requires = ["Cython<3", "setuptools", "wheel"]
|
|
/// ```
|
|
///
|
|
/// Like `pip` and `build`, we should use PEP 517 here and respect the `requires`, but use the
|
|
/// default build backend.
|
|
#[test]
|
|
fn install_dtls_socket() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("DTLSSocket @ https://files.pythonhosted.org/packages/58/42/0a0442118096eb9fbc9dc70b45aee2957f7546b80545e2a05bd839380519/DTLSSocket-0.1.16.tar.gz")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir));
|
|
});
|
|
|
|
check_command(&venv, "import DTLSSocket", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, direct URL source distribution installs.
|
|
#[test]
|
|
fn install_url_source_dist_cached() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("tqdm @ https://files.pythonhosted.org/packages/62/06/d5604a70d160f6a6ca5fd2ba25597c24abd5c5ca5f437263d177ac242308/tqdm-4.66.1.tar.gz")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ tqdm @ https://files.pythonhosted.org/packages/62/06/d5604a70d160f6a6ca5fd2ba25597c24abd5c5ca5f437263d177ac242308/tqdm-4.66.1.tar.gz
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tqdm", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&parent, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ tqdm @ https://files.pythonhosted.org/packages/62/06/d5604a70d160f6a6ca5fd2ba25597c24abd5c5ca5f437263d177ac242308/tqdm-4.66.1.tar.gz
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tqdm", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, Git source distribution installs.
|
|
#[test]
|
|
#[cfg(feature = "git")]
|
|
fn install_git_source_dist_cached() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("werkzeug @ git+https://github.com/pallets/werkzeug.git@af160e0b6b7ddd81c22f1652c728ff5ac72d5c74")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ werkzeug @ git+https://github.com/pallets/werkzeug.git@af160e0b6b7ddd81c22f1652c728ff5ac72d5c74
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&parent, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ werkzeug @ git+https://github.com/pallets/werkzeug.git@af160e0b6b7ddd81c22f1652c728ff5ac72d5c74
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import werkzeug", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, registry source distribution installs.
|
|
#[test]
|
|
fn install_registry_source_dist_cached() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("future==0.18.3")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ future==0.18.3
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import future", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&parent, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ future==0.18.3
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import future", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, local source distribution installs.
|
|
#[test]
|
|
fn install_path_source_dist_cached() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
// Download a source distribution.
|
|
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/b0/b4/bc2baae3970c282fae6c2cb8e0f179923dceb7eaffb0e76170628f9af97b/wheel-0.42.0.tar.gz")?;
|
|
let archive = temp_dir.child("wheel-0.42.0.tar.gz");
|
|
let mut archive_file = std::fs::File::create(&archive)?;
|
|
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.write_str(&format!("wheel @ file://{}", archive.path().display()))?;
|
|
|
|
// In addition to the standard filters, remove the temporary directory from the snapshot.
|
|
let mut filters = INSTA_FILTERS.to_vec();
|
|
filters.push((r"file://.*/", "file://[TEMP_DIR]/"));
|
|
|
|
insta::with_settings!({
|
|
filters => filters.clone()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ wheel @ file://[TEMP_DIR]/wheel-0.42.0.tar.gz
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import wheel", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&parent, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => filters.clone()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ wheel @ file://[TEMP_DIR]/wheel-0.42.0.tar.gz
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import wheel", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, local source distribution installs.
|
|
#[test]
|
|
fn install_path_built_dist_cached() -> Result<()> {
|
|
let temp_dir = assert_fs::TempDir::new()?;
|
|
let cache_dir = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
// Download a wheel.
|
|
let response = reqwest::blocking::get("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl")?;
|
|
let archive = temp_dir.child("tomli-3.0.1-py3-none-any.whl");
|
|
let mut archive_file = std::fs::File::create(&archive)?;
|
|
std::io::copy(&mut response.bytes()?.as_ref(), &mut archive_file)?;
|
|
|
|
let requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.write_str(&format!("tomli @ file://{}", archive.path().display()))?;
|
|
|
|
// In addition to the standard filters, remove the temporary directory from the snapshot.
|
|
let mut filters = INSTA_FILTERS.to_vec();
|
|
filters.push((r"file://.*/", "file://[TEMP_DIR]/"));
|
|
|
|
insta::with_settings!({
|
|
filters => filters.clone()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ tomli @ file://[TEMP_DIR]/tomli-3.0.1-py3-none-any.whl
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tomli", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => filters.clone()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ tomli @ file://[TEMP_DIR]/tomli-3.0.1-py3-none-any.whl
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tomli", &parent);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Check that we show the right messages on cached, direct URL built distribution installs.
|
|
#[test]
|
|
fn install_url_built_dist_cached() -> 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 requirements_txt = temp_dir.child("requirements.txt");
|
|
requirements_txt.touch()?;
|
|
requirements_txt.write_str("tqdm @ https://files.pythonhosted.org/packages/00/e5/f12a80907d0884e6dff9c16d0c0114d81b8cd07dc3ae54c5e962cc83037e/tqdm-4.66.1-py3-none-any.whl")?;
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Resolved 1 package in [TIME]
|
|
Downloaded 1 package in [TIME]
|
|
Unzipped 1 package in [TIME]
|
|
Installed 1 package in [TIME]
|
|
+ tqdm @ https://files.pythonhosted.org/packages/00/e5/f12a80907d0884e6dff9c16d0c0114d81b8cd07dc3ae54c5e962cc83037e/tqdm-4.66.1-py3-none-any.whl
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tqdm", &temp_dir);
|
|
|
|
// Re-run the installation in a new virtual environment.
|
|
let parent = assert_fs::TempDir::new()?;
|
|
let venv = create_venv_py312(&parent, &cache_dir);
|
|
|
|
insta::with_settings!({
|
|
filters => INSTA_FILTERS.to_vec()
|
|
}, {
|
|
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
|
.arg("pip-sync")
|
|
.arg("requirements.txt")
|
|
.arg("--cache-dir")
|
|
.arg(cache_dir.path())
|
|
.env("VIRTUAL_ENV", venv.as_os_str())
|
|
.current_dir(&temp_dir), @r###"
|
|
success: true
|
|
exit_code: 0
|
|
----- stdout -----
|
|
|
|
----- stderr -----
|
|
Installed 1 package in [TIME]
|
|
+ tqdm @ https://files.pythonhosted.org/packages/00/e5/f12a80907d0884e6dff9c16d0c0114d81b8cd07dc3ae54c5e962cc83037e/tqdm-4.66.1-py3-none-any.whl
|
|
"###);
|
|
});
|
|
|
|
check_command(&venv, "import tqdm", &temp_dir);
|
|
|
|
Ok(())
|
|
}
|