mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-20 03:49:54 +00:00
Read all extras directly from lockfile (#4033)
## Summary We now pass `ExtrasSpecification` to the lock routine.
This commit is contained in:
parent
1b3200b2af
commit
8de3e38b94
3 changed files with 29 additions and 48 deletions
|
|
@ -10,7 +10,7 @@ use tracing::{debug, trace};
|
||||||
use pep508_rs::VerbatimUrl;
|
use pep508_rs::VerbatimUrl;
|
||||||
use pypi_types::{Requirement, RequirementSource};
|
use pypi_types::{Requirement, RequirementSource};
|
||||||
use uv_fs::{absolutize_path, Simplified};
|
use uv_fs::{absolutize_path, Simplified};
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::PackageName;
|
||||||
use uv_warnings::warn_user;
|
use uv_warnings::warn_user;
|
||||||
|
|
||||||
use crate::pyproject::{PyProjectToml, Source, ToolUvWorkspace};
|
use crate::pyproject::{PyProjectToml, Source, ToolUvWorkspace};
|
||||||
|
|
@ -134,21 +134,9 @@ impl Workspace {
|
||||||
/// Returns `None` if the package is not part of the workspace.
|
/// Returns `None` if the package is not part of the workspace.
|
||||||
pub fn with_current_project(self, package_name: PackageName) -> Option<ProjectWorkspace> {
|
pub fn with_current_project(self, package_name: PackageName) -> Option<ProjectWorkspace> {
|
||||||
let member = self.packages.get(&package_name)?;
|
let member = self.packages.get(&package_name)?;
|
||||||
let extras = member
|
|
||||||
.pyproject_toml
|
|
||||||
.project
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|project| project.optional_dependencies.as_ref())
|
|
||||||
.map(|optional_dependencies| {
|
|
||||||
let mut extras = optional_dependencies.keys().cloned().collect::<Vec<_>>();
|
|
||||||
extras.sort_unstable();
|
|
||||||
extras
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
Some(ProjectWorkspace {
|
Some(ProjectWorkspace {
|
||||||
project_root: member.root().clone(),
|
project_root: member.root().clone(),
|
||||||
project_name: package_name,
|
project_name: package_name,
|
||||||
extras,
|
|
||||||
workspace: self,
|
workspace: self,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -393,8 +381,6 @@ pub struct ProjectWorkspace {
|
||||||
project_root: PathBuf,
|
project_root: PathBuf,
|
||||||
/// The name of the package.
|
/// The name of the package.
|
||||||
project_name: PackageName,
|
project_name: PackageName,
|
||||||
/// The extras available in the project.
|
|
||||||
extras: Vec<ExtraName>,
|
|
||||||
/// The workspace the project is part of.
|
/// The workspace the project is part of.
|
||||||
workspace: Workspace,
|
workspace: Workspace,
|
||||||
}
|
}
|
||||||
|
|
@ -496,11 +482,6 @@ impl ProjectWorkspace {
|
||||||
&self.project_name
|
&self.project_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the extras available in the project.
|
|
||||||
pub fn project_extras(&self) -> &[ExtraName] {
|
|
||||||
&self.extras
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the [`Workspace`] containing the current project.
|
/// Returns the [`Workspace`] containing the current project.
|
||||||
pub fn workspace(&self) -> &Workspace {
|
pub fn workspace(&self) -> &Workspace {
|
||||||
&self.workspace
|
&self.workspace
|
||||||
|
|
@ -516,7 +497,15 @@ impl ProjectWorkspace {
|
||||||
pub fn requirements(&self) -> Vec<Requirement> {
|
pub fn requirements(&self) -> Vec<Requirement> {
|
||||||
vec![Requirement {
|
vec![Requirement {
|
||||||
name: self.project_name.clone(),
|
name: self.project_name.clone(),
|
||||||
extras: self.extras.clone(),
|
extras: self.workspace().packages[&self.project_name]
|
||||||
|
.pyproject_toml
|
||||||
|
.project
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|project| project.optional_dependencies.as_ref())
|
||||||
|
.map(|optional_dependencies| {
|
||||||
|
optional_dependencies.keys().cloned().collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
marker: None,
|
marker: None,
|
||||||
source: RequirementSource::Path {
|
source: RequirementSource::Path {
|
||||||
path: self.project_root.clone(),
|
path: self.project_root.clone(),
|
||||||
|
|
@ -538,18 +527,6 @@ impl ProjectWorkspace {
|
||||||
.map_err(WorkspaceError::Normalize)?
|
.map_err(WorkspaceError::Normalize)?
|
||||||
.to_path_buf();
|
.to_path_buf();
|
||||||
|
|
||||||
// Extract the extras available in the project.
|
|
||||||
let extras = project
|
|
||||||
.project
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|project| project.optional_dependencies.as_ref())
|
|
||||||
.map(|optional_dependencies| {
|
|
||||||
let mut extras = optional_dependencies.keys().cloned().collect::<Vec<_>>();
|
|
||||||
extras.sort_unstable();
|
|
||||||
extras
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
// Check if the current project is also an explicit workspace root.
|
// Check if the current project is also an explicit workspace root.
|
||||||
let mut workspace = project
|
let mut workspace = project
|
||||||
.tool
|
.tool
|
||||||
|
|
@ -579,7 +556,6 @@ impl ProjectWorkspace {
|
||||||
return Ok(Self {
|
return Ok(Self {
|
||||||
project_root: project_path.clone(),
|
project_root: project_path.clone(),
|
||||||
project_name: project_name.clone(),
|
project_name: project_name.clone(),
|
||||||
extras,
|
|
||||||
workspace: Workspace {
|
workspace: Workspace {
|
||||||
root: project_path.clone(),
|
root: project_path.clone(),
|
||||||
packages: current_project_as_members,
|
packages: current_project_as_members,
|
||||||
|
|
@ -607,7 +583,6 @@ impl ProjectWorkspace {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
project_root: project_path,
|
project_root: project_path,
|
||||||
project_name,
|
project_name,
|
||||||
extras,
|
|
||||||
workspace,
|
workspace,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -838,7 +813,6 @@ mod tests {
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-in-example/examples/bird-feeder",
|
"project_root": "[ROOT]/albatross-in-example/examples/bird-feeder",
|
||||||
"project_name": "bird-feeder",
|
"project_name": "bird-feeder",
|
||||||
"extras": [],
|
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"root": "[ROOT]/albatross-in-example/examples/bird-feeder",
|
"root": "[ROOT]/albatross-in-example/examples/bird-feeder",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
@ -869,7 +843,6 @@ mod tests {
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-project-in-excluded/excluded/bird-feeder",
|
"project_root": "[ROOT]/albatross-project-in-excluded/excluded/bird-feeder",
|
||||||
"project_name": "bird-feeder",
|
"project_name": "bird-feeder",
|
||||||
"extras": [],
|
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"root": "[ROOT]/albatross-project-in-excluded/excluded/bird-feeder",
|
"root": "[ROOT]/albatross-project-in-excluded/excluded/bird-feeder",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
@ -899,7 +872,6 @@ mod tests {
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-root-workspace",
|
"project_root": "[ROOT]/albatross-root-workspace",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"extras": [],
|
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"root": "[ROOT]/albatross-root-workspace",
|
"root": "[ROOT]/albatross-root-workspace",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
@ -943,7 +915,6 @@ mod tests {
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
"project_root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"extras": [],
|
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"root": "[ROOT]/albatross-virtual-workspace",
|
"root": "[ROOT]/albatross-virtual-workspace",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
@ -981,7 +952,6 @@ mod tests {
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-just-project",
|
"project_root": "[ROOT]/albatross-just-project",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"extras": [],
|
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"root": "[ROOT]/albatross-just-project",
|
"root": "[ROOT]/albatross-just-project",
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ use pep440_rs::Version;
|
||||||
use pep508_rs::{MarkerEnvironment, MarkerTree, VerbatimUrl};
|
use pep508_rs::{MarkerEnvironment, MarkerTree, VerbatimUrl};
|
||||||
use platform_tags::{TagCompatibility, TagPriority, Tags};
|
use platform_tags::{TagCompatibility, TagPriority, Tags};
|
||||||
use pypi_types::{HashDigest, ParsedArchiveUrl, ParsedGitUrl};
|
use pypi_types::{HashDigest, ParsedArchiveUrl, ParsedGitUrl};
|
||||||
|
use uv_configuration::ExtrasSpecification;
|
||||||
use uv_git::{GitReference, GitSha, RepositoryReference, ResolvedRepositoryReference};
|
use uv_git::{GitReference, GitSha, RepositoryReference, ResolvedRepositoryReference};
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
|
|
||||||
|
|
@ -110,7 +111,7 @@ impl Lock {
|
||||||
marker_env: &MarkerEnvironment,
|
marker_env: &MarkerEnvironment,
|
||||||
tags: &Tags,
|
tags: &Tags,
|
||||||
root_name: &PackageName,
|
root_name: &PackageName,
|
||||||
extras: &[ExtraName],
|
extras: &ExtrasSpecification,
|
||||||
) -> Resolution {
|
) -> Resolution {
|
||||||
let mut queue: VecDeque<(&Distribution, Option<&ExtraName>)> = VecDeque::new();
|
let mut queue: VecDeque<(&Distribution, Option<&ExtraName>)> = VecDeque::new();
|
||||||
|
|
||||||
|
|
@ -119,8 +120,23 @@ impl Lock {
|
||||||
.find_by_name(root_name)
|
.find_by_name(root_name)
|
||||||
.expect("found too many distributions matching root")
|
.expect("found too many distributions matching root")
|
||||||
.expect("could not find root");
|
.expect("could not find root");
|
||||||
for extra in std::iter::once(None).chain(extras.iter().map(Some)) {
|
|
||||||
queue.push_back((root, extra));
|
// Add the base package.
|
||||||
|
queue.push_back((root, None));
|
||||||
|
|
||||||
|
// Add any extras.
|
||||||
|
match extras {
|
||||||
|
ExtrasSpecification::None => {}
|
||||||
|
ExtrasSpecification::All => {
|
||||||
|
for extra in root.optional_dependencies.keys() {
|
||||||
|
queue.push_back((root, Some(extra)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExtrasSpecification::Some(extras) => {
|
||||||
|
for extra in extras {
|
||||||
|
queue.push_back((root, Some(extra)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut map = BTreeMap::default();
|
let mut map = BTreeMap::default();
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,6 @@ pub(super) async fn do_sync(
|
||||||
let tags = venv.interpreter().tags()?;
|
let tags = venv.interpreter().tags()?;
|
||||||
|
|
||||||
// Read the lockfile.
|
// Read the lockfile.
|
||||||
let extras = match extras {
|
|
||||||
ExtrasSpecification::None => vec![],
|
|
||||||
ExtrasSpecification::All => project.project_extras().to_vec(),
|
|
||||||
ExtrasSpecification::Some(extras) => extras,
|
|
||||||
};
|
|
||||||
let resolution = lock.to_resolution(markers, tags, project.project_name(), &extras);
|
let resolution = lock.to_resolution(markers, tags, project.project_name(), &extras);
|
||||||
|
|
||||||
// Initialize the registry client.
|
// Initialize the registry client.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue