1#[cfg(feature = "schemars")]
2use std::borrow::Cow;
3use std::{
4 fmt::{self, Debug},
5 num::NonZeroUsize,
6 path::Path,
7 path::PathBuf,
8};
9
10use serde::de::{Error, SeqAccess, Visitor, value::SeqAccessDeserializer};
11use serde::{Deserialize, Deserializer, Serialize};
12
13use uv_cache_info::CacheKey;
14use uv_configuration::{
15 AddBoundsKind, AnnotationStyle, BuildIsolation, ExcludeDependency, ExcludeNewerPackage,
16 ForkStrategy, IndexStrategy, KeyringProviderType, PackageNameSpecifier, PrereleaseMode,
17 PrereleasePackage, ProxyUrl, Reinstall, RequiredVersion, ResolutionMode, TargetTriple,
18 TrustedHost, TrustedPublishing, Upgrade, serialize_exclude_newer_package_with_spans,
19};
20use uv_distribution_types::{
21 ConfigSettings, ExcludeNewerOverride, ExcludeNewerSpan, ExcludeNewerValue, ExtraBuildVariables,
22 Index, IndexLocations, IndexUrl, IndexUrlError, MinimumLibcVersion, Origin,
23 PackageConfigSettings, PipExtraIndex, PipFindLinks, PipIndex, StaticMetadata,
24};
25use uv_install_wheel::LinkMode;
26use uv_macros::{CombineOptions, OptionsMetadata};
27use uv_normalize::{ExtraName, PackageName, PipGroupName};
28use uv_pep508::Requirement;
29use uv_preview::{MaybePreviewFeature, Preview};
30use uv_pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
31use uv_python_types::{PythonDownloadMirrors, PythonDownloads, PythonPreference, PythonVersion};
32use uv_redacted::DisplaySafeUrl;
33use uv_torch::TorchMode;
34use uv_workspace::pyproject::{
35 BuildConstraintDependency, ExtraBuildDependencies, OverrideDependency,
36};
37
38use crate::{EnvironmentOptions, FilesystemOptions};
39
40#[allow(dead_code)]
42#[derive(Debug, Clone, Default, Deserialize)]
43pub(crate) struct PyProjectToml {
44 pub(crate) tool: Option<Tools>,
45}
46
47#[allow(dead_code)]
49#[derive(Debug, Clone, Default, Deserialize)]
50pub(crate) struct Tools {
51 pub(crate) uv: Option<Options>,
52}
53
54#[derive(Debug, Clone, Default, Deserialize)]
56pub(crate) struct PyProjectRequiredVersionToml {
57 pub(crate) tool: Option<RequiredVersionTools>,
58}
59
60#[derive(Debug, Clone, Default, Deserialize)]
62pub(crate) struct RequiredVersionTools {
63 pub(crate) uv: Option<RequiredVersionOptions>,
64}
65
66#[derive(Debug, Clone, Default, Deserialize)]
68#[serde(rename_all = "kebab-case")]
69pub(crate) struct RequiredVersionOptions {
70 pub(crate) required_version: Option<RequiredVersion>,
71}
72
73#[derive(Debug, Clone, Default, Deserialize)]
75#[serde(rename_all = "kebab-case")]
76pub(crate) struct UvRequiredVersionToml {
77 pub(crate) required_version: Option<RequiredVersion>,
78}
79
80#[allow(dead_code)]
82#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
83#[serde(try_from = "OptionsWire", rename_all = "kebab-case")]
84#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
85#[cfg_attr(feature = "schemars", schemars(!try_from))]
86pub struct Options {
87 #[serde(flatten)]
88 pub globals: GlobalOptions,
89
90 #[serde(flatten)]
91 pub top_level: ResolverInstallerSchema,
92
93 #[serde(flatten)]
94 pub install_mirrors: PythonInstallMirrors,
95
96 #[serde(flatten)]
97 pub publish: PublishOptions,
98
99 #[serde(flatten)]
100 pub add: AddOptions,
101
102 #[option_group]
103 pub audit: Option<AuditOptions>,
104
105 #[option_group]
106 pub pip: Option<PipOptions>,
107
108 #[option(
144 default = r#"[{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }]"#,
145 value_type = "list[dict]",
146 example = r#"
147 cache-keys = [{ file = "pyproject.toml" }, { file = "requirements.txt" }, { git = { commit = true } }]
148 "#
149 )]
150 pub cache_keys: Option<Vec<CacheKey>>,
151
152 #[cfg_attr(feature = "schemars", schemars(skip))]
156 pub override_dependencies: Option<Vec<OverrideDependency>>,
157
158 #[cfg_attr(feature = "schemars", schemars(skip))]
159 pub exclude_dependencies: Option<Vec<ExcludeDependency>>,
160
161 #[cfg_attr(feature = "schemars", schemars(skip))]
162 pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
163
164 #[cfg_attr(feature = "schemars", schemars(skip))]
165 pub build_constraint_dependencies: Option<Vec<BuildConstraintDependency>>,
166
167 #[cfg_attr(feature = "schemars", schemars(skip))]
168 pub environments: Option<SupportedEnvironments>,
169
170 #[cfg_attr(feature = "schemars", schemars(skip))]
171 pub required_environments: Option<SupportedEnvironments>,
172
173 #[cfg_attr(feature = "schemars", schemars(skip))]
174 pub minimum_libc_version: Option<MinimumLibcVersion>,
175
176 #[cfg_attr(feature = "schemars", schemars(skip))]
180 pub(crate) conflicts: Option<serde::de::IgnoredAny>,
181
182 #[cfg_attr(feature = "schemars", schemars(skip))]
183 pub(crate) workspace: Option<serde::de::IgnoredAny>,
184
185 #[cfg_attr(feature = "schemars", schemars(skip))]
186 pub(crate) sources: Option<serde::de::IgnoredAny>,
187
188 #[cfg_attr(feature = "schemars", schemars(skip))]
189 pub(crate) dev_dependencies: Option<serde::de::IgnoredAny>,
190
191 #[cfg_attr(feature = "schemars", schemars(skip))]
192 pub(crate) default_groups: Option<serde::de::IgnoredAny>,
193
194 #[cfg_attr(feature = "schemars", schemars(skip))]
195 pub(crate) dependency_groups: Option<serde::de::IgnoredAny>,
196
197 #[cfg_attr(feature = "schemars", schemars(skip))]
198 pub(crate) managed: Option<serde::de::IgnoredAny>,
199
200 #[cfg_attr(feature = "schemars", schemars(skip))]
201 pub(crate) r#package: Option<serde::de::IgnoredAny>,
202
203 #[cfg_attr(feature = "schemars", schemars(skip))]
204 pub(crate) build_backend: Option<serde::de::IgnoredAny>,
205}
206
207impl Options {
208 pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerSchema) -> Self {
210 Self {
211 globals,
212 top_level,
213 ..Default::default()
214 }
215 }
216
217 #[must_use]
219 pub(crate) fn with_origin(mut self, origin: Origin) -> Self {
220 if let Some(indexes) = &mut self.top_level.index {
221 for index in indexes {
222 index.origin.get_or_insert(origin);
223 }
224 }
225 if let Some(index_url) = &mut self.top_level.index_url {
226 index_url.try_set_origin(origin);
227 }
228 if let Some(extra_index_urls) = &mut self.top_level.extra_index_url {
229 for index_url in extra_index_urls {
230 index_url.try_set_origin(origin);
231 }
232 }
233 if let Some(pip) = &mut self.pip {
234 if let Some(indexes) = &mut pip.index {
235 for index in indexes {
236 index.origin.get_or_insert(origin);
237 }
238 }
239 if let Some(index_url) = &mut pip.index_url {
240 index_url.try_set_origin(origin);
241 }
242 if let Some(extra_index_urls) = &mut pip.extra_index_url {
243 for index_url in extra_index_urls {
244 index_url.try_set_origin(origin);
245 }
246 }
247 }
248 self
249 }
250
251 pub(crate) fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
253 Ok(Self {
254 top_level: self.top_level.relative_to(root_dir)?,
255 pip: self.pip.map(|pip| pip.relative_to(root_dir)).transpose()?,
256 ..self
257 })
258 }
259}
260
261#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
263#[serde(try_from = "GlobalOptionsWire", rename_all = "kebab-case")]
264#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
265#[cfg_attr(feature = "schemars", schemars(!try_from))]
266pub struct GlobalOptions {
267 #[option(
274 default = "null",
275 value_type = "str",
276 example = r#"
277 required-version = ">=0.5.0"
278 "#
279 )]
280 pub required_version: Option<RequiredVersion>,
281 #[option(
286 default = "false",
287 value_type = "bool",
288 uv_toml_only = true,
289 example = r#"
290 system-certs = true
291 "#
292 )]
293 pub system_certs: Option<bool>,
294 #[deprecated(note = "use `system-certs` instead")]
301 #[option(
302 default = "false",
303 value_type = "bool",
304 uv_toml_only = true,
305 example = r#"
306 native-tls = true
307 "#
308 )]
309 pub native_tls: Option<bool>,
310 #[option(
312 default = "false",
313 value_type = "bool",
314 example = r#"
315 offline = true
316 "#
317 )]
318 pub offline: Option<bool>,
319 #[option(
322 default = "false",
323 value_type = "bool",
324 example = r#"
325 no-cache = true
326 "#
327 )]
328 pub no_cache: Option<bool>,
329 #[option(
334 default = "None",
335 value_type = "str",
336 uv_toml_only = true,
337 example = r#"
338 cache-dir = "./.uv_cache"
339 "#
340 )]
341 pub cache_dir: Option<PathBuf>,
342
343 #[serde(flatten)]
345 pub preview: Option<PreviewOption>,
346
347 #[option(
350 default = "\"managed\"",
351 value_type = "str",
352 example = r#"
353 python-preference = "managed"
354 "#,
355 possible_values = true
356 )]
357 pub python_preference: Option<PythonPreference>,
358 #[option(
360 default = "\"automatic\"",
361 value_type = "str",
362 example = r#"
363 python-downloads = "manual"
364 "#,
365 possible_values = true
366 )]
367 pub python_downloads: Option<PythonDownloads>,
368 #[option(
371 default = "50",
372 value_type = "int",
373 example = r#"
374 concurrent-downloads = 4
375 "#
376 )]
377 pub concurrent_downloads: Option<NonZeroUsize>,
378 #[option(
383 default = "None",
384 value_type = "int",
385 example = r#"
386 concurrent-builds = 4
387 "#
388 )]
389 pub concurrent_builds: Option<NonZeroUsize>,
390 #[option(
394 default = "None",
395 value_type = "int",
396 example = r#"
397 concurrent-installs = 4
398 "#
399 )]
400 pub concurrent_installs: Option<NonZeroUsize>,
401 #[option(
403 default = "None",
404 value_type = "str",
405 uv_toml_only = true,
406 example = r#"
407 http-proxy = "http://proxy.example.com"
408 "#
409 )]
410 pub http_proxy: Option<ProxyUrl>,
411 #[option(
413 default = "None",
414 value_type = "str",
415 uv_toml_only = true,
416 example = r#"
417 https-proxy = "https://proxy.example.com"
418 "#
419 )]
420 pub https_proxy: Option<ProxyUrl>,
421 #[option(
423 default = "None",
424 value_type = "list[str]",
425 uv_toml_only = true,
426 example = r#"
427 no-proxy = ["localhost", "127.0.0.1"]
428 "#
429 )]
430 pub no_proxy: Option<Vec<String>>,
431 #[option(
440 default = "[]",
441 value_type = "list[str]",
442 example = r#"
443 allow-insecure-host = ["localhost:8080"]
444 "#
445 )]
446 pub allow_insecure_host: Option<Vec<TrustedHost>>,
447}
448
449#[derive(Debug, Clone, Default, Deserialize)]
452#[serde(rename_all = "kebab-case")]
453struct GlobalOptionsWire {
454 required_version: Option<RequiredVersion>,
455 system_certs: Option<bool>,
456 native_tls: Option<bool>,
457 offline: Option<bool>,
458 no_cache: Option<bool>,
459 cache_dir: Option<PathBuf>,
460
461 preview: Option<bool>,
462 preview_features: Option<PreviewFeaturesOption>,
463
464 python_preference: Option<PythonPreference>,
465 python_downloads: Option<PythonDownloads>,
466 concurrent_downloads: Option<NonZeroUsize>,
467 concurrent_builds: Option<NonZeroUsize>,
468 concurrent_installs: Option<NonZeroUsize>,
469 http_proxy: Option<ProxyUrl>,
470 https_proxy: Option<ProxyUrl>,
471 no_proxy: Option<Vec<String>>,
472 allow_insecure_host: Option<Vec<TrustedHost>>,
473}
474
475impl TryFrom<GlobalOptionsWire> for GlobalOptions {
476 type Error = &'static str;
477
478 #[allow(deprecated)]
479 fn try_from(value: GlobalOptionsWire) -> Result<Self, Self::Error> {
480 let GlobalOptionsWire {
481 required_version,
482 system_certs,
483 native_tls,
484 offline,
485 no_cache,
486 cache_dir,
487 preview,
488 preview_features,
489 python_preference,
490 python_downloads,
491 concurrent_downloads,
492 concurrent_builds,
493 concurrent_installs,
494 http_proxy,
495 https_proxy,
496 no_proxy,
497 allow_insecure_host,
498 } = value;
499
500 Ok(Self {
501 required_version,
502 system_certs,
503 native_tls,
504 offline,
505 no_cache,
506 cache_dir,
507 preview: PreviewOption::try_from(preview, preview_features)?,
508 python_preference,
509 python_downloads,
510 concurrent_downloads,
511 concurrent_builds,
512 concurrent_installs,
513 http_proxy,
514 https_proxy,
515 no_proxy,
516 allow_insecure_host,
517 })
518 }
519}
520
521fn rebase_indexes(
523 root_dir: &Path,
524 indexes: &mut Option<Vec<Index>>,
525 index_url: &mut Option<PipIndex>,
526 extra_index_urls: &mut Option<Vec<PipExtraIndex>>,
527 find_links: &mut Option<Vec<PipFindLinks>>,
528) -> Result<(), IndexUrlError> {
529 *indexes = indexes
530 .take()
531 .map(|indexes| {
532 indexes
533 .into_iter()
534 .map(|index| index.relative_to(root_dir))
535 .collect::<Result<Vec<_>, _>>()
536 })
537 .transpose()?;
538 *index_url = index_url
539 .take()
540 .map(|index| index.relative_to(root_dir))
541 .transpose()?;
542 *extra_index_urls = extra_index_urls
543 .take()
544 .map(|indexes| {
545 indexes
546 .into_iter()
547 .map(|index| index.relative_to(root_dir))
548 .collect::<Result<Vec<_>, _>>()
549 })
550 .transpose()?;
551 *find_links = find_links
552 .take()
553 .map(|find_links| {
554 find_links
555 .into_iter()
556 .map(|find_link| find_link.relative_to(root_dir))
557 .collect::<Result<Vec<_>, _>>()
558 })
559 .transpose()?;
560
561 Ok(())
562}
563
564#[derive(Debug, Clone, Default, CombineOptions)]
566pub struct InstallerOptions {
567 index: Option<Vec<Index>>,
568 index_url: Option<PipIndex>,
569 extra_index_url: Option<Vec<PipExtraIndex>>,
570 no_index: Option<bool>,
571 find_links: Option<Vec<PipFindLinks>>,
572 index_strategy: Option<IndexStrategy>,
573 keyring_provider: Option<KeyringProviderType>,
574 config_settings: Option<ConfigSettings>,
575 exclude_newer: Option<ExcludeNewerOverride>,
576 link_mode: Option<LinkMode>,
577 compile_bytecode: Option<bool>,
578 reinstall: Option<Reinstall>,
579 build_isolation: Option<BuildIsolation>,
580 no_build: Option<bool>,
581 no_build_package: Option<Vec<PackageName>>,
582 no_binary: Option<bool>,
583 no_binary_package: Option<Vec<PackageName>>,
584 no_sources: Option<bool>,
585 no_sources_package: Option<Vec<PackageName>>,
586}
587
588#[derive(Debug, Clone, Default, CombineOptions)]
590pub struct IndexOptions {
591 pub index: Option<Vec<Index>>,
592 pub index_url: Option<PipIndex>,
593 pub extra_index_url: Option<Vec<PipExtraIndex>>,
594 pub no_index: Option<bool>,
595 pub find_links: Option<Vec<PipFindLinks>>,
596}
597
598impl IndexOptions {
599 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
601 rebase_indexes(
602 root_dir,
603 &mut self.index,
604 &mut self.index_url,
605 &mut self.extra_index_url,
606 &mut self.find_links,
607 )?;
608
609 Ok(self)
610 }
611}
612
613impl From<IndexOptions> for IndexLocations {
614 fn from(value: IndexOptions) -> Self {
615 let IndexOptions {
616 index,
617 index_url,
618 extra_index_url,
619 no_index,
620 find_links,
621 } = value;
622
623 Self::new(
624 index
625 .into_iter()
626 .flatten()
627 .chain(extra_index_url.into_iter().flatten().map(Index::from))
628 .chain(index_url.into_iter().map(Index::from))
629 .collect(),
630 find_links.into_iter().flatten().map(Index::from).collect(),
631 no_index.unwrap_or_default(),
632 )
633 }
634}
635
636impl From<IndexOptions> for PipOptions {
637 fn from(value: IndexOptions) -> Self {
638 let IndexOptions {
639 index,
640 index_url,
641 extra_index_url,
642 no_index,
643 find_links,
644 } = value;
645
646 Self {
647 index,
648 index_url,
649 extra_index_url,
650 no_index,
651 find_links,
652 ..Self::default()
653 }
654 }
655}
656
657#[derive(Debug, Clone, Default, CombineOptions)]
659pub struct ResolverOptions {
660 pub indexes: IndexOptions,
661 pub index_strategy: Option<IndexStrategy>,
662 pub keyring_provider: Option<KeyringProviderType>,
663 pub resolution: Option<ResolutionMode>,
664 pub prerelease: Option<PrereleaseMode>,
665 pub prerelease_package: Option<PrereleasePackage>,
666 pub fork_strategy: Option<ForkStrategy>,
667 pub dependency_metadata: Option<Vec<StaticMetadata>>,
668 pub config_settings: Option<ConfigSettings>,
669 pub config_settings_package: Option<PackageConfigSettings>,
670 pub exclude_newer: Option<ExcludeNewerOverride>,
671 pub exclude_newer_package: Option<ExcludeNewerPackage>,
672 pub link_mode: Option<LinkMode>,
673 pub torch_backend: Option<TorchMode>,
674 pub upgrade: Option<Upgrade>,
675 pub build_isolation: Option<BuildIsolation>,
676 pub no_build: Option<bool>,
677 pub no_build_package: Option<Vec<PackageName>>,
678 pub no_binary: Option<bool>,
679 pub no_binary_package: Option<Vec<PackageName>>,
680 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
681 pub extra_build_variables: Option<ExtraBuildVariables>,
682 pub no_sources: Option<bool>,
683 pub no_sources_package: Option<Vec<PackageName>>,
684}
685
686impl ResolverOptions {
687 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
689 self.indexes = self.indexes.relative_to(root_dir)?;
690 Ok(self)
691 }
692}
693
694#[derive(Debug, Clone, Default, CombineOptions)]
697pub struct ResolverInstallerOptions {
698 pub indexes: IndexOptions,
699 pub index_strategy: Option<IndexStrategy>,
700 pub keyring_provider: Option<KeyringProviderType>,
701 pub resolution: Option<ResolutionMode>,
702 pub prerelease: Option<PrereleaseMode>,
703 pub prerelease_package: Option<PrereleasePackage>,
704 pub fork_strategy: Option<ForkStrategy>,
705 pub dependency_metadata: Option<Vec<StaticMetadata>>,
706 pub config_settings: Option<ConfigSettings>,
707 pub config_settings_package: Option<PackageConfigSettings>,
708 pub build_isolation: Option<BuildIsolation>,
709 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
710 pub extra_build_variables: Option<ExtraBuildVariables>,
711 pub exclude_newer: Option<ExcludeNewerOverride>,
712 pub exclude_newer_package: Option<ExcludeNewerPackage>,
713 pub link_mode: Option<LinkMode>,
714 pub torch_backend: Option<TorchMode>,
715 pub compile_bytecode: Option<bool>,
716 pub no_sources: Option<bool>,
717 pub no_sources_package: Option<Vec<PackageName>>,
718 pub upgrade: Option<Upgrade>,
719 pub reinstall: Option<Reinstall>,
720 pub no_build: Option<bool>,
721 pub no_build_package: Option<Vec<PackageName>>,
722 pub no_binary: Option<bool>,
723 pub no_binary_package: Option<Vec<PackageName>>,
724}
725
726impl ResolverInstallerOptions {
727 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
729 self.indexes = self.indexes.relative_to(root_dir)?;
730 Ok(self)
731 }
732}
733
734impl From<ResolverInstallerSchema> for ResolverInstallerOptions {
735 fn from(value: ResolverInstallerSchema) -> Self {
736 let ResolverInstallerSchema {
737 index,
738 index_url,
739 extra_index_url,
740 no_index,
741 find_links,
742 index_strategy,
743 keyring_provider,
744 resolution,
745 prerelease,
746 prerelease_package,
747 fork_strategy,
748 dependency_metadata,
749 config_settings,
750 config_settings_package,
751 no_build_isolation,
752 no_build_isolation_package,
753 extra_build_dependencies,
754 extra_build_variables,
755 exclude_newer,
756 exclude_newer_package,
757 link_mode,
758 torch_backend,
759 compile_bytecode,
760 no_sources,
761 no_sources_package,
762 upgrade,
763 upgrade_package,
764 reinstall,
765 reinstall_package,
766 no_build,
767 no_build_package,
768 no_binary,
769 no_binary_package,
770 } = value;
771 Self {
772 indexes: IndexOptions {
773 index,
774 index_url,
775 extra_index_url,
776 no_index,
777 find_links,
778 },
779 index_strategy,
780 keyring_provider,
781 resolution,
782 prerelease,
783 prerelease_package,
784 fork_strategy,
785 dependency_metadata,
786 config_settings,
787 config_settings_package,
788 build_isolation: BuildIsolation::from_args(
789 no_build_isolation,
790 no_build_isolation_package.into_iter().flatten().collect(),
791 ),
792 extra_build_dependencies,
793 extra_build_variables,
794 exclude_newer,
795 exclude_newer_package,
796 link_mode,
797 torch_backend,
798 compile_bytecode,
799 no_sources,
800 no_sources_package,
801 upgrade: Upgrade::from_args(
802 upgrade,
803 upgrade_package
804 .into_iter()
805 .flatten()
806 .map(Into::into)
807 .collect(),
808 Vec::new(),
809 ),
810 reinstall: Reinstall::from_args(reinstall, reinstall_package.unwrap_or_default()),
811 no_build,
812 no_build_package,
813 no_binary,
814 no_binary_package,
815 }
816 }
817}
818
819impl ResolverInstallerSchema {
820 fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
822 rebase_indexes(
823 root_dir,
824 &mut self.index,
825 &mut self.index_url,
826 &mut self.extra_index_url,
827 &mut self.find_links,
828 )?;
829
830 Ok(self)
831 }
832}
833
834#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
836#[serde(rename_all = "kebab-case")]
837#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
838pub struct ResolverInstallerSchema {
839 #[option(
867 default = "\"[]\"",
868 value_type = "dict",
869 example = r#"
870 [[tool.uv.index]]
871 name = "pytorch"
872 url = "https://download.pytorch.org/whl/cu130"
873 "#
874 )]
875 pub index: Option<Vec<Index>>,
876 #[option(
886 default = "\"https://pypi.org/simple\"",
887 value_type = "str",
888 example = r#"
889 index-url = "https://test.pypi.org/simple"
890 "#
891 )]
892 pub index_url: Option<PipIndex>,
893 #[option(
907 default = "[]",
908 value_type = "list[str]",
909 example = r#"
910 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
911 "#
912 )]
913 pub extra_index_url: Option<Vec<PipExtraIndex>>,
914 #[option(
917 default = "false",
918 value_type = "bool",
919 example = r#"
920 no-index = true
921 "#
922 )]
923 pub no_index: Option<bool>,
924 #[option(
933 default = "[]",
934 value_type = "list[str]",
935 example = r#"
936 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
937 "#
938 )]
939 pub find_links: Option<Vec<PipFindLinks>>,
940 #[option(
947 default = "\"first-index\"",
948 value_type = "str",
949 example = r#"
950 index-strategy = "unsafe-best-match"
951 "#,
952 possible_values = true
953 )]
954 pub index_strategy: Option<IndexStrategy>,
955 #[option(
960 default = "\"disabled\"",
961 value_type = "str",
962 example = r#"
963 keyring-provider = "subprocess"
964 "#
965 )]
966 pub keyring_provider: Option<KeyringProviderType>,
967 #[option(
972 default = "\"highest\"",
973 value_type = "str",
974 example = r#"
975 resolution = "lowest-direct"
976 "#,
977 possible_values = true
978 )]
979 pub resolution: Option<ResolutionMode>,
980 #[option(
986 default = "\"if-necessary\"",
987 value_type = "str",
988 example = r#"
989 prerelease = "allow"
990 "#,
991 possible_values = true
992 )]
993 pub prerelease: Option<PrereleaseMode>,
994 #[option(
999 default = "{}",
1000 value_type = "dict",
1001 example = r#"
1002 prerelease-package = { numpy = "allow", scipy = "disallow" }
1003 "#
1004 )]
1005 pub prerelease_package: Option<PrereleasePackage>,
1006 #[option(
1017 default = "\"requires-python\"",
1018 value_type = "str",
1019 example = r#"
1020 fork-strategy = "fewest"
1021 "#,
1022 possible_values = true
1023 )]
1024 pub fork_strategy: Option<ForkStrategy>,
1025 #[option(
1039 default = r#"[]"#,
1040 value_type = "list[dict]",
1041 example = r#"
1042 dependency-metadata = [
1043 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1044 ]
1045 "#
1046 )]
1047 pub dependency_metadata: Option<Vec<StaticMetadata>>,
1048 #[option(
1051 default = "{}",
1052 value_type = "dict",
1053 example = r#"
1054 config-settings = { editable_mode = "compat" }
1055 "#
1056 )]
1057 pub config_settings: Option<ConfigSettings>,
1058 #[option(
1063 default = "{}",
1064 value_type = "dict",
1065 example = r#"
1066 config-settings-package = { numpy = { editable_mode = "compat" } }
1067 "#
1068 )]
1069 pub config_settings_package: Option<PackageConfigSettings>,
1070 #[option(
1075 default = "false",
1076 value_type = "bool",
1077 example = r#"
1078 no-build-isolation = true
1079 "#
1080 )]
1081 pub no_build_isolation: Option<bool>,
1082 #[option(
1087 default = "[]",
1088 value_type = "list[str]",
1089 example = r#"
1090 no-build-isolation-package = ["package1", "package2"]
1091 "#
1092 )]
1093 pub no_build_isolation_package: Option<Vec<PackageName>>,
1094 #[option(
1100 default = "[]",
1101 value_type = "dict",
1102 example = r#"
1103 extra-build-dependencies = { pytest = ["setuptools"] }
1104 "#
1105 )]
1106 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1107 #[option(
1112 default = r#"{}"#,
1113 value_type = r#"dict[str, dict[str, str]]"#,
1114 example = r#"
1115 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1116 "#
1117 )]
1118 pub extra_build_variables: Option<ExtraBuildVariables>,
1119 #[option(
1134 default = "None",
1135 value_type = "str | false",
1136 example = r#"
1137 exclude-newer = "2006-12-02T02:07:43Z"
1138 "#
1139 )]
1140 pub exclude_newer: Option<ExcludeNewerOverride>,
1141 #[option(
1155 default = "None",
1156 value_type = "dict",
1157 example = r#"
1158 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
1159 "#
1160 )]
1161 pub exclude_newer_package: Option<ExcludeNewerPackage>,
1162 #[option(
1172 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
1173 value_type = "str",
1174 example = r#"
1175 link-mode = "copy"
1176 "#,
1177 possible_values = true
1178 )]
1179 pub link_mode: Option<LinkMode>,
1180 #[option(
1191 default = "false",
1192 value_type = "bool",
1193 example = r#"
1194 compile-bytecode = true
1195 "#
1196 )]
1197 pub compile_bytecode: Option<bool>,
1198 #[option(
1202 default = "false",
1203 value_type = "bool",
1204 example = r#"
1205 no-sources = true
1206 "#
1207 )]
1208 pub no_sources: Option<bool>,
1209 #[option(
1211 default = "[]",
1212 value_type = "list[str]",
1213 example = r#"
1214 no-sources-package = ["ruff"]
1215 "#
1216 )]
1217 pub no_sources_package: Option<Vec<PackageName>>,
1218 #[option(
1220 default = "false",
1221 value_type = "bool",
1222 example = r#"
1223 upgrade = true
1224 "#
1225 )]
1226 pub upgrade: Option<bool>,
1227 #[option(
1232 default = "[]",
1233 value_type = "list[str]",
1234 example = r#"
1235 upgrade-package = ["ruff"]
1236 "#
1237 )]
1238 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1239 #[option(
1241 default = "false",
1242 value_type = "bool",
1243 example = r#"
1244 reinstall = true
1245 "#
1246 )]
1247 pub reinstall: Option<bool>,
1248 #[option(
1251 default = "[]",
1252 value_type = "list[str]",
1253 example = r#"
1254 reinstall-package = ["ruff"]
1255 "#
1256 )]
1257 pub reinstall_package: Option<Vec<PackageName>>,
1258 #[option(
1265 default = "false",
1266 value_type = "bool",
1267 example = r#"
1268 no-build = true
1269 "#
1270 )]
1271 pub no_build: Option<bool>,
1272 #[option(
1276 default = "[]",
1277 value_type = "list[str]",
1278 example = r#"
1279 no-build-package = ["ruff"]
1280 "#
1281 )]
1282 pub no_build_package: Option<Vec<PackageName>>,
1283 #[option(
1288 default = "false",
1289 value_type = "bool",
1290 example = r#"
1291 no-binary = true
1292 "#
1293 )]
1294 pub no_binary: Option<bool>,
1295 #[option(
1297 default = "[]",
1298 value_type = "list[str]",
1299 example = r#"
1300 no-binary-package = ["ruff"]
1301 "#
1302 )]
1303 pub no_binary_package: Option<Vec<PackageName>>,
1304 #[option(
1319 default = "null",
1320 value_type = "str",
1321 example = r#"
1322 torch-backend = "auto"
1323 "#
1324 )]
1325 pub torch_backend: Option<TorchMode>,
1326}
1327
1328#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
1330#[serde(rename_all = "kebab-case")]
1331#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1332pub struct PythonInstallMirrors {
1333 #[option(
1341 default = "None",
1342 value_type = "str",
1343 uv_toml_only = true,
1344 example = r#"
1345 python-install-mirror = "https://github.com/astral-sh/python-build-standalone/releases/download"
1346 "#
1347 )]
1348 pub python_install_mirror: Option<String>,
1349 #[option(
1358 default = "None",
1359 value_type = "str",
1360 uv_toml_only = true,
1361 example = r#"
1362 pypy-install-mirror = "https://downloads.python.org/pypy"
1363 "#
1364 )]
1365 pub pypy_install_mirror: Option<String>,
1366 #[option(
1374 default = "None",
1375 value_type = "str",
1376 uv_toml_only = true,
1377 example = r#"
1378 graalpy-install-mirror = "https://github.com/oracle/graalpython/releases/download"
1379 "#
1380 )]
1381 pub graalpy_install_mirror: Option<String>,
1382 #[option(
1390 default = "None",
1391 value_type = "str",
1392 uv_toml_only = true,
1393 example = r#"
1394 pyodide-install-mirror = "https://github.com/pyodide/pyodide/releases/download"
1395 "#
1396 )]
1397 pub pyodide_install_mirror: Option<String>,
1398
1399 #[option(
1401 default = "None",
1402 value_type = "str",
1403 uv_toml_only = true,
1404 example = r#"
1405 python-downloads-json-url = "/etc/uv/python-downloads.json"
1406 "#
1407 )]
1408 pub python_downloads_json_url: Option<String>,
1409}
1410
1411impl PythonInstallMirrors {
1412 pub fn mirrors(&self) -> PythonDownloadMirrors<'_> {
1414 PythonDownloadMirrors {
1415 cpython: self.python_install_mirror.as_deref(),
1416 pypy: self.pypy_install_mirror.as_deref(),
1417 graalpy: self.graalpy_install_mirror.as_deref(),
1418 pyodide: self.pyodide_install_mirror.as_deref(),
1419 }
1420 }
1421
1422 #[must_use]
1423 pub fn combine(self, other: Self) -> Self {
1424 Self {
1425 python_install_mirror: self.python_install_mirror.or(other.python_install_mirror),
1426 pypy_install_mirror: self.pypy_install_mirror.or(other.pypy_install_mirror),
1427 graalpy_install_mirror: self.graalpy_install_mirror.or(other.graalpy_install_mirror),
1428 pyodide_install_mirror: self.pyodide_install_mirror.or(other.pyodide_install_mirror),
1429 python_downloads_json_url: self
1430 .python_downloads_json_url
1431 .or(other.python_downloads_json_url),
1432 }
1433 }
1434}
1435
1436#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
1441#[serde(deny_unknown_fields, rename_all = "kebab-case")]
1442#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1443pub struct PipOptions {
1444 #[option(
1457 default = "None",
1458 value_type = "str",
1459 example = r#"
1460 python = "3.10"
1461 "#
1462 )]
1463 pub python: Option<String>,
1464 #[option(
1473 default = "false",
1474 value_type = "bool",
1475 example = r#"
1476 system = true
1477 "#
1478 )]
1479 pub system: Option<bool>,
1480 #[option(
1487 default = "false",
1488 value_type = "bool",
1489 example = r#"
1490 break-system-packages = true
1491 "#
1492 )]
1493 pub break_system_packages: Option<bool>,
1494 #[option(
1497 default = "None",
1498 value_type = "str",
1499 example = r#"
1500 target = "./target"
1501 "#
1502 )]
1503 pub target: Option<PathBuf>,
1504 #[option(
1512 default = "None",
1513 value_type = "str",
1514 example = r#"
1515 prefix = "./prefix"
1516 "#
1517 )]
1518 pub prefix: Option<PathBuf>,
1519 #[serde(skip)]
1520 #[cfg_attr(feature = "schemars", schemars(skip))]
1521 pub index: Option<Vec<Index>>,
1522 #[option(
1530 default = "\"https://pypi.org/simple\"",
1531 value_type = "str",
1532 example = r#"
1533 index-url = "https://test.pypi.org/simple"
1534 "#
1535 )]
1536 pub index_url: Option<PipIndex>,
1537 #[option(
1548 default = "[]",
1549 value_type = "list[str]",
1550 example = r#"
1551 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
1552 "#
1553 )]
1554 pub extra_index_url: Option<Vec<PipExtraIndex>>,
1555 #[option(
1558 default = "false",
1559 value_type = "bool",
1560 example = r#"
1561 no-index = true
1562 "#
1563 )]
1564 pub no_index: Option<bool>,
1565 #[option(
1574 default = "[]",
1575 value_type = "list[str]",
1576 example = r#"
1577 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
1578 "#
1579 )]
1580 pub find_links: Option<Vec<PipFindLinks>>,
1581 #[option(
1588 default = "\"first-index\"",
1589 value_type = "str",
1590 example = r#"
1591 index-strategy = "unsafe-best-match"
1592 "#,
1593 possible_values = true
1594 )]
1595 pub index_strategy: Option<IndexStrategy>,
1596 #[option(
1601 default = "disabled",
1602 value_type = "str",
1603 example = r#"
1604 keyring-provider = "subprocess"
1605 "#
1606 )]
1607 pub keyring_provider: Option<KeyringProviderType>,
1608 #[option(
1616 default = "false",
1617 value_type = "bool",
1618 example = r#"
1619 no-build = true
1620 "#
1621 )]
1622 pub no_build: Option<bool>,
1623 #[option(
1631 default = "[]",
1632 value_type = "list[str]",
1633 example = r#"
1634 no-binary = ["ruff"]
1635 "#
1636 )]
1637 pub no_binary: Option<Vec<PackageNameSpecifier>>,
1638 #[option(
1648 default = "[]",
1649 value_type = "list[str]",
1650 example = r#"
1651 only-binary = ["ruff"]
1652 "#
1653 )]
1654 pub only_binary: Option<Vec<PackageNameSpecifier>>,
1655 #[option(
1660 default = "false",
1661 value_type = "bool",
1662 example = r#"
1663 no-build-isolation = true
1664 "#
1665 )]
1666 pub no_build_isolation: Option<bool>,
1667 #[option(
1672 default = "[]",
1673 value_type = "list[str]",
1674 example = r#"
1675 no-build-isolation-package = ["package1", "package2"]
1676 "#
1677 )]
1678 pub no_build_isolation_package: Option<Vec<PackageName>>,
1679 #[option(
1685 default = "[]",
1686 value_type = "dict",
1687 example = r#"
1688 extra-build-dependencies = { pytest = ["setuptools"] }
1689 "#
1690 )]
1691 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1692 #[option(
1697 default = r#"{}"#,
1698 value_type = r#"dict[str, dict[str, str]]"#,
1699 example = r#"
1700 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1701 "#
1702 )]
1703 pub extra_build_variables: Option<ExtraBuildVariables>,
1704 #[option(
1707 default = "false",
1708 value_type = "bool",
1709 example = r#"
1710 strict = true
1711 "#
1712 )]
1713 pub strict: Option<bool>,
1714 #[option(
1718 default = "[]",
1719 value_type = "list[str]",
1720 example = r#"
1721 extra = ["dev", "docs"]
1722 "#
1723 )]
1724 pub extra: Option<Vec<ExtraName>>,
1725 #[option(
1729 default = "false",
1730 value_type = "bool",
1731 example = r#"
1732 all-extras = true
1733 "#
1734 )]
1735 pub all_extras: Option<bool>,
1736 #[option(
1738 default = "[]",
1739 value_type = "list[str]",
1740 example = r#"
1741 all-extras = true
1742 no-extra = ["dev", "docs"]
1743 "#
1744 )]
1745 pub no_extra: Option<Vec<ExtraName>>,
1746 #[option(
1749 default = "false",
1750 value_type = "bool",
1751 example = r#"
1752 no-deps = true
1753 "#
1754 )]
1755 pub no_deps: Option<bool>,
1756 #[option(
1758 default = "None",
1759 value_type = "list[str]",
1760 example = r#"
1761 group = ["dev", "docs"]
1762 "#
1763 )]
1764 pub group: Option<Vec<PipGroupName>>,
1765 #[option(
1768 default = "false",
1769 value_type = "bool",
1770 example = r#"
1771 allow-empty-requirements = true
1772 "#
1773 )]
1774 pub allow_empty_requirements: Option<bool>,
1775 #[option(
1780 default = "\"highest\"",
1781 value_type = "str",
1782 example = r#"
1783 resolution = "lowest-direct"
1784 "#,
1785 possible_values = true
1786 )]
1787 pub resolution: Option<ResolutionMode>,
1788 #[option(
1794 default = "\"if-necessary\"",
1795 value_type = "str",
1796 example = r#"
1797 prerelease = "allow"
1798 "#,
1799 possible_values = true
1800 )]
1801 pub prerelease: Option<PrereleaseMode>,
1802 #[serde(skip)]
1803 #[cfg_attr(feature = "schemars", schemars(skip))]
1804 pub prerelease_package: Option<PrereleasePackage>,
1805 #[option(
1816 default = "\"requires-python\"",
1817 value_type = "str",
1818 example = r#"
1819 fork-strategy = "fewest"
1820 "#,
1821 possible_values = true
1822 )]
1823 pub fork_strategy: Option<ForkStrategy>,
1824 #[option(
1838 default = r#"[]"#,
1839 value_type = "list[dict]",
1840 example = r#"
1841 dependency-metadata = [
1842 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1843 ]
1844 "#
1845 )]
1846 pub dependency_metadata: Option<Vec<StaticMetadata>>,
1847 #[option(
1852 default = "None",
1853 value_type = "str",
1854 example = r#"
1855 output-file = "requirements.txt"
1856 "#
1857 )]
1858 pub output_file: Option<PathBuf>,
1859 #[option(
1865 default = "false",
1866 value_type = "bool",
1867 example = r#"
1868 no-strip-extras = true
1869 "#
1870 )]
1871 pub no_strip_extras: Option<bool>,
1872 #[option(
1877 default = "false",
1878 value_type = "bool",
1879 example = r#"
1880 no-strip-markers = true
1881 "#
1882 )]
1883 pub no_strip_markers: Option<bool>,
1884 #[option(
1887 default = "false",
1888 value_type = "bool",
1889 example = r#"
1890 no-annotate = true
1891 "#
1892 )]
1893 pub no_annotate: Option<bool>,
1894 #[option(
1896 default = r#"false"#,
1897 value_type = "bool",
1898 example = r#"
1899 no-header = true
1900 "#
1901 )]
1902 pub no_header: Option<bool>,
1903 #[option(
1907 default = "None",
1908 value_type = "str",
1909 example = r#"
1910 custom-compile-command = "./custom-uv-compile.sh"
1911 "#
1912 )]
1913 pub custom_compile_command: Option<String>,
1914 #[option(
1916 default = "false",
1917 value_type = "bool",
1918 example = r#"
1919 generate-hashes = true
1920 "#
1921 )]
1922 pub generate_hashes: Option<bool>,
1923 #[option(
1926 default = "{}",
1927 value_type = "dict",
1928 example = r#"
1929 config-settings = { editable_mode = "compat" }
1930 "#
1931 )]
1932 pub config_settings: Option<ConfigSettings>,
1933 #[option(
1936 default = "{}",
1937 value_type = "dict",
1938 example = r#"
1939 config-settings-package = { numpy = { editable_mode = "compat" } }
1940 "#
1941 )]
1942 pub config_settings_package: Option<PackageConfigSettings>,
1943 #[option(
1949 default = "None",
1950 value_type = "str",
1951 example = r#"
1952 python-version = "3.8"
1953 "#
1954 )]
1955 pub python_version: Option<PythonVersion>,
1956 #[option(
1962 default = "None",
1963 value_type = "str",
1964 example = r#"
1965 python-platform = "x86_64-unknown-linux-gnu"
1966 "#
1967 )]
1968 pub python_platform: Option<TargetTriple>,
1969 #[option(
1977 default = "false",
1978 value_type = "bool",
1979 example = r#"
1980 universal = true
1981 "#
1982 )]
1983 pub universal: Option<bool>,
1984 #[option(
1999 default = "None",
2000 value_type = "str | false",
2001 example = r#"
2002 exclude-newer = "2006-12-02T02:07:43Z"
2003 "#
2004 )]
2005 pub exclude_newer: Option<ExcludeNewerOverride>,
2006 #[option(
2019 default = "None",
2020 value_type = "dict",
2021 example = r#"
2022 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
2023 "#
2024 )]
2025 pub exclude_newer_package: Option<ExcludeNewerPackage>,
2026 #[option(
2029 default = "[]",
2030 value_type = "list[str]",
2031 example = r#"
2032 no-emit-package = ["ruff"]
2033 "#
2034 )]
2035 pub no_emit_package: Option<Vec<PackageName>>,
2036 #[option(
2038 default = "false",
2039 value_type = "bool",
2040 example = r#"
2041 emit-index-url = true
2042 "#
2043 )]
2044 pub emit_index_url: Option<bool>,
2045 #[option(
2047 default = "false",
2048 value_type = "bool",
2049 example = r#"
2050 emit-find-links = true
2051 "#
2052 )]
2053 pub emit_find_links: Option<bool>,
2054 #[option(
2056 default = "false",
2057 value_type = "bool",
2058 example = r#"
2059 emit-build-options = true
2060 "#
2061 )]
2062 pub emit_build_options: Option<bool>,
2063 #[option(
2070 default = "false",
2071 value_type = "bool",
2072 example = r#"
2073 emit-marker-expression = true
2074 "#
2075 )]
2076 pub emit_marker_expression: Option<bool>,
2077 #[option(
2080 default = "false",
2081 value_type = "bool",
2082 example = r#"
2083 emit-index-annotation = true
2084 "#
2085 )]
2086 pub emit_index_annotation: Option<bool>,
2087 #[option(
2090 default = "\"split\"",
2091 value_type = "str",
2092 example = r#"
2093 annotation-style = "line"
2094 "#,
2095 possible_values = true
2096 )]
2097 pub annotation_style: Option<AnnotationStyle>,
2098 #[option(
2108 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
2109 value_type = "str",
2110 example = r#"
2111 link-mode = "copy"
2112 "#,
2113 possible_values = true
2114 )]
2115 pub link_mode: Option<LinkMode>,
2116 #[option(
2127 default = "false",
2128 value_type = "bool",
2129 example = r#"
2130 compile-bytecode = true
2131 "#
2132 )]
2133 pub compile_bytecode: Option<bool>,
2134 #[option(
2147 default = "false",
2148 value_type = "bool",
2149 example = r#"
2150 require-hashes = true
2151 "#
2152 )]
2153 pub require_hashes: Option<bool>,
2154 #[option(
2160 default = "true",
2161 value_type = "bool",
2162 example = r#"
2163 verify-hashes = true
2164 "#
2165 )]
2166 pub verify_hashes: Option<bool>,
2167 #[option(
2171 default = "false",
2172 value_type = "bool",
2173 example = r#"
2174 no-sources = true
2175 "#
2176 )]
2177 pub no_sources: Option<bool>,
2178 #[option(
2180 default = "[]",
2181 value_type = "list[str]",
2182 example = r#"
2183 no-sources-package = ["ruff"]
2184 "#
2185 )]
2186 pub no_sources_package: Option<Vec<PackageName>>,
2187 #[option(
2189 default = "false",
2190 value_type = "bool",
2191 example = r#"
2192 upgrade = true
2193 "#
2194 )]
2195 pub upgrade: Option<bool>,
2196 #[option(
2201 default = "[]",
2202 value_type = "list[str]",
2203 example = r#"
2204 upgrade-package = ["ruff"]
2205 "#
2206 )]
2207 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2208 #[option(
2210 default = "false",
2211 value_type = "bool",
2212 example = r#"
2213 reinstall = true
2214 "#
2215 )]
2216 pub reinstall: Option<bool>,
2217 #[option(
2220 default = "[]",
2221 value_type = "list[str]",
2222 example = r#"
2223 reinstall-package = ["ruff"]
2224 "#
2225 )]
2226 pub reinstall_package: Option<Vec<PackageName>>,
2227 #[option(
2242 default = "null",
2243 value_type = "str",
2244 example = r#"
2245 torch-backend = "auto"
2246 "#
2247 )]
2248 pub torch_backend: Option<TorchMode>,
2249}
2250
2251impl PipOptions {
2252 fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
2254 rebase_indexes(
2255 root_dir,
2256 &mut self.index,
2257 &mut self.index_url,
2258 &mut self.extra_index_url,
2259 &mut self.find_links,
2260 )?;
2261
2262 Ok(self)
2263 }
2264}
2265
2266impl From<ResolverInstallerSchema> for ResolverOptions {
2267 fn from(value: ResolverInstallerSchema) -> Self {
2268 Self {
2269 indexes: IndexOptions {
2270 index: value.index,
2271 index_url: value.index_url,
2272 extra_index_url: value.extra_index_url,
2273 no_index: value.no_index,
2274 find_links: value.find_links,
2275 },
2276 index_strategy: value.index_strategy,
2277 keyring_provider: value.keyring_provider,
2278 resolution: value.resolution,
2279 prerelease: value.prerelease,
2280 prerelease_package: value.prerelease_package,
2281 fork_strategy: value.fork_strategy,
2282 dependency_metadata: value.dependency_metadata,
2283 config_settings: value.config_settings,
2284 config_settings_package: value.config_settings_package,
2285 exclude_newer: value.exclude_newer,
2286 exclude_newer_package: value.exclude_newer_package,
2287 link_mode: value.link_mode,
2288 upgrade: Upgrade::from_args(
2289 value.upgrade,
2290 value
2291 .upgrade_package
2292 .into_iter()
2293 .flatten()
2294 .map(Into::into)
2295 .collect(),
2296 Vec::new(),
2297 ),
2298 no_build: value.no_build,
2299 no_build_package: value.no_build_package,
2300 no_binary: value.no_binary,
2301 no_binary_package: value.no_binary_package,
2302 build_isolation: BuildIsolation::from_args(
2303 value.no_build_isolation,
2304 value.no_build_isolation_package.unwrap_or_default(),
2305 ),
2306 extra_build_dependencies: value.extra_build_dependencies,
2307 extra_build_variables: value.extra_build_variables,
2308 no_sources: value.no_sources,
2309 no_sources_package: value.no_sources_package,
2310 torch_backend: value.torch_backend,
2311 }
2312 }
2313}
2314
2315impl From<ResolverInstallerSchema> for InstallerOptions {
2316 fn from(value: ResolverInstallerSchema) -> Self {
2317 Self {
2318 index: value.index,
2319 index_url: value.index_url,
2320 extra_index_url: value.extra_index_url,
2321 no_index: value.no_index,
2322 find_links: value.find_links,
2323 index_strategy: value.index_strategy,
2324 keyring_provider: value.keyring_provider,
2325 config_settings: value.config_settings,
2326 exclude_newer: value.exclude_newer,
2327 link_mode: value.link_mode,
2328 compile_bytecode: value.compile_bytecode,
2329 reinstall: Reinstall::from_args(
2330 value.reinstall,
2331 value.reinstall_package.unwrap_or_default(),
2332 ),
2333 build_isolation: BuildIsolation::from_args(
2334 value.no_build_isolation,
2335 value.no_build_isolation_package.unwrap_or_default(),
2336 ),
2337 no_build: value.no_build,
2338 no_build_package: value.no_build_package,
2339 no_binary: value.no_binary,
2340 no_binary_package: value.no_binary_package,
2341 no_sources: value.no_sources,
2342 no_sources_package: value.no_sources_package,
2343 }
2344 }
2345}
2346
2347#[derive(
2352 Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata,
2353)]
2354#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2355#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2356pub struct ToolOptions {
2357 index: Option<Vec<Index>>,
2358 index_url: Option<PipIndex>,
2359 extra_index_url: Option<Vec<PipExtraIndex>>,
2360 no_index: Option<bool>,
2361 find_links: Option<Vec<PipFindLinks>>,
2362 index_strategy: Option<IndexStrategy>,
2363 keyring_provider: Option<KeyringProviderType>,
2364 resolution: Option<ResolutionMode>,
2365 prerelease: Option<PrereleaseMode>,
2366 prerelease_package: Option<PrereleasePackage>,
2367 fork_strategy: Option<ForkStrategy>,
2368 dependency_metadata: Option<Vec<StaticMetadata>>,
2369 config_settings: Option<ConfigSettings>,
2370 config_settings_package: Option<PackageConfigSettings>,
2371 build_isolation: Option<BuildIsolation>,
2372 extra_build_dependencies: Option<ExtraBuildDependencies>,
2373 extra_build_variables: Option<ExtraBuildVariables>,
2374 exclude_newer: Option<ExcludeNewerOverride>,
2375 exclude_newer_package: Option<ExcludeNewerPackage>,
2376 link_mode: Option<LinkMode>,
2377 compile_bytecode: Option<bool>,
2378 no_sources: Option<bool>,
2379 no_sources_package: Option<Vec<PackageName>>,
2380 no_build: Option<bool>,
2381 no_build_package: Option<Vec<PackageName>>,
2382 no_binary: Option<bool>,
2383 no_binary_package: Option<Vec<PackageName>>,
2384 torch_backend: Option<TorchMode>,
2385}
2386
2387#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2389#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2390pub struct ToolOptionsWire {
2391 index: Option<Vec<Index>>,
2392 index_url: Option<PipIndex>,
2393 extra_index_url: Option<Vec<PipExtraIndex>>,
2394 no_index: Option<bool>,
2395 find_links: Option<Vec<PipFindLinks>>,
2396 index_strategy: Option<IndexStrategy>,
2397 keyring_provider: Option<KeyringProviderType>,
2398 resolution: Option<ResolutionMode>,
2399 prerelease: Option<PrereleaseMode>,
2400 prerelease_package: Option<PrereleasePackage>,
2401 fork_strategy: Option<ForkStrategy>,
2402 dependency_metadata: Option<Vec<StaticMetadata>>,
2403 config_settings: Option<ConfigSettings>,
2404 config_settings_package: Option<PackageConfigSettings>,
2405 build_isolation: Option<BuildIsolation>,
2406 extra_build_dependencies: Option<ExtraBuildDependencies>,
2407 extra_build_variables: Option<ExtraBuildVariables>,
2408 exclude_newer: Option<ExcludeNewerOverride>,
2409 exclude_newer_span: Option<ExcludeNewerSpan>,
2410 #[serde(serialize_with = "serialize_exclude_newer_package_with_spans")]
2411 exclude_newer_package: Option<ExcludeNewerPackage>,
2412 link_mode: Option<LinkMode>,
2413 compile_bytecode: Option<bool>,
2414 no_sources: Option<bool>,
2415 no_sources_package: Option<Vec<PackageName>>,
2416 no_build: Option<bool>,
2417 no_build_package: Option<Vec<PackageName>>,
2418 no_binary: Option<bool>,
2419 no_binary_package: Option<Vec<PackageName>>,
2420 torch_backend: Option<TorchMode>,
2421}
2422
2423impl From<ResolverInstallerOptions> for ToolOptions {
2424 fn from(value: ResolverInstallerOptions) -> Self {
2425 Self {
2426 index: value.indexes.index.map(|indexes| {
2427 indexes
2428 .into_iter()
2429 .map(Index::with_promoted_auth_policy)
2430 .collect()
2431 }),
2432 index_url: value.indexes.index_url,
2433 extra_index_url: value.indexes.extra_index_url,
2434 no_index: value.indexes.no_index,
2435 find_links: value.indexes.find_links,
2436 index_strategy: value.index_strategy,
2437 keyring_provider: value.keyring_provider,
2438 resolution: value.resolution,
2439 prerelease: value.prerelease,
2440 prerelease_package: value.prerelease_package,
2441 fork_strategy: value.fork_strategy,
2442 dependency_metadata: value.dependency_metadata,
2443 config_settings: value.config_settings,
2444 config_settings_package: value.config_settings_package,
2445 build_isolation: value.build_isolation,
2446 extra_build_dependencies: value.extra_build_dependencies,
2447 extra_build_variables: value.extra_build_variables,
2448 exclude_newer: value.exclude_newer,
2449 exclude_newer_package: value.exclude_newer_package,
2450 link_mode: value.link_mode,
2451 compile_bytecode: value.compile_bytecode,
2452 no_sources: value.no_sources,
2453 no_sources_package: value.no_sources_package,
2454 no_build: value.no_build,
2455 no_build_package: value.no_build_package,
2456 no_binary: value.no_binary,
2457 no_binary_package: value.no_binary_package,
2458 torch_backend: value.torch_backend,
2459 }
2460 }
2461}
2462
2463impl From<ToolOptionsWire> for ToolOptions {
2464 fn from(value: ToolOptionsWire) -> Self {
2465 let exclude_newer = value
2466 .exclude_newer
2467 .map(|exclude_newer| match exclude_newer {
2468 ExcludeNewerOverride::Disabled => ExcludeNewerOverride::Disabled,
2469 ExcludeNewerOverride::Enabled(exclude_newer) => {
2470 let exclude_newer = *exclude_newer;
2471 if let Some(span) = value.exclude_newer_span
2472 && exclude_newer.span().is_none()
2473 {
2474 ExcludeNewerValue::relative(span).into()
2475 } else {
2476 exclude_newer.into()
2477 }
2478 }
2479 });
2480
2481 Self {
2482 index: value.index,
2483 index_url: value.index_url,
2484 extra_index_url: value.extra_index_url,
2485 no_index: value.no_index,
2486 find_links: value.find_links,
2487 index_strategy: value.index_strategy,
2488 keyring_provider: value.keyring_provider,
2489 resolution: value.resolution,
2490 prerelease: value.prerelease,
2491 prerelease_package: value.prerelease_package,
2492 fork_strategy: value.fork_strategy,
2493 dependency_metadata: value.dependency_metadata,
2494 config_settings: value.config_settings,
2495 config_settings_package: value.config_settings_package,
2496 build_isolation: value.build_isolation,
2497 extra_build_dependencies: value.extra_build_dependencies,
2498 extra_build_variables: value.extra_build_variables,
2499 exclude_newer,
2500 exclude_newer_package: value.exclude_newer_package,
2501 link_mode: value.link_mode,
2502 compile_bytecode: value.compile_bytecode,
2503 no_sources: value.no_sources,
2504 no_sources_package: value.no_sources_package,
2505 no_build: value.no_build,
2506 no_build_package: value.no_build_package,
2507 no_binary: value.no_binary,
2508 no_binary_package: value.no_binary_package,
2509 torch_backend: value.torch_backend,
2510 }
2511 }
2512}
2513
2514impl From<ToolOptions> for ToolOptionsWire {
2515 fn from(value: ToolOptions) -> Self {
2516 let (exclude_newer, exclude_newer_span) = match &value.exclude_newer {
2517 Some(ExcludeNewerOverride::Disabled) => (Some(ExcludeNewerOverride::Disabled), None),
2518 Some(ExcludeNewerOverride::Enabled(value)) => match value.as_ref() {
2519 ExcludeNewerValue::Absolute(_) => {
2520 (Some(ExcludeNewerOverride::Enabled(value.clone())), None)
2521 }
2522 ExcludeNewerValue::Relative(span) => (
2523 Some(ExcludeNewerValue::absolute(value.timestamp()).into()),
2524 Some(*span),
2525 ),
2526 },
2527 None => (None, None),
2528 };
2529
2530 Self {
2531 index: value.index,
2532 index_url: value.index_url,
2533 extra_index_url: value.extra_index_url,
2534 no_index: value.no_index,
2535 find_links: value.find_links,
2536 index_strategy: value.index_strategy,
2537 keyring_provider: value.keyring_provider,
2538 resolution: value.resolution,
2539 prerelease: value.prerelease,
2540 prerelease_package: value.prerelease_package,
2541 fork_strategy: value.fork_strategy,
2542 dependency_metadata: value.dependency_metadata,
2543 config_settings: value.config_settings,
2544 config_settings_package: value.config_settings_package,
2545 build_isolation: value.build_isolation,
2546 extra_build_dependencies: value.extra_build_dependencies,
2547 extra_build_variables: value.extra_build_variables,
2548 exclude_newer,
2549 exclude_newer_span,
2550 exclude_newer_package: value.exclude_newer_package,
2551 link_mode: value.link_mode,
2552 compile_bytecode: value.compile_bytecode,
2553 no_sources: value.no_sources,
2554 no_sources_package: value.no_sources_package,
2555 no_build: value.no_build,
2556 no_build_package: value.no_build_package,
2557 no_binary: value.no_binary,
2558 no_binary_package: value.no_binary_package,
2559 torch_backend: value.torch_backend,
2560 }
2561 }
2562}
2563
2564impl From<ToolOptions> for ResolverInstallerOptions {
2565 fn from(value: ToolOptions) -> Self {
2566 Self {
2567 indexes: IndexOptions {
2568 index: value.index,
2569 index_url: value.index_url,
2570 extra_index_url: value.extra_index_url,
2571 no_index: value.no_index,
2572 find_links: value.find_links,
2573 },
2574 index_strategy: value.index_strategy,
2575 keyring_provider: value.keyring_provider,
2576 resolution: value.resolution,
2577 prerelease: value.prerelease,
2578 prerelease_package: value.prerelease_package,
2579 fork_strategy: value.fork_strategy,
2580 dependency_metadata: value.dependency_metadata,
2581 config_settings: value.config_settings,
2582 config_settings_package: value.config_settings_package,
2583 build_isolation: value.build_isolation,
2584 extra_build_dependencies: value.extra_build_dependencies,
2585 extra_build_variables: value.extra_build_variables,
2586 exclude_newer: value.exclude_newer,
2587 exclude_newer_package: value.exclude_newer_package,
2588 link_mode: value.link_mode,
2589 compile_bytecode: value.compile_bytecode,
2590 no_sources: value.no_sources,
2591 no_sources_package: value.no_sources_package,
2592 upgrade: None,
2593 reinstall: None,
2594 no_build: value.no_build,
2595 no_build_package: value.no_build_package,
2596 no_binary: value.no_binary,
2597 no_binary_package: value.no_binary_package,
2598 torch_backend: value.torch_backend,
2599 }
2600 }
2601}
2602
2603#[derive(Debug, Clone, Default, Deserialize)]
2606#[serde(rename_all = "kebab-case", deny_unknown_fields)]
2607struct OptionsWire {
2608 required_version: Option<RequiredVersion>,
2611 system_certs: Option<bool>,
2612 native_tls: Option<bool>,
2613 offline: Option<bool>,
2614 no_cache: Option<bool>,
2615 cache_dir: Option<PathBuf>,
2616 preview: Option<bool>,
2617 preview_features: Option<PreviewFeaturesOption>,
2618 python_preference: Option<PythonPreference>,
2619 python_downloads: Option<PythonDownloads>,
2620 concurrent_downloads: Option<NonZeroUsize>,
2621 concurrent_builds: Option<NonZeroUsize>,
2622 concurrent_installs: Option<NonZeroUsize>,
2623
2624 index: Option<Vec<Index>>,
2627 index_url: Option<PipIndex>,
2628 extra_index_url: Option<Vec<PipExtraIndex>>,
2629 no_index: Option<bool>,
2630 find_links: Option<Vec<PipFindLinks>>,
2631 index_strategy: Option<IndexStrategy>,
2632 keyring_provider: Option<KeyringProviderType>,
2633 http_proxy: Option<ProxyUrl>,
2634 https_proxy: Option<ProxyUrl>,
2635 no_proxy: Option<Vec<String>>,
2636 allow_insecure_host: Option<Vec<TrustedHost>>,
2637 resolution: Option<ResolutionMode>,
2638 prerelease: Option<PrereleaseMode>,
2639 prerelease_package: Option<PrereleasePackage>,
2640 fork_strategy: Option<ForkStrategy>,
2641 dependency_metadata: Option<Vec<StaticMetadata>>,
2642 config_settings: Option<ConfigSettings>,
2643 config_settings_package: Option<PackageConfigSettings>,
2644 no_build_isolation: Option<bool>,
2645 no_build_isolation_package: Option<Vec<PackageName>>,
2646 extra_build_dependencies: Option<ExtraBuildDependencies>,
2647 extra_build_variables: Option<ExtraBuildVariables>,
2648 exclude_newer: Option<ExcludeNewerOverride>,
2649 exclude_newer_package: Option<ExcludeNewerPackage>,
2650 link_mode: Option<LinkMode>,
2651 compile_bytecode: Option<bool>,
2652 no_sources: Option<bool>,
2653 no_sources_package: Option<Vec<PackageName>>,
2654 upgrade: Option<bool>,
2655 upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2656 reinstall: Option<bool>,
2657 reinstall_package: Option<Vec<PackageName>>,
2658 no_build: Option<bool>,
2659 no_build_package: Option<Vec<PackageName>>,
2660 no_binary: Option<bool>,
2661 no_binary_package: Option<Vec<PackageName>>,
2662 torch_backend: Option<TorchMode>,
2663
2664 python_install_mirror: Option<String>,
2667 pypy_install_mirror: Option<String>,
2668 graalpy_install_mirror: Option<String>,
2669 pyodide_install_mirror: Option<String>,
2670 python_downloads_json_url: Option<String>,
2671
2672 publish_url: Option<DisplaySafeUrl>,
2675 trusted_publishing: Option<TrustedPublishing>,
2676 check_url: Option<IndexUrl>,
2677
2678 add_bounds: Option<AddBoundsKind>,
2681
2682 audit: Option<AuditOptions>,
2683 pip: Option<PipOptions>,
2684 cache_keys: Option<Vec<CacheKey>>,
2685
2686 override_dependencies: Option<Vec<OverrideDependency>>,
2690 exclude_dependencies: Option<Vec<ExcludeDependency>>,
2691 constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2692 build_constraint_dependencies: Option<Vec<BuildConstraintDependency>>,
2693 environments: Option<SupportedEnvironments>,
2694 required_environments: Option<SupportedEnvironments>,
2695 minimum_libc_version: Option<MinimumLibcVersion>,
2696
2697 conflicts: Option<serde::de::IgnoredAny>,
2701 workspace: Option<serde::de::IgnoredAny>,
2702 sources: Option<serde::de::IgnoredAny>,
2703 managed: Option<serde::de::IgnoredAny>,
2704 r#package: Option<serde::de::IgnoredAny>,
2705 default_groups: Option<serde::de::IgnoredAny>,
2706 dependency_groups: Option<serde::de::IgnoredAny>,
2707 dev_dependencies: Option<serde::de::IgnoredAny>,
2708
2709 build_backend: Option<serde::de::IgnoredAny>,
2711}
2712
2713impl TryFrom<OptionsWire> for Options {
2714 type Error = &'static str;
2715
2716 #[allow(deprecated)]
2717 fn try_from(value: OptionsWire) -> Result<Self, Self::Error> {
2718 let OptionsWire {
2719 required_version,
2720 system_certs,
2721 native_tls,
2722 offline,
2723 no_cache,
2724 cache_dir,
2725 preview,
2726 preview_features,
2727 python_preference,
2728 python_downloads,
2729 python_install_mirror,
2730 pypy_install_mirror,
2731 graalpy_install_mirror,
2732 pyodide_install_mirror,
2733 python_downloads_json_url,
2734 concurrent_downloads,
2735 concurrent_builds,
2736 concurrent_installs,
2737 index,
2738 index_url,
2739 extra_index_url,
2740 no_index,
2741 find_links,
2742 index_strategy,
2743 keyring_provider,
2744 http_proxy,
2745 https_proxy,
2746 no_proxy,
2747 allow_insecure_host,
2748 resolution,
2749 prerelease,
2750 prerelease_package,
2751 fork_strategy,
2752 dependency_metadata,
2753 config_settings,
2754 config_settings_package,
2755 no_build_isolation,
2756 no_build_isolation_package,
2757 exclude_newer,
2758 exclude_newer_package,
2759 link_mode,
2760 compile_bytecode,
2761 no_sources,
2762 no_sources_package,
2763 upgrade,
2764 upgrade_package,
2765 reinstall,
2766 reinstall_package,
2767 no_build,
2768 no_build_package,
2769 no_binary,
2770 no_binary_package,
2771 torch_backend,
2772 audit,
2773 pip,
2774 cache_keys,
2775 override_dependencies,
2776 exclude_dependencies,
2777 constraint_dependencies,
2778 build_constraint_dependencies,
2779 environments,
2780 required_environments,
2781 minimum_libc_version,
2782 conflicts,
2783 publish_url,
2784 trusted_publishing,
2785 check_url,
2786 workspace,
2787 sources,
2788 default_groups,
2789 dependency_groups,
2790 extra_build_dependencies,
2791 extra_build_variables,
2792 dev_dependencies,
2793 managed,
2794 package,
2795 add_bounds: bounds,
2796 build_backend,
2798 } = value;
2799
2800 Ok(Self {
2801 globals: GlobalOptions {
2802 required_version,
2803 system_certs,
2804 native_tls,
2805 offline,
2806 no_cache,
2807 cache_dir,
2808 preview: PreviewOption::try_from(preview, preview_features)?,
2809 python_preference,
2810 python_downloads,
2811 concurrent_downloads,
2812 concurrent_builds,
2813 concurrent_installs,
2814 http_proxy,
2815 https_proxy,
2816 no_proxy,
2817 allow_insecure_host: allow_insecure_host.clone(),
2819 },
2820 top_level: ResolverInstallerSchema {
2821 index,
2822 index_url,
2823 extra_index_url,
2824 no_index,
2825 find_links,
2826 index_strategy,
2827 keyring_provider,
2828 resolution,
2829 prerelease,
2830 prerelease_package,
2831 fork_strategy,
2832 dependency_metadata,
2833 config_settings,
2834 config_settings_package,
2835 no_build_isolation,
2836 no_build_isolation_package,
2837 extra_build_dependencies,
2838 extra_build_variables,
2839 exclude_newer,
2840 exclude_newer_package,
2841 link_mode,
2842 compile_bytecode,
2843 no_sources,
2844 no_sources_package,
2845 upgrade,
2846 upgrade_package,
2847 reinstall,
2848 reinstall_package,
2849 no_build,
2850 no_build_package,
2851 no_binary,
2852 no_binary_package,
2853 torch_backend,
2854 },
2855 pip,
2856 cache_keys,
2857 build_backend,
2858 override_dependencies,
2859 exclude_dependencies,
2860 constraint_dependencies,
2861 build_constraint_dependencies,
2862 environments,
2863 required_environments,
2864 minimum_libc_version,
2865 install_mirrors: PythonInstallMirrors {
2866 python_install_mirror,
2867 pypy_install_mirror,
2868 graalpy_install_mirror,
2869 pyodide_install_mirror,
2870 python_downloads_json_url,
2871 },
2872 conflicts,
2873 publish: PublishOptions {
2874 publish_url,
2875 trusted_publishing,
2876 check_url,
2877 },
2878 add: AddOptions { add_bounds: bounds },
2879 audit,
2880 workspace,
2881 sources,
2882 dev_dependencies,
2883 default_groups,
2884 dependency_groups,
2885 managed,
2886 package,
2887 })
2888 }
2889}
2890
2891#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2892#[serde(rename_all = "kebab-case")]
2893#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2894pub struct PublishOptions {
2895 #[option(
2898 default = "\"https://upload.pypi.org/legacy/\"",
2899 value_type = "str",
2900 example = r#"
2901 publish-url = "https://test.pypi.org/legacy/"
2902 "#
2903 )]
2904 pub publish_url: Option<DisplaySafeUrl>,
2905
2906 #[option(
2913 default = "automatic",
2914 value_type = "str",
2915 example = r#"
2916 trusted-publishing = "always"
2917 "#
2918 )]
2919 pub trusted_publishing: Option<TrustedPublishing>,
2920
2921 #[option(
2935 default = "None",
2936 value_type = "str",
2937 example = r#"
2938 check-url = "https://test.pypi.org/simple"
2939 "#
2940 )]
2941 pub check_url: Option<IndexUrl>,
2942}
2943
2944#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2945#[serde(rename_all = "kebab-case")]
2946#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2947pub struct AddOptions {
2948 #[option(
2959 default = "\"lower\"",
2960 value_type = "str",
2961 example = r#"
2962 add-bounds = "major"
2963 "#,
2964 possible_values = true
2965 )]
2966 pub add_bounds: Option<AddBoundsKind>,
2967}
2968
2969#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2970#[serde(rename_all = "kebab-case")]
2971#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2972pub struct AuditOptions {
2973 #[option(
2975 default = "false",
2976 value_type = "bool",
2977 example = r#"
2978 malware-check = true
2979 "#
2980 )]
2981 pub malware_check: Option<bool>,
2982
2983 #[option(
2985 default = "\"https://api.osv.dev/\"",
2986 value_type = "str",
2987 example = r#"
2988 malware-check-url = "https://example.com"
2989 "#
2990 )]
2991 pub malware_check_url: Option<DisplaySafeUrl>,
2992
2993 #[option(
2998 default = "[]",
2999 value_type = "list[str]",
3000 example = r#"
3001 ignore = ["PYSEC-2022-43017", "GHSA-5239-wwwm-4pmq"]
3002 "#
3003 )]
3004 pub ignore: Option<Vec<String>>,
3005
3006 #[option(
3012 default = "[]",
3013 value_type = "list[str]",
3014 example = r#"
3015 ignore-until-fixed = ["PYSEC-2022-43017"]
3016 "#
3017 )]
3018 pub ignore_until_fixed: Option<Vec<String>>,
3019}
3020
3021#[derive(Debug, Clone)]
3022pub struct MalwareCheckSettings {
3023 pub enabled: bool,
3025 pub malware_check_url: Option<DisplaySafeUrl>,
3027}
3028
3029impl MalwareCheckSettings {
3030 pub fn resolve(
3031 filesystem: Option<&FilesystemOptions>,
3032 environment: &EnvironmentOptions,
3033 ) -> Self {
3034 let audit = filesystem.and_then(|options| options.audit.as_ref());
3035
3036 Self {
3037 enabled: environment
3038 .malware_check
3039 .value
3040 .or(audit.and_then(|audit| audit.malware_check))
3041 .unwrap_or_default(),
3042 malware_check_url: environment
3043 .malware_check_url
3044 .clone()
3045 .or_else(|| audit.and_then(|audit| audit.malware_check_url.clone())),
3046 }
3047 }
3048}
3049
3050#[derive(Debug, Clone)]
3052#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
3053#[cfg_attr(feature = "schemars", schemars(untagged))]
3054pub enum PreviewFeaturesOption {
3055 Toggle(bool),
3056 Features(Vec<MaybePreviewFeature>),
3057}
3058
3059struct PreviewFeaturesVisitor;
3061
3062impl<'de> Visitor<'de> for PreviewFeaturesVisitor {
3063 type Value = PreviewFeaturesOption;
3064
3065 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
3066 formatter.write_str("a boolean or a list of preview feature names")
3067 }
3068
3069 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
3070 where
3071 E: Error,
3072 {
3073 Ok(PreviewFeaturesOption::Toggle(value))
3074 }
3075
3076 fn visit_seq<S>(self, sequence: S) -> Result<Self::Value, S::Error>
3077 where
3078 S: SeqAccess<'de>,
3079 {
3080 Vec::deserialize(SeqAccessDeserializer::new(sequence)).map(PreviewFeaturesOption::Features)
3081 }
3082}
3083
3084impl<'de> Deserialize<'de> for PreviewFeaturesOption {
3085 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
3086 where
3087 D: Deserializer<'de>,
3088 {
3089 deserializer.deserialize_any(PreviewFeaturesVisitor)
3090 }
3091}
3092
3093#[expect(
3094 dead_code,
3095 reason = "Fields are only used by the OptionsMetadata and JsonSchema derives"
3096)]
3097#[derive(OptionsMetadata)]
3098#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
3099#[cfg_attr(feature = "schemars", schemars(rename_all = "kebab-case"))]
3100struct PreviewOptionsDefinition {
3101 #[deprecated(note = "use `preview-features` instead")]
3107 preview: Option<bool>,
3108 #[option(
3112 default = "false",
3113 value_type = "bool | list[str]",
3114 example = r#"
3115 preview-features = true
3116 # or
3117 preview-features = ["json-output"]
3118 "#
3119 )]
3120 preview_features: Option<PreviewFeaturesOption>,
3121}
3122
3123#[derive(Debug, Clone)]
3125pub enum PreviewOption {
3126 Preview(bool),
3128 PreviewFeatures(PreviewFeaturesOption),
3130}
3131
3132impl uv_options_metadata::OptionsMetadata for PreviewOption {
3133 fn record(visit: &mut dyn uv_options_metadata::Visit) {
3134 <PreviewOptionsDefinition as uv_options_metadata::OptionsMetadata>::record(visit);
3135 }
3136}
3137
3138#[cfg(feature = "schemars")]
3139struct ConflictingPreviewOptions;
3140
3141#[cfg(feature = "schemars")]
3142impl schemars::JsonSchema for ConflictingPreviewOptions {
3143 fn schema_name() -> Cow<'static, str> {
3144 Cow::Borrowed("ConflictingPreviewOptions")
3145 }
3146
3147 fn json_schema(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3148 schemars::json_schema!({
3149 "type": "object",
3150 "properties": {
3151 "preview": {},
3152 "preview-features": {},
3153 },
3154 "required": ["preview", "preview-features"],
3155 })
3156 }
3157}
3158
3159#[cfg(feature = "schemars")]
3160impl schemars::JsonSchema for PreviewOption {
3161 fn schema_name() -> Cow<'static, str> {
3162 Cow::Borrowed("PreviewOption")
3163 }
3164
3165 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3166 let mut schema = <PreviewOptionsDefinition as schemars::JsonSchema>::json_schema(generator);
3167 schema.insert(
3170 "not".to_string(),
3171 generator
3172 .subschema_for::<ConflictingPreviewOptions>()
3173 .into(),
3174 );
3175 schema
3176 }
3177}
3178
3179impl PreviewOption {
3180 fn try_from(
3181 preview: Option<bool>,
3182 preview_features: Option<PreviewFeaturesOption>,
3183 ) -> Result<Option<Self>, &'static str> {
3184 match (preview, preview_features) {
3185 (Some(_), Some(_)) => Err("cannot specify both `preview` and `preview-features`"),
3186 (Some(b), None) => Ok(Some(Self::Preview(b))),
3187 (None, Some(features)) => Ok(Some(Self::PreviewFeatures(features))),
3188 (None, None) => Ok(None),
3189 }
3190 }
3191
3192 pub fn resolve(&self) -> Preview {
3194 use PreviewFeaturesOption::{Features, Toggle};
3195
3196 match self {
3197 Self::Preview(false) | Self::PreviewFeatures(Toggle(false)) => Preview::default(),
3198 Self::Preview(true) | Self::PreviewFeatures(Toggle(true)) => Preview::all(),
3199 Self::PreviewFeatures(Features(features)) => Preview::from_feature_names(features),
3200 }
3201 }
3202}