uv_configuration/
install_options.rs1use std::collections::BTreeSet;
2
3use tracing::debug;
4
5use uv_normalize::PackageName;
6
7#[derive(Debug, Clone, Copy)]
9pub struct InstallTarget<'a> {
10 pub name: &'a PackageName,
12 pub is_local: bool,
14}
15
16#[derive(Debug, Clone, Default)]
17pub struct InstallOptions {
18 pub no_install_project: bool,
20 pub only_install_project: bool,
22 pub no_install_workspace: bool,
24 pub only_install_workspace: bool,
26 pub no_install_local: bool,
28 pub only_install_local: bool,
30 pub no_install_package: Vec<PackageName>,
32 pub only_install_package: Vec<PackageName>,
34}
35
36impl InstallOptions {
37 #[allow(clippy::fn_params_excessive_bools)]
38 pub fn new(
39 no_install_project: bool,
40 only_install_project: bool,
41 no_install_workspace: bool,
42 only_install_workspace: bool,
43 no_install_local: bool,
44 only_install_local: bool,
45 no_install_package: Vec<PackageName>,
46 only_install_package: Vec<PackageName>,
47 ) -> Self {
48 Self {
49 no_install_project,
50 only_install_project,
51 no_install_workspace,
52 only_install_workspace,
53 no_install_local,
54 only_install_local,
55 no_install_package,
56 only_install_package,
57 }
58 }
59
60 pub fn include_package(
62 &self,
63 target: InstallTarget<'_>,
64 project_name: Option<&PackageName>,
65 members: &BTreeSet<PackageName>,
66 ) -> bool {
67 let package_name = target.name;
68
69 if !self.only_install_package.is_empty() {
71 if self.only_install_package.contains(package_name) {
72 return true;
73 }
74 debug!("Omitting `{package_name}` from resolution due to `--only-install-package`");
75 return false;
76 }
77
78 if self.only_install_local {
80 if target.is_local {
81 return true;
82 }
83 debug!("Omitting `{package_name}` from resolution due to `--only-install-local`");
84 return false;
85 }
86
87 if self.only_install_workspace {
89 if let Some(project_name) = project_name {
91 if package_name == project_name {
92 return true;
93 }
94 }
95
96 if members.contains(package_name) {
98 return true;
99 }
100
101 debug!("Omitting `{package_name}` from resolution due to `--only-install-workspace`");
103 return false;
104 }
105
106 if self.only_install_project {
108 if let Some(project_name) = project_name {
109 if package_name == project_name {
110 return true;
111 }
112 }
113 debug!("Omitting `{package_name}` from resolution due to `--only-install-project`");
114 return false;
115 }
116
117 if self.no_install_project {
119 if let Some(project_name) = project_name {
120 if package_name == project_name {
121 debug!(
122 "Omitting `{package_name}` from resolution due to `--no-install-project`"
123 );
124 return false;
125 }
126 }
127 }
128
129 if self.no_install_workspace {
131 if !self.no_install_project {
135 if let Some(project_name) = project_name {
136 if package_name == project_name {
137 debug!(
138 "Omitting `{package_name}` from resolution due to `--no-install-workspace`"
139 );
140 return false;
141 }
142 }
143 }
144
145 if members.contains(package_name) {
146 debug!("Omitting `{package_name}` from resolution due to `--no-install-workspace`");
147 return false;
148 }
149 }
150
151 if self.no_install_local {
153 if target.is_local {
154 debug!("Omitting `{package_name}` from resolution due to `--no-install-local`");
155 return false;
156 }
157 }
158
159 if self.no_install_package.contains(package_name) {
161 debug!("Omitting `{package_name}` from resolution due to `--no-install-package`");
162 return false;
163 }
164
165 true
166 }
167}