uv_types/
builds.rs

1use std::path::Path;
2use std::sync::Arc;
3
4use dashmap::DashMap;
5
6use uv_configuration::{BuildKind, SourceStrategy};
7use uv_normalize::PackageName;
8use uv_python::PythonEnvironment;
9
10/// Whether to enforce build isolation when building source distributions.
11#[derive(Debug, Default, Copy, Clone)]
12pub enum BuildIsolation<'a> {
13    #[default]
14    Isolated,
15    Shared(&'a PythonEnvironment),
16    SharedPackage(&'a PythonEnvironment, &'a [PackageName]),
17}
18
19impl BuildIsolation<'_> {
20    /// Returns `true` if build isolation is enforced for the given package name.
21    pub fn is_isolated(&self, package: Option<&PackageName>) -> bool {
22        match self {
23            Self::Isolated => true,
24            Self::Shared(_) => false,
25            Self::SharedPackage(_, packages) => {
26                package.is_none_or(|package| !packages.iter().any(|p| p == package))
27            }
28        }
29    }
30
31    /// Returns the shared environment for a given package, if build isolation is not enforced.
32    pub fn shared_environment(&self, package: Option<&PackageName>) -> Option<&PythonEnvironment> {
33        match self {
34            Self::Isolated => None,
35            Self::Shared(env) => Some(env),
36            Self::SharedPackage(env, packages) => {
37                if package.is_some_and(|package| packages.iter().any(|p| p == package)) {
38                    Some(env)
39                } else {
40                    None
41                }
42            }
43        }
44    }
45}
46
47/// A key for the build cache, which includes the interpreter, source root, subdirectory, source
48/// strategy, and build kind.
49#[derive(Debug, Clone, PartialEq, Eq, Hash)]
50pub struct BuildKey {
51    pub base_python: Box<Path>,
52    pub source_root: Box<Path>,
53    pub subdirectory: Option<Box<Path>>,
54    pub source_strategy: SourceStrategy,
55    pub build_kind: BuildKind,
56}
57
58/// An arena of in-process builds.
59#[derive(Debug)]
60pub struct BuildArena<T>(Arc<DashMap<BuildKey, T>>);
61
62impl<T> Default for BuildArena<T> {
63    fn default() -> Self {
64        Self(Arc::new(DashMap::new()))
65    }
66}
67
68impl<T> Clone for BuildArena<T> {
69    fn clone(&self) -> Self {
70        Self(self.0.clone())
71    }
72}
73
74impl<T> BuildArena<T> {
75    /// Insert a build entry into the arena.
76    pub fn insert(&self, key: BuildKey, value: T) {
77        self.0.insert(key, value);
78    }
79
80    /// Remove a build entry from the arena.
81    pub fn remove(&self, key: &BuildKey) -> Option<T> {
82        self.0.remove(key).map(|entry| entry.1)
83    }
84}