use anyhow::Result;
use uv_configuration::{
BuildOptions, DependencyGroupsWithDefaults, ExtrasSpecification, InstallOptions,
};
use uv_distribution_types::Resolution;
use uv_normalize::{DefaultExtras, GroupName, PackageName};
use uv_python::Interpreter;
use uv_resolver::{Lock, Package};
use uv_workspace::VirtualProject;
use crate::commands::pip::{resolution_markers, resolution_tags};
pub(crate) struct LockedTool<'lock> {
package: &'lock Package,
requires_separate_environment: bool,
}
impl<'lock> LockedTool<'lock> {
pub(crate) fn package(&self) -> &'lock Package {
self.package
}
pub(crate) fn requires_separate_environment(&self) -> bool {
self.requires_separate_environment
}
}
pub(crate) fn find_locked_tool<'lock>(
project: &VirtualProject,
lock: &'lock Lock,
interpreter: &Interpreter,
package_name: &PackageName,
dependency_group: &GroupName,
groups: &DependencyGroupsWithDefaults,
) -> Result<Option<LockedTool<'lock>>> {
let marker_environment = interpreter.resolver_marker_environment();
let selection = lock
.dependency_selection(
project.project_name(),
package_name,
marker_environment.markers(),
)
.map_err(anyhow::Error::msg)?;
let (package, installed) = if let Some(package) = selection.group(dependency_group) {
(package, groups.contains(dependency_group))
} else if let Some(package) = selection.production() {
(package, groups.prod())
} else {
return Ok(None);
};
Ok(Some(LockedTool {
package,
requires_separate_environment: !installed,
}))
}
pub(crate) fn resolution_from_lock(
project: &VirtualProject,
lock: &Lock,
package: &Package,
interpreter: &Interpreter,
build_options: &BuildOptions,
) -> Result<Resolution> {
let marker_environment = resolution_markers(None, None, interpreter);
let tags = resolution_tags(None, None, interpreter)?;
let extras = ExtrasSpecification::default().with_defaults(DefaultExtras::default());
let groups = DependencyGroupsWithDefaults::none();
Ok(lock.to_resolution(
project.workspace().install_path(),
[package],
project.project_name(),
&marker_environment,
&tags,
&extras,
&groups,
build_options,
&InstallOptions::default(),
)?)
}