mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Report project name instead of root
when using pyproject.toml
files (#295)
Part of https://github.com/astral-sh/puffin/issues/214 Adds a `project: Option<PackageName>` to the `Manifest`, `Resolver`, and `RequirementsSpecification`. To populate an optional `name` for `PubGubPackage::Root`. I'll work on removing the version number next. Should we consider using the parent directory name when a `pyproject.toml` file is not present?
This commit is contained in:
parent
e008c43f29
commit
e1382cc747
12 changed files with 123 additions and 9 deletions
|
@ -44,6 +44,7 @@ pub(crate) async fn pip_compile(
|
|||
|
||||
// Read all requirements from the provided sources.
|
||||
let RequirementsSpecification {
|
||||
project,
|
||||
requirements,
|
||||
constraints,
|
||||
extras: used_extras,
|
||||
|
@ -84,6 +85,7 @@ pub(crate) async fn pip_compile(
|
|||
preferences,
|
||||
resolution_mode,
|
||||
prerelease_mode,
|
||||
project,
|
||||
);
|
||||
|
||||
// Detect the current Python interpreter.
|
||||
|
|
|
@ -33,6 +33,7 @@ pub(crate) async fn pip_sync(
|
|||
) -> Result<ExitStatus> {
|
||||
// Read all requirements from the provided sources.
|
||||
let RequirementsSpecification {
|
||||
project: _,
|
||||
requirements,
|
||||
constraints: _,
|
||||
extras: _,
|
||||
|
|
|
@ -22,6 +22,7 @@ pub(crate) async fn pip_uninstall(
|
|||
|
||||
// Read all requirements from the provided sources.
|
||||
let RequirementsSpecification {
|
||||
project: _,
|
||||
requirements,
|
||||
constraints: _,
|
||||
extras: _,
|
||||
|
|
|
@ -8,7 +8,7 @@ use anyhow::{Context, Result};
|
|||
use fs_err as fs;
|
||||
|
||||
use pep508_rs::Requirement;
|
||||
use puffin_normalize::ExtraName;
|
||||
use puffin_normalize::{ExtraName, PackageName};
|
||||
use puffin_package::requirements_txt::RequirementsTxt;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -58,6 +58,8 @@ impl ExtrasSpecification<'_> {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct RequirementsSpecification {
|
||||
/// The name of the project specifying requirements.
|
||||
pub(crate) project: Option<PackageName>,
|
||||
/// The requirements for the project.
|
||||
pub(crate) requirements: Vec<Requirement>,
|
||||
/// The constraints for the project.
|
||||
|
@ -77,6 +79,7 @@ impl RequirementsSpecification {
|
|||
let requirement = Requirement::from_str(name)
|
||||
.with_context(|| format!("Failed to parse `{name}`"))?;
|
||||
Self {
|
||||
project: None,
|
||||
requirements: vec![requirement],
|
||||
constraints: vec![],
|
||||
extras: HashSet::new(),
|
||||
|
@ -85,6 +88,7 @@ impl RequirementsSpecification {
|
|||
RequirementsSource::RequirementsTxt(path) => {
|
||||
let requirements_txt = RequirementsTxt::parse(path, std::env::current_dir()?)?;
|
||||
Self {
|
||||
project: None,
|
||||
requirements: requirements_txt
|
||||
.requirements
|
||||
.into_iter()
|
||||
|
@ -100,6 +104,7 @@ impl RequirementsSpecification {
|
|||
.with_context(|| format!("Failed to read `{}`", path.display()))?;
|
||||
let mut used_extras = HashSet::new();
|
||||
let mut requirements = Vec::new();
|
||||
let mut project_name = None;
|
||||
if let Some(project) = pyproject_toml.project {
|
||||
requirements.extend(project.dependencies.unwrap_or_default());
|
||||
// Include any optional dependencies specified in `extras`
|
||||
|
@ -114,9 +119,12 @@ impl RequirementsSpecification {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Parse the project name
|
||||
project_name = Some(PackageName::new(project.name));
|
||||
}
|
||||
|
||||
Self {
|
||||
project: project_name,
|
||||
requirements,
|
||||
constraints: vec![],
|
||||
extras: used_extras,
|
||||
|
@ -141,6 +149,11 @@ impl RequirementsSpecification {
|
|||
spec.requirements.extend(source.requirements);
|
||||
spec.constraints.extend(source.constraints);
|
||||
spec.extras.extend(source.extras);
|
||||
|
||||
// Use the first project name discovered
|
||||
if spec.project.is_none() {
|
||||
spec.project = source.project;
|
||||
}
|
||||
}
|
||||
|
||||
// Read all constraints, treating both requirements _and_ constraints as constraints.
|
||||
|
|
|
@ -1047,3 +1047,51 @@ optional-dependencies.bar = [
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compile requirements that cannot be solved due to conflict in a `pyproject.toml` fil;e.
|
||||
#[test]
|
||||
fn compile_unsolvable_requirements() -> 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("--cache-dir")
|
||||
.arg(cache_dir.path())
|
||||
.current_dir(&temp_dir)
|
||||
.assert()
|
||||
.success();
|
||||
venv.assert(predicates::path::is_dir());
|
||||
|
||||
let pyproject_toml = temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.touch()?;
|
||||
pyproject_toml.write_str(
|
||||
r#"[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
|
||||
[project]
|
||||
name = "my-project"
|
||||
dependencies = ["django==5.0b1", "django==5.0a1"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
insta::with_settings!({
|
||||
filters => vec![
|
||||
(r"\d(ms|s)", "[TIME]"),
|
||||
(r"# .* pip-compile", "# [BIN_PATH] pip-compile"),
|
||||
(r"--cache-dir .*", "--cache-dir [CACHE_DIR]"),
|
||||
]
|
||||
}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.arg("pip-compile")
|
||||
.arg("pyproject.toml")
|
||||
.arg("--cache-dir")
|
||||
.arg(cache_dir.path())
|
||||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||||
.current_dir(&temp_dir));
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
source: crates/puffin-cli/tests/pip_compile.rs
|
||||
info:
|
||||
program: puffin
|
||||
args:
|
||||
- pip-compile
|
||||
- pyproject.toml
|
||||
- "--cache-dir"
|
||||
- /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/.tmpfuaPhl
|
||||
env:
|
||||
VIRTUAL_ENV: /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/.tmpLxUB5I/.venv
|
||||
---
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ my-project 0a0.dev0 depends on django ∅
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue