Refactor development dependency configuration (#8309)

Part of #8090
Unblocks https://github.com/astral-sh/uv/pull/8274

Refactors `DevMode` and `DevSpecification` into a shared type
`DevGroupsSpecification` that allows us to track if `--dev` was
implicitly or explicitly provided.
This commit is contained in:
Zanie Blue 2024-10-18 11:57:58 -05:00
parent fc2e79c6ce
commit d2e1f180ef
11 changed files with 166 additions and 110 deletions

View file

@ -15,7 +15,7 @@ use toml_edit::{value, Array, ArrayOfTables, InlineTable, Item, Table, Value};
use url::Url;
use uv_cache_key::RepositoryUrl;
use uv_configuration::{BuildOptions, DevSpecification, ExtrasSpecification, InstallOptions};
use uv_configuration::{BuildOptions, DevGroupsSpecification, ExtrasSpecification, InstallOptions};
use uv_distribution::DistributionDatabase;
use uv_distribution_filename::{DistExtension, ExtensionError, SourceDistExtension, WheelFilename};
use uv_distribution_types::{
@ -580,7 +580,7 @@ impl Lock {
marker_env: &ResolverMarkerEnvironment,
tags: &Tags,
extras: &ExtrasSpecification,
dev: &DevSpecification,
dev: &DevGroupsSpecification,
build_options: &BuildOptions,
install_options: &InstallOptions,
) -> Result<Resolution, LockError> {

View file

@ -10,7 +10,7 @@ use petgraph::{Directed, Graph};
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use url::Url;
use uv_configuration::{DevSpecification, EditableMode, ExtrasSpecification, InstallOptions};
use uv_configuration::{DevGroupsSpecification, EditableMode, ExtrasSpecification, InstallOptions};
use uv_distribution_filename::{DistExtension, SourceDistExtension};
use uv_fs::Simplified;
use uv_git::GitReference;
@ -43,7 +43,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
lock: &'lock Lock,
root_name: &PackageName,
extras: &ExtrasSpecification,
dev: &DevSpecification,
dev: &DevGroupsSpecification,
editable: EditableMode,
hashes: bool,
install_options: &'lock InstallOptions,

View file

@ -7,7 +7,7 @@ use petgraph::visit::Dfs;
use petgraph::Direction;
use rustc_hash::{FxHashMap, FxHashSet};
use uv_configuration::DevMode;
use uv_configuration::DevGroupsSpecification;
use uv_normalize::{ExtraName, GroupName, PackageName};
use uv_pypi_types::ResolverMarkerEnvironment;
@ -34,7 +34,7 @@ impl<'env> TreeDisplay<'env> {
depth: usize,
prune: &[PackageName],
packages: &[PackageName],
dev: DevMode,
dev: &DevGroupsSpecification,
no_dedupe: bool,
invert: bool,
) -> Self {
@ -134,8 +134,6 @@ impl<'env> TreeDisplay<'env> {
}
}
let mut modified = false;
// Step 1: Filter out packages that aren't reachable on this platform.
if let Some(environment_markers) = markers {
let mut reachable = FxHashSet::default();
@ -167,12 +165,11 @@ impl<'env> TreeDisplay<'env> {
// Remove the unreachable nodes from the graph.
graph.retain_nodes(|_, index| reachable.contains(&index));
modified = true;
}
// Step 2: Filter the graph to those that are reachable in production or development, if
// `--no-dev` or `--only-dev` were specified, respectively.
if dev != DevMode::Include {
{
let mut reachable = FxHashSet::default();
// Perform a DFS from the root nodes to find the reachable nodes, following only the
@ -189,27 +186,24 @@ impl<'env> TreeDisplay<'env> {
while let Some(node) = stack.pop_front() {
reachable.insert(node);
for edge in graph.edges_directed(node, Direction::Outgoing) {
if matches!(edge.weight(), Edge::Prod(_) | Edge::Optional(_, _)) {
let include = match edge.weight() {
Edge::Prod(_) => dev.prod(),
Edge::Optional(_, _) => dev.prod(),
Edge::Dev(group, _) => dev.iter().contains(*group),
};
if include {
stack.push_back(edge.target());
}
}
}
// Remove the unreachable nodes from the graph.
graph.retain_nodes(|_, index| {
if reachable.contains(&index) {
dev != DevMode::Only
} else {
dev != DevMode::Exclude
}
});
modified = true;
graph.retain_nodes(|_, index| reachable.contains(&index));
}
// Step 3: Reverse the graph.
if invert {
graph.reverse();
modified = true;
}
// Step 4: Filter the graph to those nodes reachable from the target packages.
@ -230,11 +224,10 @@ impl<'env> TreeDisplay<'env> {
// Remove the unreachable nodes from the graph.
graph.retain_nodes(|_, index| reachable.contains(&index));
modified = true;
}
// If the graph was modified, re-create the inverse map.
if modified {
// Re-create the inverse map.
{
inverse.clear();
for node in graph.node_indices() {
inverse.insert(graph[node], node);