Skip to main content

uv_settings/
settings.rs

1use std::{fmt::Debug, num::NonZeroUsize, path::Path, path::PathBuf};
2
3use serde::{Deserialize, Serialize};
4
5use uv_cache_info::CacheKey;
6use uv_configuration::{
7    BuildIsolation, IndexStrategy, KeyringProviderType, PackageNameSpecifier, ProxyUrl, Reinstall,
8    RequiredVersion, TargetTriple, TrustedHost, TrustedPublishing, Upgrade,
9};
10use uv_distribution_types::{
11    ConfigSettings, ExtraBuildVariables, Index, IndexUrl, IndexUrlError, Origin,
12    PackageConfigSettings, PipExtraIndex, PipFindLinks, PipIndex, StaticMetadata,
13};
14use uv_install_wheel::LinkMode;
15use uv_macros::{CombineOptions, OptionsMetadata};
16use uv_normalize::{ExtraName, PackageName, PipGroupName};
17use uv_pep508::Requirement;
18use uv_pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
19use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
20use uv_redacted::DisplaySafeUrl;
21use uv_resolver::{
22    AnnotationStyle, ExcludeNewer, ExcludeNewerPackage, ExcludeNewerSpan, ExcludeNewerValue,
23    ForkStrategy, PrereleaseMode, ResolutionMode, serialize_exclude_newer_package_with_spans,
24};
25use uv_torch::TorchMode;
26use uv_workspace::pyproject::ExtraBuildDependencies;
27use uv_workspace::pyproject_mut::AddBoundsKind;
28
29/// A `pyproject.toml` with an (optional) `[tool.uv]` section.
30#[allow(dead_code)]
31#[derive(Debug, Clone, Default, Deserialize)]
32pub(crate) struct PyProjectToml {
33    pub(crate) tool: Option<Tools>,
34}
35
36/// A `[tool]` section.
37#[allow(dead_code)]
38#[derive(Debug, Clone, Default, Deserialize)]
39pub(crate) struct Tools {
40    pub(crate) uv: Option<Options>,
41}
42
43/// A `[tool.uv]` section.
44#[allow(dead_code)]
45#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
46#[serde(from = "OptionsWire", rename_all = "kebab-case")]
47#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
48#[cfg_attr(feature = "schemars", schemars(!from))]
49pub struct Options {
50    #[serde(flatten)]
51    pub globals: GlobalOptions,
52
53    #[serde(flatten)]
54    pub top_level: ResolverInstallerSchema,
55
56    #[serde(flatten)]
57    pub install_mirrors: PythonInstallMirrors,
58
59    #[serde(flatten)]
60    pub publish: PublishOptions,
61
62    #[serde(flatten)]
63    pub add: AddOptions,
64
65    #[option_group]
66    pub audit: Option<AuditOptions>,
67
68    #[option_group]
69    pub pip: Option<PipOptions>,
70
71    /// The keys to consider when caching builds for the project.
72    ///
73    /// Cache keys enable you to specify the files or directories that should trigger a rebuild when
74    /// modified. By default, uv will rebuild a project whenever the `pyproject.toml`, `setup.py`,
75    /// or `setup.cfg` files in the project directory are modified, or if a `src` directory is
76    /// added or removed, i.e.:
77    ///
78    /// ```toml
79    /// cache-keys = [{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }, { dir = "src" }]
80    /// ```
81    ///
82    /// As an example: if a project uses dynamic metadata to read its dependencies from a
83    /// `requirements.txt` file, you can specify `cache-keys = [{ file = "requirements.txt" }, { file = "pyproject.toml" }]`
84    /// to ensure that the project is rebuilt whenever the `requirements.txt` file is modified (in
85    /// addition to watching the `pyproject.toml`).
86    ///
87    /// Globs are supported, following the syntax of the [`glob`](https://docs.rs/glob/0.3.1/glob/struct.Pattern.html)
88    /// crate. For example, to invalidate the cache whenever a `.toml` file in the project directory
89    /// or any of its subdirectories is modified, you can specify `cache-keys = [{ file = "**/*.toml" }]`.
90    /// Note that the use of globs can be expensive, as uv may need to walk the filesystem to
91    /// determine whether any files have changed.
92    ///
93    /// Cache keys can also include version control information. For example, if a project uses
94    /// `setuptools_scm` to read its version from a Git commit, you can specify `cache-keys = [{ git = { commit = true }, { file = "pyproject.toml" }]`
95    /// to include the current Git commit hash in the cache key (in addition to the
96    /// `pyproject.toml`). Git tags are also supported via `cache-keys = [{ git = { commit = true, tags = true } }]`.
97    ///
98    /// Cache keys can also include environment variables. For example, if a project relies on
99    /// `MACOSX_DEPLOYMENT_TARGET` or other environment variables to determine its behavior, you can
100    /// specify `cache-keys = [{ env = "MACOSX_DEPLOYMENT_TARGET" }]` to invalidate the cache
101    /// whenever the environment variable changes.
102    ///
103    /// Cache keys only affect the project defined by the `pyproject.toml` in which they're
104    /// specified (as opposed to, e.g., affecting all members in a workspace), and all paths and
105    /// globs are interpreted as relative to the project directory.
106    #[option(
107        default = r#"[{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }]"#,
108        value_type = "list[dict]",
109        example = r#"
110            cache-keys = [{ file = "pyproject.toml" }, { file = "requirements.txt" }, { git = { commit = true } }]
111        "#
112    )]
113    pub cache_keys: Option<Vec<CacheKey>>,
114
115    // NOTE(charlie): These fields are shared with `ToolUv` in
116    // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
117    // They're respected in both `pyproject.toml` and `uv.toml` files.
118    #[cfg_attr(feature = "schemars", schemars(skip))]
119    pub override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
120
121    #[cfg_attr(feature = "schemars", schemars(skip))]
122    pub exclude_dependencies: Option<Vec<uv_normalize::PackageName>>,
123
124    #[cfg_attr(feature = "schemars", schemars(skip))]
125    pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
126
127    #[cfg_attr(feature = "schemars", schemars(skip))]
128    pub build_constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
129
130    #[cfg_attr(feature = "schemars", schemars(skip))]
131    pub environments: Option<SupportedEnvironments>,
132
133    #[cfg_attr(feature = "schemars", schemars(skip))]
134    pub required_environments: Option<SupportedEnvironments>,
135
136    // NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
137    // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
138    // They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
139    #[cfg_attr(feature = "schemars", schemars(skip))]
140    pub conflicts: Option<serde::de::IgnoredAny>,
141
142    #[cfg_attr(feature = "schemars", schemars(skip))]
143    pub workspace: Option<serde::de::IgnoredAny>,
144
145    #[cfg_attr(feature = "schemars", schemars(skip))]
146    pub sources: Option<serde::de::IgnoredAny>,
147
148    #[cfg_attr(feature = "schemars", schemars(skip))]
149    pub dev_dependencies: Option<serde::de::IgnoredAny>,
150
151    #[cfg_attr(feature = "schemars", schemars(skip))]
152    pub default_groups: Option<serde::de::IgnoredAny>,
153
154    #[cfg_attr(feature = "schemars", schemars(skip))]
155    pub dependency_groups: Option<serde::de::IgnoredAny>,
156
157    #[cfg_attr(feature = "schemars", schemars(skip))]
158    pub managed: Option<serde::de::IgnoredAny>,
159
160    #[cfg_attr(feature = "schemars", schemars(skip))]
161    pub r#package: Option<serde::de::IgnoredAny>,
162
163    #[cfg_attr(feature = "schemars", schemars(skip))]
164    pub build_backend: Option<serde::de::IgnoredAny>,
165}
166
167impl Options {
168    /// Construct an [`Options`] with the given global and top-level settings.
169    pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerSchema) -> Self {
170        Self {
171            globals,
172            top_level,
173            ..Default::default()
174        }
175    }
176
177    /// Set the [`Origin`] on all indexes without an existing origin.
178    #[must_use]
179    pub fn with_origin(mut self, origin: Origin) -> Self {
180        if let Some(indexes) = &mut self.top_level.index {
181            for index in indexes {
182                index.origin.get_or_insert(origin);
183            }
184        }
185        if let Some(index_url) = &mut self.top_level.index_url {
186            index_url.try_set_origin(origin);
187        }
188        if let Some(extra_index_urls) = &mut self.top_level.extra_index_url {
189            for index_url in extra_index_urls {
190                index_url.try_set_origin(origin);
191            }
192        }
193        if let Some(pip) = &mut self.pip {
194            if let Some(indexes) = &mut pip.index {
195                for index in indexes {
196                    index.origin.get_or_insert(origin);
197                }
198            }
199            if let Some(index_url) = &mut pip.index_url {
200                index_url.try_set_origin(origin);
201            }
202            if let Some(extra_index_urls) = &mut pip.extra_index_url {
203                for index_url in extra_index_urls {
204                    index_url.try_set_origin(origin);
205                }
206            }
207        }
208        self
209    }
210
211    /// Resolve the [`Options`] relative to the given root directory.
212    pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
213        Ok(Self {
214            top_level: self.top_level.relative_to(root_dir)?,
215            pip: self.pip.map(|pip| pip.relative_to(root_dir)).transpose()?,
216            ..self
217        })
218    }
219}
220
221/// Global settings, relevant to all invocations.
222#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
223#[serde(rename_all = "kebab-case")]
224#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
225pub struct GlobalOptions {
226    /// Enforce a requirement on the version of uv.
227    ///
228    /// If the version of uv does not meet the requirement at runtime, uv will exit
229    /// with an error.
230    ///
231    /// Accepts a [PEP 440](https://peps.python.org/pep-0440/) specifier, like `==0.5.0` or `>=0.5.0`.
232    #[option(
233        default = "null",
234        value_type = "str",
235        example = r#"
236            required-version = ">=0.5.0"
237        "#
238    )]
239    pub required_version: Option<RequiredVersion>,
240    /// Whether to load TLS certificates from the platform's native certificate store.
241    ///
242    /// By default, uv uses bundled Mozilla root certificates. When enabled, this loads
243    /// certificates from the platform's native certificate store instead.
244    #[option(
245        default = "false",
246        value_type = "bool",
247        uv_toml_only = true,
248        example = r#"
249            system-certs = true
250        "#
251    )]
252    pub system_certs: Option<bool>,
253    /// Whether to load TLS certificates from the platform's native certificate store.
254    ///
255    /// By default, uv uses bundled Mozilla root certificates. When enabled, this loads
256    /// certificates from the platform's native certificate store instead.
257    ///
258    /// (Deprecated: use `system-certs` instead.)
259    #[deprecated(note = "use `system-certs` instead")]
260    #[option(
261        default = "false",
262        value_type = "bool",
263        uv_toml_only = true,
264        example = r#"
265            native-tls = true
266        "#
267    )]
268    pub native_tls: Option<bool>,
269    /// Disable network access, relying only on locally cached data and locally available files.
270    #[option(
271        default = "false",
272        value_type = "bool",
273        example = r#"
274            offline = true
275        "#
276    )]
277    pub offline: Option<bool>,
278    /// Avoid reading from or writing to the cache, instead using a temporary directory for the
279    /// duration of the operation.
280    #[option(
281        default = "false",
282        value_type = "bool",
283        example = r#"
284            no-cache = true
285        "#
286    )]
287    pub no_cache: Option<bool>,
288    /// Path to the cache directory.
289    ///
290    /// Defaults to `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` on Linux and macOS, and
291    /// `%LOCALAPPDATA%\uv\cache` on Windows.
292    #[option(
293        default = "None",
294        value_type = "str",
295        uv_toml_only = true,
296        example = r#"
297            cache-dir = "./.uv_cache"
298        "#
299    )]
300    pub cache_dir: Option<PathBuf>,
301    /// Whether to enable experimental, preview features.
302    #[option(
303        default = "false",
304        value_type = "bool",
305        example = r#"
306            preview = true
307        "#
308    )]
309    pub preview: Option<bool>,
310    /// Whether to prefer using Python installations that are already present on the system, or
311    /// those that are downloaded and installed by uv.
312    #[option(
313        default = "\"managed\"",
314        value_type = "str",
315        example = r#"
316            python-preference = "managed"
317        "#,
318        possible_values = true
319    )]
320    pub python_preference: Option<PythonPreference>,
321    /// Whether to allow Python downloads.
322    #[option(
323        default = "\"automatic\"",
324        value_type = "str",
325        example = r#"
326            python-downloads = "manual"
327        "#,
328        possible_values = true
329    )]
330    pub python_downloads: Option<PythonDownloads>,
331    /// The maximum number of in-flight concurrent downloads that uv will perform at any given
332    /// time.
333    #[option(
334        default = "50",
335        value_type = "int",
336        example = r#"
337            concurrent-downloads = 4
338        "#
339    )]
340    pub concurrent_downloads: Option<NonZeroUsize>,
341    /// The maximum number of source distributions that uv will build concurrently at any given
342    /// time.
343    ///
344    /// Defaults to the number of available CPU cores.
345    #[option(
346        default = "None",
347        value_type = "int",
348        example = r#"
349            concurrent-builds = 4
350        "#
351    )]
352    pub concurrent_builds: Option<NonZeroUsize>,
353    /// The number of threads used when installing and unzipping packages.
354    ///
355    /// Defaults to the number of available CPU cores.
356    #[option(
357        default = "None",
358        value_type = "int",
359        example = r#"
360            concurrent-installs = 4
361        "#
362    )]
363    pub concurrent_installs: Option<NonZeroUsize>,
364    /// The URL of the HTTP proxy to use.
365    #[option(
366        default = "None",
367        value_type = "str",
368        uv_toml_only = true,
369        example = r#"
370            http-proxy = "http://proxy.example.com"
371        "#
372    )]
373    pub http_proxy: Option<ProxyUrl>,
374    /// The URL of the HTTPS proxy to use.
375    #[option(
376        default = "None",
377        value_type = "str",
378        uv_toml_only = true,
379        example = r#"
380            https-proxy = "https://proxy.example.com"
381        "#
382    )]
383    pub https_proxy: Option<ProxyUrl>,
384    /// A list of hosts to exclude from proxying.
385    #[option(
386        default = "None",
387        value_type = "list[str]",
388        uv_toml_only = true,
389        example = r#"
390            no-proxy = ["localhost", "127.0.0.1"]
391        "#
392    )]
393    pub no_proxy: Option<Vec<String>>,
394    /// Allow insecure connections to host.
395    ///
396    /// Expects to receive either a hostname (e.g., `localhost`), a host-port pair (e.g.,
397    /// `localhost:8080`), or a URL (e.g., `https://localhost`).
398    ///
399    /// WARNING: Hosts included in this list will not be verified against the system's certificate
400    /// store. Only use `--allow-insecure-host` in a secure network with verified sources, as it
401    /// bypasses SSL verification and could expose you to MITM attacks.
402    #[option(
403        default = "[]",
404        value_type = "list[str]",
405        example = r#"
406            allow-insecure-host = ["localhost:8080"]
407        "#
408    )]
409    pub allow_insecure_host: Option<Vec<TrustedHost>>,
410}
411
412/// Settings relevant to all installer operations.
413#[derive(Debug, Clone, Default, CombineOptions)]
414pub struct InstallerOptions {
415    pub index: Option<Vec<Index>>,
416    pub index_url: Option<PipIndex>,
417    pub extra_index_url: Option<Vec<PipExtraIndex>>,
418    pub no_index: Option<bool>,
419    pub find_links: Option<Vec<PipFindLinks>>,
420    pub index_strategy: Option<IndexStrategy>,
421    pub keyring_provider: Option<KeyringProviderType>,
422    pub config_settings: Option<ConfigSettings>,
423    pub exclude_newer: Option<ExcludeNewerValue>,
424    pub link_mode: Option<LinkMode>,
425    pub compile_bytecode: Option<bool>,
426    pub reinstall: Option<Reinstall>,
427    pub build_isolation: Option<BuildIsolation>,
428    pub no_build: Option<bool>,
429    pub no_build_package: Option<Vec<PackageName>>,
430    pub no_binary: Option<bool>,
431    pub no_binary_package: Option<Vec<PackageName>>,
432    pub no_sources: Option<bool>,
433    pub no_sources_package: Option<Vec<PackageName>>,
434}
435
436/// Settings relevant to all resolver operations.
437#[derive(Debug, Clone, Default, CombineOptions)]
438pub struct ResolverOptions {
439    pub index: Option<Vec<Index>>,
440    pub index_url: Option<PipIndex>,
441    pub extra_index_url: Option<Vec<PipExtraIndex>>,
442    pub no_index: Option<bool>,
443    pub find_links: Option<Vec<PipFindLinks>>,
444    pub index_strategy: Option<IndexStrategy>,
445    pub keyring_provider: Option<KeyringProviderType>,
446    pub resolution: Option<ResolutionMode>,
447    pub prerelease: Option<PrereleaseMode>,
448    pub fork_strategy: Option<ForkStrategy>,
449    pub dependency_metadata: Option<Vec<StaticMetadata>>,
450    pub config_settings: Option<ConfigSettings>,
451    pub config_settings_package: Option<PackageConfigSettings>,
452    pub exclude_newer: ExcludeNewer,
453    pub link_mode: Option<LinkMode>,
454    pub torch_backend: Option<TorchMode>,
455    pub upgrade: Option<Upgrade>,
456    pub build_isolation: Option<BuildIsolation>,
457    pub no_build: Option<bool>,
458    pub no_build_package: Option<Vec<PackageName>>,
459    pub no_binary: Option<bool>,
460    pub no_binary_package: Option<Vec<PackageName>>,
461    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
462    pub extra_build_variables: Option<ExtraBuildVariables>,
463    pub no_sources: Option<bool>,
464    pub no_sources_package: Option<Vec<PackageName>>,
465}
466
467/// Shared settings, relevant to all operations that must resolve and install dependencies. The
468/// union of [`InstallerOptions`] and [`ResolverOptions`].
469#[derive(Debug, Clone, Default, CombineOptions)]
470pub struct ResolverInstallerOptions {
471    pub index: Option<Vec<Index>>,
472    pub index_url: Option<PipIndex>,
473    pub extra_index_url: Option<Vec<PipExtraIndex>>,
474    pub no_index: Option<bool>,
475    pub find_links: Option<Vec<PipFindLinks>>,
476    pub index_strategy: Option<IndexStrategy>,
477    pub keyring_provider: Option<KeyringProviderType>,
478    pub resolution: Option<ResolutionMode>,
479    pub prerelease: Option<PrereleaseMode>,
480    pub fork_strategy: Option<ForkStrategy>,
481    pub dependency_metadata: Option<Vec<StaticMetadata>>,
482    pub config_settings: Option<ConfigSettings>,
483    pub config_settings_package: Option<PackageConfigSettings>,
484    pub build_isolation: Option<BuildIsolation>,
485    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
486    pub extra_build_variables: Option<ExtraBuildVariables>,
487    pub exclude_newer: Option<ExcludeNewerValue>,
488    pub exclude_newer_package: Option<ExcludeNewerPackage>,
489    pub link_mode: Option<LinkMode>,
490    pub torch_backend: Option<TorchMode>,
491    pub compile_bytecode: Option<bool>,
492    pub no_sources: Option<bool>,
493    pub no_sources_package: Option<Vec<PackageName>>,
494    pub upgrade: Option<Upgrade>,
495    pub reinstall: Option<Reinstall>,
496    pub no_build: Option<bool>,
497    pub no_build_package: Option<Vec<PackageName>>,
498    pub no_binary: Option<bool>,
499    pub no_binary_package: Option<Vec<PackageName>>,
500}
501
502impl ResolverInstallerOptions {
503    /// Recompute any relative exclude-newer values against the current time.
504    #[must_use]
505    pub fn recompute_exclude_newer(mut self) -> Self {
506        let exclude_newer = ExcludeNewer::new(
507            self.exclude_newer.take(),
508            self.exclude_newer_package.take().unwrap_or_default(),
509        )
510        .recompute();
511        self.exclude_newer = exclude_newer.global;
512        self.exclude_newer_package = if exclude_newer.package.is_empty() {
513            None
514        } else {
515            Some(exclude_newer.package)
516        };
517        self
518    }
519}
520
521impl From<ResolverInstallerSchema> for ResolverInstallerOptions {
522    fn from(value: ResolverInstallerSchema) -> Self {
523        let ResolverInstallerSchema {
524            index,
525            index_url,
526            extra_index_url,
527            no_index,
528            find_links,
529            index_strategy,
530            keyring_provider,
531            resolution,
532            prerelease,
533            fork_strategy,
534            dependency_metadata,
535            config_settings,
536            config_settings_package,
537            no_build_isolation,
538            no_build_isolation_package,
539            extra_build_dependencies,
540            extra_build_variables,
541            exclude_newer,
542            exclude_newer_package,
543            link_mode,
544            torch_backend,
545            compile_bytecode,
546            no_sources,
547            no_sources_package,
548            upgrade,
549            upgrade_package,
550            reinstall,
551            reinstall_package,
552            no_build,
553            no_build_package,
554            no_binary,
555            no_binary_package,
556        } = value;
557        Self {
558            index,
559            index_url,
560            extra_index_url,
561            no_index,
562            find_links,
563            index_strategy,
564            keyring_provider,
565            resolution,
566            prerelease,
567            fork_strategy,
568            dependency_metadata,
569            config_settings,
570            config_settings_package,
571            build_isolation: BuildIsolation::from_args(
572                no_build_isolation,
573                no_build_isolation_package.into_iter().flatten().collect(),
574            ),
575            extra_build_dependencies,
576            extra_build_variables,
577            exclude_newer,
578            exclude_newer_package,
579            link_mode,
580            torch_backend,
581            compile_bytecode,
582            no_sources,
583            no_sources_package,
584            upgrade: Upgrade::from_args(
585                upgrade,
586                upgrade_package
587                    .into_iter()
588                    .flatten()
589                    .map(Into::into)
590                    .collect(),
591                Vec::new(),
592            ),
593            reinstall: Reinstall::from_args(reinstall, reinstall_package.unwrap_or_default()),
594            no_build,
595            no_build_package,
596            no_binary,
597            no_binary_package,
598        }
599    }
600}
601
602impl ResolverInstallerSchema {
603    /// Resolve the [`ResolverInstallerSchema`] relative to the given root directory.
604    pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
605        Ok(Self {
606            index: self
607                .index
608                .map(|index| {
609                    index
610                        .into_iter()
611                        .map(|index| index.relative_to(root_dir))
612                        .collect::<Result<Vec<_>, _>>()
613                })
614                .transpose()?,
615            index_url: self
616                .index_url
617                .map(|index_url| index_url.relative_to(root_dir))
618                .transpose()?,
619            extra_index_url: self
620                .extra_index_url
621                .map(|extra_index_url| {
622                    extra_index_url
623                        .into_iter()
624                        .map(|extra_index_url| extra_index_url.relative_to(root_dir))
625                        .collect::<Result<Vec<_>, _>>()
626                })
627                .transpose()?,
628            find_links: self
629                .find_links
630                .map(|find_links| {
631                    find_links
632                        .into_iter()
633                        .map(|find_link| find_link.relative_to(root_dir))
634                        .collect::<Result<Vec<_>, _>>()
635                })
636                .transpose()?,
637            ..self
638        })
639    }
640}
641
642/// The JSON schema for the `[tool.uv]` section of a `pyproject.toml` file.
643#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
644#[serde(rename_all = "kebab-case")]
645#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
646pub struct ResolverInstallerSchema {
647    /// The package indexes to use when resolving dependencies.
648    ///
649    /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
650    /// (the simple repository API), or a local directory laid out in the same format.
651    ///
652    /// Indexes are considered in the order in which they're defined, such that the first-defined
653    /// index has the highest priority. Further, the indexes provided by this setting are given
654    /// higher priority than any indexes specified via [`index_url`](#index-url) or
655    /// [`extra_index_url`](#extra-index-url). uv will only consider the first index that contains
656    /// a given package, unless an alternative [index strategy](#index-strategy) is specified.
657    ///
658    /// If an index is marked as `explicit = true`, it will be used exclusively for those
659    /// dependencies that select it explicitly via `[tool.uv.sources]`, as in:
660    ///
661    /// ```toml
662    /// [[tool.uv.index]]
663    /// name = "pytorch"
664    /// url = "https://download.pytorch.org/whl/cu121"
665    /// explicit = true
666    ///
667    /// [tool.uv.sources]
668    /// torch = { index = "pytorch" }
669    /// ```
670    ///
671    /// If an index is marked as `default = true`, it will be moved to the end of the prioritized list, such that it is
672    /// given the lowest priority when resolving packages. Additionally, marking an index as default will disable the
673    /// PyPI default index.
674    #[option(
675        default = "\"[]\"",
676        value_type = "dict",
677        example = r#"
678            [[tool.uv.index]]
679            name = "pytorch"
680            url = "https://download.pytorch.org/whl/cu121"
681        "#
682    )]
683    pub index: Option<Vec<Index>>,
684    /// The URL of the Python package index (by default: <https://pypi.org/simple>).
685    ///
686    /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
687    /// (the simple repository API), or a local directory laid out in the same format.
688    ///
689    /// The index provided by this setting is given lower priority than any indexes specified via
690    /// [`extra_index_url`](#extra-index-url) or [`index`](#index).
691    ///
692    /// (Deprecated: use `index` instead.)
693    #[option(
694        default = "\"https://pypi.org/simple\"",
695        value_type = "str",
696        example = r#"
697            index-url = "https://test.pypi.org/simple"
698        "#
699    )]
700    pub index_url: Option<PipIndex>,
701    /// Extra URLs of package indexes to use, in addition to `--index-url`.
702    ///
703    /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
704    /// (the simple repository API), or a local directory laid out in the same format.
705    ///
706    /// All indexes provided via this flag take priority over the index specified by
707    /// [`index_url`](#index-url) or [`index`](#index) with `default = true`. When multiple indexes
708    /// are provided, earlier values take priority.
709    ///
710    /// To control uv's resolution strategy when multiple indexes are present, see
711    /// [`index_strategy`](#index-strategy).
712    ///
713    /// (Deprecated: use `index` instead.)
714    #[option(
715        default = "[]",
716        value_type = "list[str]",
717        example = r#"
718            extra-index-url = ["https://download.pytorch.org/whl/cpu"]
719        "#
720    )]
721    pub extra_index_url: Option<Vec<PipExtraIndex>>,
722    /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and
723    /// those provided via `--find-links`.
724    #[option(
725        default = "false",
726        value_type = "bool",
727        example = r#"
728            no-index = true
729        "#
730    )]
731    pub no_index: Option<bool>,
732    /// Locations to search for candidate distributions, in addition to those found in the registry
733    /// indexes.
734    ///
735    /// If a path, the target must be a directory that contains packages as wheel files (`.whl`) or
736    /// source distributions (e.g., `.tar.gz` or `.zip`) at the top level.
737    ///
738    /// If a URL, the page must contain a flat list of links to package files adhering to the
739    /// formats described above.
740    #[option(
741        default = "[]",
742        value_type = "list[str]",
743        example = r#"
744            find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
745        "#
746    )]
747    pub find_links: Option<Vec<PipFindLinks>>,
748    /// The strategy to use when resolving against multiple index URLs.
749    ///
750    /// By default, uv will stop at the first index on which a given package is available, and
751    /// limit resolutions to those present on that first index (`first-index`). This prevents
752    /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the
753    /// same name to an alternate index.
754    #[option(
755        default = "\"first-index\"",
756        value_type = "str",
757        example = r#"
758            index-strategy = "unsafe-best-match"
759        "#,
760        possible_values = true
761    )]
762    pub index_strategy: Option<IndexStrategy>,
763    /// Attempt to use `keyring` for authentication for index URLs.
764    ///
765    /// At present, only `--keyring-provider subprocess` is supported, which configures uv to
766    /// use the `keyring` CLI to handle authentication.
767    #[option(
768        default = "\"disabled\"",
769        value_type = "str",
770        example = r#"
771            keyring-provider = "subprocess"
772        "#
773    )]
774    pub keyring_provider: Option<KeyringProviderType>,
775    /// The strategy to use when selecting between the different compatible versions for a given
776    /// package requirement.
777    ///
778    /// By default, uv will use the latest compatible version of each package (`highest`).
779    #[option(
780        default = "\"highest\"",
781        value_type = "str",
782        example = r#"
783            resolution = "lowest-direct"
784        "#,
785        possible_values = true
786    )]
787    pub resolution: Option<ResolutionMode>,
788    /// The strategy to use when considering pre-release versions.
789    ///
790    /// By default, uv will accept pre-releases for packages that _only_ publish pre-releases,
791    /// along with first-party requirements that contain an explicit pre-release marker in the
792    /// declared specifiers (`if-necessary-or-explicit`).
793    #[option(
794        default = "\"if-necessary-or-explicit\"",
795        value_type = "str",
796        example = r#"
797            prerelease = "allow"
798        "#,
799        possible_values = true
800    )]
801    pub prerelease: Option<PrereleaseMode>,
802    /// The strategy to use when selecting multiple versions of a given package across Python
803    /// versions and platforms.
804    ///
805    /// By default, uv will optimize for selecting the latest version of each package for each
806    /// supported Python version (`requires-python`), while minimizing the number of selected
807    /// versions across platforms.
808    ///
809    /// Under `fewest`, uv will minimize the number of selected versions for each package,
810    /// preferring older versions that are compatible with a wider range of supported Python
811    /// versions or platforms.
812    #[option(
813        default = "\"requires-python\"",
814        value_type = "str",
815        example = r#"
816            fork-strategy = "fewest"
817        "#,
818        possible_values = true
819    )]
820    pub fork_strategy: Option<ForkStrategy>,
821    /// Pre-defined static metadata for dependencies of the project (direct or transitive). When
822    /// provided, enables the resolver to use the specified metadata instead of querying the
823    /// registry or building the relevant package from source.
824    ///
825    /// Metadata should be provided in adherence with the [Metadata 2.3](https://packaging.python.org/en/latest/specifications/core-metadata/)
826    /// standard, though only the following fields are respected:
827    ///
828    /// - `name`: The name of the package.
829    /// - (Optional) `version`: The version of the package. If omitted, the metadata will be applied
830    ///   to all versions of the package.
831    /// - (Optional) `requires-dist`: The dependencies of the package (e.g., `werkzeug>=0.14`).
832    /// - (Optional) `requires-python`: The Python version required by the package (e.g., `>=3.10`).
833    /// - (Optional) `provides-extra`: The extras provided by the package.
834    #[option(
835        default = r#"[]"#,
836        value_type = "list[dict]",
837        example = r#"
838            dependency-metadata = [
839                { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
840            ]
841        "#
842    )]
843    pub dependency_metadata: Option<Vec<StaticMetadata>>,
844    /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
845    /// specified as `KEY=VALUE` pairs.
846    #[option(
847        default = "{}",
848        value_type = "dict",
849        example = r#"
850            config-settings = { editable_mode = "compat" }
851        "#
852    )]
853    pub config_settings: Option<ConfigSettings>,
854    /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend for specific packages,
855    /// specified as `KEY=VALUE` pairs.
856    ///
857    /// Accepts a map from package names to string key-value pairs.
858    #[option(
859        default = "{}",
860        value_type = "dict",
861        example = r#"
862            config-settings-package = { numpy = { editable_mode = "compat" } }
863        "#
864    )]
865    pub config_settings_package: Option<PackageConfigSettings>,
866    /// Disable isolation when building source distributions.
867    ///
868    /// Assumes that build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
869    /// are already installed.
870    #[option(
871        default = "false",
872        value_type = "bool",
873        example = r#"
874            no-build-isolation = true
875        "#
876    )]
877    pub no_build_isolation: Option<bool>,
878    /// Disable isolation when building source distributions for a specific package.
879    ///
880    /// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
881    /// are already installed.
882    #[option(
883        default = "[]",
884        value_type = "list[str]",
885        example = r#"
886        no-build-isolation-package = ["package1", "package2"]
887    "#
888    )]
889    pub no_build_isolation_package: Option<Vec<PackageName>>,
890    /// Additional build dependencies for packages.
891    ///
892    /// This allows extending the PEP 517 build environment for the project's dependencies with
893    /// additional packages. This is useful for packages that assume the presence of packages like
894    /// `pip`, and do not declare them as build dependencies.
895    #[option(
896        default = "[]",
897        value_type = "dict",
898        example = r#"
899            extra-build-dependencies = { pytest = ["setuptools"] }
900        "#
901    )]
902    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
903    /// Extra environment variables to set when building certain packages.
904    ///
905    /// Environment variables will be added to the environment when building the
906    /// specified packages.
907    #[option(
908        default = r#"{}"#,
909        value_type = r#"dict[str, dict[str, str]]"#,
910        example = r#"
911            extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
912        "#
913    )]
914    pub extra_build_variables: Option<ExtraBuildVariables>,
915    /// Limit candidate packages to those that were uploaded prior to the given date.
916    ///
917    /// The date is compared against the upload time of each individual distribution artifact
918    /// (i.e., when each file was uploaded to the package index), not the release date of the
919    /// package version.
920    ///
921    /// Accepts RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`), a "friendly" duration (e.g.,
922    /// `24 hours`, `1 week`, `30 days`), or an ISO 8601 duration (e.g., `PT24H`, `P7D`, `P30D`).
923    ///
924    /// Durations do not respect semantics of the local time zone and are always resolved to a fixed
925    /// number of seconds assuming that a day is 24 hours (e.g., DST transitions are ignored).
926    /// Calendar units such as months and years are not allowed.
927    #[option(
928        default = "None",
929        value_type = "str",
930        example = r#"
931            exclude-newer = "2006-12-02T02:07:43Z"
932        "#
933    )]
934    pub exclude_newer: Option<ExcludeNewerValue>,
935    /// Limit candidate packages for specific packages to those that were uploaded prior to the
936    /// given date.
937    ///
938    /// Accepts a dictionary format of `PACKAGE = "DATE"` pairs, where `DATE` is an RFC 3339
939    /// timestamp (e.g., `2006-12-02T02:07:43Z`), a "friendly" duration (e.g., `24 hours`, `1 week`,
940    /// `30 days`), or a ISO 8601 duration (e.g., `PT24H`, `P7D`, `P30D`).
941    ///
942    /// Durations do not respect semantics of the local time zone and are always resolved to a fixed
943    /// number of seconds assuming that a day is 24 hours (e.g., DST transitions are ignored).
944    /// Calendar units such as months and years are not allowed.
945    ///
946    /// Set a package to `false` to exempt it from the global [`exclude-newer`](#exclude-newer)
947    /// constraint entirely.
948    #[option(
949        default = "None",
950        value_type = "dict",
951        example = r#"
952            exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
953        "#
954    )]
955    pub exclude_newer_package: Option<ExcludeNewerPackage>,
956    /// The method to use when installing packages from the global cache.
957    ///
958    /// Defaults to `clone` (also known as Copy-on-Write) on macOS and Linux, and `hardlink` on
959    /// Windows.
960    ///
961    /// WARNING: The use of symlink link mode is discouraged, as they create tight coupling between
962    /// the cache and the target environment. For example, clearing the cache (`uv cache clean`)
963    /// will break all installed packages by way of removing the underlying source files. Use
964    /// symlinks with caution.
965    #[option(
966        default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
967        value_type = "str",
968        example = r#"
969            link-mode = "copy"
970        "#,
971        possible_values = true
972    )]
973    pub link_mode: Option<LinkMode>,
974    /// Compile Python files to bytecode after installation.
975    ///
976    /// By default, uv does not compile Python (`.py`) files to bytecode (`__pycache__/*.pyc`);
977    /// instead, compilation is performed lazily the first time a module is imported. For use-cases
978    /// in which start time is critical, such as CLI applications and Docker containers, this option
979    /// can be enabled to trade longer installation times for faster start times.
980    ///
981    /// When enabled, uv will process the entire site-packages directory (including packages that
982    /// are not being modified by the current operation) for consistency. Like pip, it will also
983    /// ignore errors.
984    #[option(
985        default = "false",
986        value_type = "bool",
987        example = r#"
988            compile-bytecode = true
989        "#
990    )]
991    pub compile_bytecode: Option<bool>,
992    /// Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the
993    /// standards-compliant, publishable package metadata, as opposed to using any local or Git
994    /// sources.
995    #[option(
996        default = "false",
997        value_type = "bool",
998        example = r#"
999            no-sources = true
1000        "#
1001    )]
1002    pub no_sources: Option<bool>,
1003    /// Ignore `tool.uv.sources` for the specified packages.
1004    #[option(
1005        default = "[]",
1006        value_type = "list[str]",
1007        example = r#"
1008            no-sources-package = ["ruff"]
1009        "#
1010    )]
1011    pub no_sources_package: Option<Vec<PackageName>>,
1012    /// Allow package upgrades, ignoring pinned versions in any existing output file.
1013    #[option(
1014        default = "false",
1015        value_type = "bool",
1016        example = r#"
1017            upgrade = true
1018        "#
1019    )]
1020    pub upgrade: Option<bool>,
1021    /// Allow upgrades for a specific package, ignoring pinned versions in any existing output
1022    /// file.
1023    ///
1024    /// Accepts both standalone package names (`ruff`) and version specifiers (`ruff<0.5.0`).
1025    #[option(
1026        default = "[]",
1027        value_type = "list[str]",
1028        example = r#"
1029            upgrade-package = ["ruff"]
1030        "#
1031    )]
1032    pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1033    /// Reinstall all packages, regardless of whether they're already installed. Implies `refresh`.
1034    #[option(
1035        default = "false",
1036        value_type = "bool",
1037        example = r#"
1038            reinstall = true
1039        "#
1040    )]
1041    pub reinstall: Option<bool>,
1042    /// Reinstall a specific package, regardless of whether it's already installed. Implies
1043    /// `refresh-package`.
1044    #[option(
1045        default = "[]",
1046        value_type = "list[str]",
1047        example = r#"
1048            reinstall-package = ["ruff"]
1049        "#
1050    )]
1051    pub reinstall_package: Option<Vec<PackageName>>,
1052    /// Don't build source distributions.
1053    ///
1054    /// When enabled, resolving will not run arbitrary Python code. The cached wheels of
1055    /// already-built source distributions will be reused, but operations that require building
1056    /// distributions will exit with an error.
1057    #[option(
1058        default = "false",
1059        value_type = "bool",
1060        example = r#"
1061            no-build = true
1062        "#
1063    )]
1064    pub no_build: Option<bool>,
1065    /// Don't build source distributions for a specific package.
1066    #[option(
1067        default = "[]",
1068        value_type = "list[str]",
1069        example = r#"
1070            no-build-package = ["ruff"]
1071        "#
1072    )]
1073    pub no_build_package: Option<Vec<PackageName>>,
1074    /// Don't install pre-built wheels.
1075    ///
1076    /// The given packages will be built and installed from source. The resolver will still use
1077    /// pre-built wheels to extract package metadata, if available.
1078    #[option(
1079        default = "false",
1080        value_type = "bool",
1081        example = r#"
1082            no-binary = true
1083        "#
1084    )]
1085    pub no_binary: Option<bool>,
1086    /// Don't install pre-built wheels for a specific package.
1087    #[option(
1088        default = "[]",
1089        value_type = "list[str]",
1090        example = r#"
1091            no-binary-package = ["ruff"]
1092        "#
1093    )]
1094    pub no_binary_package: Option<Vec<PackageName>>,
1095    /// The backend to use when fetching packages in the PyTorch ecosystem.
1096    ///
1097    /// When set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,
1098    /// and will instead use the defined backend.
1099    ///
1100    /// For example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,
1101    /// uv will use the PyTorch index for CUDA 12.6.
1102    ///
1103    /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently
1104    /// installed CUDA drivers.
1105    ///
1106    /// This setting is only respected by `uv pip` commands.
1107    ///
1108    /// This option is in preview and may change in any future release.
1109    #[option(
1110        default = "null",
1111        value_type = "str",
1112        example = r#"
1113            torch-backend = "auto"
1114        "#
1115    )]
1116    pub torch_backend: Option<TorchMode>,
1117}
1118
1119/// Shared settings, relevant to all operations that might create managed python installations.
1120#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
1121#[serde(rename_all = "kebab-case")]
1122#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1123pub struct PythonInstallMirrors {
1124    /// Mirror URL for downloading managed Python installations.
1125    ///
1126    /// By default, managed Python installations are downloaded from [`python-build-standalone`](https://github.com/astral-sh/python-build-standalone).
1127    /// This variable can be set to a mirror URL to use a different source for Python installations.
1128    /// The provided URL will replace `https://github.com/astral-sh/python-build-standalone/releases/download` in, e.g., `https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`.
1129    ///
1130    /// Distributions can be read from a local directory by using the `file://` URL scheme.
1131    #[option(
1132        default = "None",
1133        value_type = "str",
1134        uv_toml_only = true,
1135        example = r#"
1136            python-install-mirror = "https://github.com/astral-sh/python-build-standalone/releases/download"
1137        "#
1138    )]
1139    pub python_install_mirror: Option<String>,
1140    /// Mirror URL to use for downloading managed PyPy installations.
1141    ///
1142    /// By default, managed PyPy installations are downloaded from [downloads.python.org](https://downloads.python.org/).
1143    /// This variable can be set to a mirror URL to use a different source for PyPy installations.
1144    /// The provided URL will replace `https://downloads.python.org/pypy` in, e.g., `https://downloads.python.org/pypy/pypy3.8-v7.3.7-osx64.tar.bz2`.
1145    ///
1146    /// Distributions can be read from a
1147    /// local directory by using the `file://` URL scheme.
1148    #[option(
1149        default = "None",
1150        value_type = "str",
1151        uv_toml_only = true,
1152        example = r#"
1153            pypy-install-mirror = "https://downloads.python.org/pypy"
1154        "#
1155    )]
1156    pub pypy_install_mirror: Option<String>,
1157
1158    /// URL pointing to JSON of custom Python installations.
1159    #[option(
1160        default = "None",
1161        value_type = "str",
1162        uv_toml_only = true,
1163        example = r#"
1164            python-downloads-json-url = "/etc/uv/python-downloads.json"
1165        "#
1166    )]
1167    pub python_downloads_json_url: Option<String>,
1168}
1169
1170impl PythonInstallMirrors {
1171    #[must_use]
1172    pub fn combine(self, other: Self) -> Self {
1173        Self {
1174            python_install_mirror: self.python_install_mirror.or(other.python_install_mirror),
1175            pypy_install_mirror: self.pypy_install_mirror.or(other.pypy_install_mirror),
1176            python_downloads_json_url: self
1177                .python_downloads_json_url
1178                .or(other.python_downloads_json_url),
1179        }
1180    }
1181}
1182
1183/// Settings that are specific to the `uv pip` command-line interface.
1184///
1185/// These values will be ignored when running commands outside the `uv pip` namespace (e.g.,
1186/// `uv lock`, `uvx`).
1187#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
1188#[serde(deny_unknown_fields, rename_all = "kebab-case")]
1189#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1190pub struct PipOptions {
1191    /// The Python interpreter into which packages should be installed.
1192    ///
1193    /// By default, uv installs into the virtual environment in the current working directory or
1194    /// any parent directory. The `--python` option allows you to specify a different interpreter,
1195    /// which is intended for use in continuous integration (CI) environments or other automated
1196    /// workflows.
1197    ///
1198    /// Supported formats:
1199    /// - `3.10` looks for an installed Python 3.10 in the registry on Windows (see
1200    ///   `py --list-paths`), or `python3.10` on Linux and macOS.
1201    /// - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`.
1202    /// - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path.
1203    #[option(
1204        default = "None",
1205        value_type = "str",
1206        example = r#"
1207            python = "3.10"
1208        "#
1209    )]
1210    pub python: Option<String>,
1211    /// Install packages into the system Python environment.
1212    ///
1213    /// By default, uv installs into the virtual environment in the current working directory or
1214    /// any parent directory. The `--system` option instructs uv to instead use the first Python
1215    /// found in the system `PATH`.
1216    ///
1217    /// WARNING: `--system` is intended for use in continuous integration (CI) environments and
1218    /// should be used with caution, as it can modify the system Python installation.
1219    #[option(
1220        default = "false",
1221        value_type = "bool",
1222        example = r#"
1223            system = true
1224        "#
1225    )]
1226    pub system: Option<bool>,
1227    /// Allow uv to modify an `EXTERNALLY-MANAGED` Python installation.
1228    ///
1229    /// WARNING: `--break-system-packages` is intended for use in continuous integration (CI)
1230    /// environments, when installing into Python installations that are managed by an external
1231    /// package manager, like `apt`. It should be used with caution, as such Python installations
1232    /// explicitly recommend against modifications by other package managers (like uv or pip).
1233    #[option(
1234        default = "false",
1235        value_type = "bool",
1236        example = r#"
1237            break-system-packages = true
1238        "#
1239    )]
1240    pub break_system_packages: Option<bool>,
1241    /// Install packages into the specified directory, rather than into the virtual or system Python
1242    /// environment. The packages will be installed at the top-level of the directory.
1243    #[option(
1244        default = "None",
1245        value_type = "str",
1246        example = r#"
1247            target = "./target"
1248        "#
1249    )]
1250    pub target: Option<PathBuf>,
1251    /// Install packages into `lib`, `bin`, and other top-level folders under the specified
1252    /// directory, as if a virtual environment were present at that location.
1253    ///
1254    /// In general, prefer the use of `--python` to install into an alternate environment, as
1255    /// scripts and other artifacts installed via `--prefix` will reference the installing
1256    /// interpreter, rather than any interpreter added to the `--prefix` directory, rendering them
1257    /// non-portable.
1258    #[option(
1259        default = "None",
1260        value_type = "str",
1261        example = r#"
1262            prefix = "./prefix"
1263        "#
1264    )]
1265    pub prefix: Option<PathBuf>,
1266    #[serde(skip)]
1267    #[cfg_attr(feature = "schemars", schemars(skip))]
1268    pub index: Option<Vec<Index>>,
1269    /// The URL of the Python package index (by default: <https://pypi.org/simple>).
1270    ///
1271    /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
1272    /// (the simple repository API), or a local directory laid out in the same format.
1273    ///
1274    /// The index provided by this setting is given lower priority than any indexes specified via
1275    /// [`extra_index_url`](#extra-index-url).
1276    #[option(
1277        default = "\"https://pypi.org/simple\"",
1278        value_type = "str",
1279        example = r#"
1280            index-url = "https://test.pypi.org/simple"
1281        "#
1282    )]
1283    pub index_url: Option<PipIndex>,
1284    /// Extra URLs of package indexes to use, in addition to `--index-url`.
1285    ///
1286    /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
1287    /// (the simple repository API), or a local directory laid out in the same format.
1288    ///
1289    /// All indexes provided via this flag take priority over the index specified by
1290    /// [`index_url`](#index-url). When multiple indexes are provided, earlier values take priority.
1291    ///
1292    /// To control uv's resolution strategy when multiple indexes are present, see
1293    /// [`index_strategy`](#index-strategy).
1294    #[option(
1295        default = "[]",
1296        value_type = "list[str]",
1297        example = r#"
1298            extra-index-url = ["https://download.pytorch.org/whl/cpu"]
1299        "#
1300    )]
1301    pub extra_index_url: Option<Vec<PipExtraIndex>>,
1302    /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and
1303    /// those provided via `--find-links`.
1304    #[option(
1305        default = "false",
1306        value_type = "bool",
1307        example = r#"
1308            no-index = true
1309        "#
1310    )]
1311    pub no_index: Option<bool>,
1312    /// Locations to search for candidate distributions, in addition to those found in the registry
1313    /// indexes.
1314    ///
1315    /// If a path, the target must be a directory that contains packages as wheel files (`.whl`) or
1316    /// source distributions (e.g., `.tar.gz` or `.zip`) at the top level.
1317    ///
1318    /// If a URL, the page must contain a flat list of links to package files adhering to the
1319    /// formats described above.
1320    #[option(
1321        default = "[]",
1322        value_type = "list[str]",
1323        example = r#"
1324            find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
1325        "#
1326    )]
1327    pub find_links: Option<Vec<PipFindLinks>>,
1328    /// The strategy to use when resolving against multiple index URLs.
1329    ///
1330    /// By default, uv will stop at the first index on which a given package is available, and
1331    /// limit resolutions to those present on that first index (`first-index`). This prevents
1332    /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the
1333    /// same name to an alternate index.
1334    #[option(
1335        default = "\"first-index\"",
1336        value_type = "str",
1337        example = r#"
1338            index-strategy = "unsafe-best-match"
1339        "#,
1340        possible_values = true
1341    )]
1342    pub index_strategy: Option<IndexStrategy>,
1343    /// Attempt to use `keyring` for authentication for index URLs.
1344    ///
1345    /// At present, only `--keyring-provider subprocess` is supported, which configures uv to
1346    /// use the `keyring` CLI to handle authentication.
1347    #[option(
1348        default = "disabled",
1349        value_type = "str",
1350        example = r#"
1351            keyring-provider = "subprocess"
1352        "#
1353    )]
1354    pub keyring_provider: Option<KeyringProviderType>,
1355    /// Don't build source distributions.
1356    ///
1357    /// When enabled, resolving will not run arbitrary Python code. The cached wheels of
1358    /// already-built source distributions will be reused, but operations that require building
1359    /// distributions will exit with an error.
1360    ///
1361    /// Alias for `--only-binary :all:`.
1362    #[option(
1363        default = "false",
1364        value_type = "bool",
1365        example = r#"
1366            no-build = true
1367        "#
1368    )]
1369    pub no_build: Option<bool>,
1370    /// Don't install pre-built wheels.
1371    ///
1372    /// The given packages will be built and installed from source. The resolver will still use
1373    /// pre-built wheels to extract package metadata, if available.
1374    ///
1375    /// Multiple packages may be provided. Disable binaries for all packages with `:all:`.
1376    /// Clear previously specified packages with `:none:`.
1377    #[option(
1378        default = "[]",
1379        value_type = "list[str]",
1380        example = r#"
1381            no-binary = ["ruff"]
1382        "#
1383    )]
1384    pub no_binary: Option<Vec<PackageNameSpecifier>>,
1385    /// Only use pre-built wheels; don't build source distributions.
1386    ///
1387    /// When enabled, resolving will not run code from the given packages. The cached wheels of already-built
1388    /// source distributions will be reused, but operations that require building distributions will
1389    /// exit with an error.
1390    ///
1391    /// Multiple packages may be provided. Disable binaries for all packages with `:all:`.
1392    /// Clear previously specified packages with `:none:`.
1393    #[option(
1394        default = "[]",
1395        value_type = "list[str]",
1396        example = r#"
1397            only-binary = ["ruff"]
1398        "#
1399    )]
1400    pub only_binary: Option<Vec<PackageNameSpecifier>>,
1401    /// Disable isolation when building source distributions.
1402    ///
1403    /// Assumes that build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
1404    /// are already installed.
1405    #[option(
1406        default = "false",
1407        value_type = "bool",
1408        example = r#"
1409            no-build-isolation = true
1410        "#
1411    )]
1412    pub no_build_isolation: Option<bool>,
1413    /// Disable isolation when building source distributions for a specific package.
1414    ///
1415    /// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
1416    /// are already installed.
1417    #[option(
1418        default = "[]",
1419        value_type = "list[str]",
1420        example = r#"
1421            no-build-isolation-package = ["package1", "package2"]
1422        "#
1423    )]
1424    pub no_build_isolation_package: Option<Vec<PackageName>>,
1425    /// Additional build dependencies for packages.
1426    ///
1427    /// This allows extending the PEP 517 build environment for the project's dependencies with
1428    /// additional packages. This is useful for packages that assume the presence of packages like
1429    /// `pip`, and do not declare them as build dependencies.
1430    #[option(
1431        default = "[]",
1432        value_type = "dict",
1433        example = r#"
1434            extra-build-dependencies = { pytest = ["setuptools"] }
1435        "#
1436    )]
1437    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1438    /// Extra environment variables to set when building certain packages.
1439    ///
1440    /// Environment variables will be added to the environment when building the
1441    /// specified packages.
1442    #[option(
1443        default = r#"{}"#,
1444        value_type = r#"dict[str, dict[str, str]]"#,
1445        example = r#"
1446            extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1447        "#
1448    )]
1449    pub extra_build_variables: Option<ExtraBuildVariables>,
1450    /// Validate the Python environment, to detect packages with missing dependencies and other
1451    /// issues.
1452    #[option(
1453        default = "false",
1454        value_type = "bool",
1455        example = r#"
1456            strict = true
1457        "#
1458    )]
1459    pub strict: Option<bool>,
1460    /// Include optional dependencies from the specified extra; may be provided more than once.
1461    ///
1462    /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
1463    #[option(
1464        default = "[]",
1465        value_type = "list[str]",
1466        example = r#"
1467            extra = ["dev", "docs"]
1468        "#
1469    )]
1470    pub extra: Option<Vec<ExtraName>>,
1471    /// Include all optional dependencies.
1472    ///
1473    /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
1474    #[option(
1475        default = "false",
1476        value_type = "bool",
1477        example = r#"
1478            all-extras = true
1479        "#
1480    )]
1481    pub all_extras: Option<bool>,
1482    /// Exclude the specified optional dependencies if `all-extras` is supplied.
1483    #[option(
1484        default = "[]",
1485        value_type = "list[str]",
1486        example = r#"
1487            all-extras = true
1488            no-extra = ["dev", "docs"]
1489        "#
1490    )]
1491    pub no_extra: Option<Vec<ExtraName>>,
1492    /// Ignore package dependencies, instead only add those packages explicitly listed
1493    /// on the command line to the resulting requirements file.
1494    #[option(
1495        default = "false",
1496        value_type = "bool",
1497        example = r#"
1498            no-deps = true
1499        "#
1500    )]
1501    pub no_deps: Option<bool>,
1502    /// Include the following dependency groups.
1503    #[option(
1504        default = "None",
1505        value_type = "list[str]",
1506        example = r#"
1507            group = ["dev", "docs"]
1508        "#
1509    )]
1510    pub group: Option<Vec<PipGroupName>>,
1511    /// Allow `uv pip sync` with empty requirements, which will clear the environment of all
1512    /// packages.
1513    #[option(
1514        default = "false",
1515        value_type = "bool",
1516        example = r#"
1517            allow-empty-requirements = true
1518        "#
1519    )]
1520    pub allow_empty_requirements: Option<bool>,
1521    /// The strategy to use when selecting between the different compatible versions for a given
1522    /// package requirement.
1523    ///
1524    /// By default, uv will use the latest compatible version of each package (`highest`).
1525    #[option(
1526        default = "\"highest\"",
1527        value_type = "str",
1528        example = r#"
1529            resolution = "lowest-direct"
1530        "#,
1531        possible_values = true
1532    )]
1533    pub resolution: Option<ResolutionMode>,
1534    /// The strategy to use when considering pre-release versions.
1535    ///
1536    /// By default, uv will accept pre-releases for packages that _only_ publish pre-releases,
1537    /// along with first-party requirements that contain an explicit pre-release marker in the
1538    /// declared specifiers (`if-necessary-or-explicit`).
1539    #[option(
1540        default = "\"if-necessary-or-explicit\"",
1541        value_type = "str",
1542        example = r#"
1543            prerelease = "allow"
1544        "#,
1545        possible_values = true
1546    )]
1547    pub prerelease: Option<PrereleaseMode>,
1548    /// The strategy to use when selecting multiple versions of a given package across Python
1549    /// versions and platforms.
1550    ///
1551    /// By default, uv will optimize for selecting the latest version of each package for each
1552    /// supported Python version (`requires-python`), while minimizing the number of selected
1553    /// versions across platforms.
1554    ///
1555    /// Under `fewest`, uv will minimize the number of selected versions for each package,
1556    /// preferring older versions that are compatible with a wider range of supported Python
1557    /// versions or platforms.
1558    #[option(
1559        default = "\"requires-python\"",
1560        value_type = "str",
1561        example = r#"
1562            fork-strategy = "fewest"
1563        "#,
1564        possible_values = true
1565    )]
1566    pub fork_strategy: Option<ForkStrategy>,
1567    /// Pre-defined static metadata for dependencies of the project (direct or transitive). When
1568    /// provided, enables the resolver to use the specified metadata instead of querying the
1569    /// registry or building the relevant package from source.
1570    ///
1571    /// Metadata should be provided in adherence with the [Metadata 2.3](https://packaging.python.org/en/latest/specifications/core-metadata/)
1572    /// standard, though only the following fields are respected:
1573    ///
1574    /// - `name`: The name of the package.
1575    /// - (Optional) `version`: The version of the package. If omitted, the metadata will be applied
1576    ///   to all versions of the package.
1577    /// - (Optional) `requires-dist`: The dependencies of the package (e.g., `werkzeug>=0.14`).
1578    /// - (Optional) `requires-python`: The Python version required by the package (e.g., `>=3.10`).
1579    /// - (Optional) `provides-extra`: The extras provided by the package.
1580    #[option(
1581        default = r#"[]"#,
1582        value_type = "list[dict]",
1583        example = r#"
1584            dependency-metadata = [
1585                { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1586            ]
1587        "#
1588    )]
1589    pub dependency_metadata: Option<Vec<StaticMetadata>>,
1590    /// Write the requirements generated by `uv pip compile` to the given `requirements.txt` file.
1591    ///
1592    /// If the file already exists, the existing versions will be preferred when resolving
1593    /// dependencies, unless `--upgrade` is also specified.
1594    #[option(
1595        default = "None",
1596        value_type = "str",
1597        example = r#"
1598            output-file = "requirements.txt"
1599        "#
1600    )]
1601    pub output_file: Option<PathBuf>,
1602    /// Include extras in the output file.
1603    ///
1604    /// By default, uv strips extras, as any packages pulled in by the extras are already included
1605    /// as dependencies in the output file directly. Further, output files generated with
1606    /// `--no-strip-extras` cannot be used as constraints files in `install` and `sync` invocations.
1607    #[option(
1608        default = "false",
1609        value_type = "bool",
1610        example = r#"
1611            no-strip-extras = true
1612        "#
1613    )]
1614    pub no_strip_extras: Option<bool>,
1615    /// Include environment markers in the output file generated by `uv pip compile`.
1616    ///
1617    /// By default, uv strips environment markers, as the resolution generated by `compile` is
1618    /// only guaranteed to be correct for the target environment.
1619    #[option(
1620        default = "false",
1621        value_type = "bool",
1622        example = r#"
1623            no-strip-markers = true
1624        "#
1625    )]
1626    pub no_strip_markers: Option<bool>,
1627    /// Exclude comment annotations indicating the source of each package from the output file
1628    /// generated by `uv pip compile`.
1629    #[option(
1630        default = "false",
1631        value_type = "bool",
1632        example = r#"
1633            no-annotate = true
1634        "#
1635    )]
1636    pub no_annotate: Option<bool>,
1637    /// Exclude the comment header at the top of output file generated by `uv pip compile`.
1638    #[option(
1639        default = r#"false"#,
1640        value_type = "bool",
1641        example = r#"
1642            no-header = true
1643        "#
1644    )]
1645    pub no_header: Option<bool>,
1646    /// The header comment to include at the top of the output file generated by `uv pip compile`.
1647    ///
1648    /// Used to reflect custom build scripts and commands that wrap `uv pip compile`.
1649    #[option(
1650        default = "None",
1651        value_type = "str",
1652        example = r#"
1653            custom-compile-command = "./custom-uv-compile.sh"
1654        "#
1655    )]
1656    pub custom_compile_command: Option<String>,
1657    /// Include distribution hashes in the output file.
1658    #[option(
1659        default = "false",
1660        value_type = "bool",
1661        example = r#"
1662            generate-hashes = true
1663        "#
1664    )]
1665    pub generate_hashes: Option<bool>,
1666    /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
1667    /// specified as `KEY=VALUE` pairs.
1668    #[option(
1669        default = "{}",
1670        value_type = "dict",
1671        example = r#"
1672            config-settings = { editable_mode = "compat" }
1673        "#
1674    )]
1675    pub config_settings: Option<ConfigSettings>,
1676    /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend for specific packages,
1677    /// specified as `KEY=VALUE` pairs.
1678    #[option(
1679        default = "{}",
1680        value_type = "dict",
1681        example = r#"
1682            config-settings-package = { numpy = { editable_mode = "compat" } }
1683        "#
1684    )]
1685    pub config_settings_package: Option<PackageConfigSettings>,
1686    /// The minimum Python version that should be supported by the resolved requirements (e.g.,
1687    /// `3.8` or `3.8.17`).
1688    ///
1689    /// If a patch version is omitted, the minimum patch version is assumed. For example, `3.8` is
1690    /// mapped to `3.8.0`.
1691    #[option(
1692        default = "None",
1693        value_type = "str",
1694        example = r#"
1695            python-version = "3.8"
1696        "#
1697    )]
1698    pub python_version: Option<PythonVersion>,
1699    /// The platform for which requirements should be resolved.
1700    ///
1701    /// Represented as a "target triple", a string that describes the target platform in terms of
1702    /// its CPU, vendor, and operating system name, like `x86_64-unknown-linux-gnu` or
1703    /// `aarch64-apple-darwin`.
1704    #[option(
1705        default = "None",
1706        value_type = "str",
1707        example = r#"
1708            python-platform = "x86_64-unknown-linux-gnu"
1709        "#
1710    )]
1711    pub python_platform: Option<TargetTriple>,
1712    /// Perform a universal resolution, attempting to generate a single `requirements.txt` output
1713    /// file that is compatible with all operating systems, architectures, and Python
1714    /// implementations.
1715    ///
1716    /// In universal mode, the current Python version (or user-provided `--python-version`) will be
1717    /// treated as a lower bound. For example, `--universal --python-version 3.7` would produce a
1718    /// universal resolution for Python 3.7 and later.
1719    #[option(
1720        default = "false",
1721        value_type = "bool",
1722        example = r#"
1723            universal = true
1724        "#
1725    )]
1726    pub universal: Option<bool>,
1727    /// Limit candidate packages to those that were uploaded prior to a given point in time.
1728    ///
1729    /// The date is compared against the upload time of each individual distribution artifact
1730    /// (i.e., when each file was uploaded to the package index), not the release date of the
1731    /// package version.
1732    ///
1733    /// Accepts a superset of [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) (e.g.,
1734    /// `2006-12-02T02:07:43Z`). A full timestamp is required to ensure that the resolver will
1735    /// behave consistently across timezones.
1736    #[option(
1737        default = "None",
1738        value_type = "str",
1739        example = r#"
1740            exclude-newer = "2006-12-02T02:07:43Z"
1741        "#
1742    )]
1743    pub exclude_newer: Option<ExcludeNewerValue>,
1744    /// Limit candidate packages for specific packages to those that were uploaded prior to the given date.
1745    ///
1746    /// Accepts package-date pairs in a dictionary format. Set a package to `false` to exempt it
1747    /// from the global [`exclude-newer`](#exclude-newer) constraint entirely.
1748    #[option(
1749        default = "None",
1750        value_type = "dict",
1751        example = r#"
1752            exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
1753        "#
1754    )]
1755    pub exclude_newer_package: Option<ExcludeNewerPackage>,
1756    /// Specify a package to omit from the output resolution. Its dependencies will still be
1757    /// included in the resolution. Equivalent to pip-compile's `--unsafe-package` option.
1758    #[option(
1759        default = "[]",
1760        value_type = "list[str]",
1761        example = r#"
1762            no-emit-package = ["ruff"]
1763        "#
1764    )]
1765    pub no_emit_package: Option<Vec<PackageName>>,
1766    /// Include `--index-url` and `--extra-index-url` entries in the output file generated by `uv pip compile`.
1767    #[option(
1768        default = "false",
1769        value_type = "bool",
1770        example = r#"
1771            emit-index-url = true
1772        "#
1773    )]
1774    pub emit_index_url: Option<bool>,
1775    /// Include `--find-links` entries in the output file generated by `uv pip compile`.
1776    #[option(
1777        default = "false",
1778        value_type = "bool",
1779        example = r#"
1780            emit-find-links = true
1781        "#
1782    )]
1783    pub emit_find_links: Option<bool>,
1784    /// Include `--no-binary` and `--only-binary` entries in the output file generated by `uv pip compile`.
1785    #[option(
1786        default = "false",
1787        value_type = "bool",
1788        example = r#"
1789            emit-build-options = true
1790        "#
1791    )]
1792    pub emit_build_options: Option<bool>,
1793    /// Whether to emit a marker string indicating the conditions under which the set of pinned
1794    /// dependencies is valid.
1795    ///
1796    /// The pinned dependencies may be valid even when the marker expression is
1797    /// false, but when the expression is true, the requirements are known to
1798    /// be correct.
1799    #[option(
1800        default = "false",
1801        value_type = "bool",
1802        example = r#"
1803            emit-marker-expression = true
1804        "#
1805    )]
1806    pub emit_marker_expression: Option<bool>,
1807    /// Include comment annotations indicating the index used to resolve each package (e.g.,
1808    /// `# from https://pypi.org/simple`).
1809    #[option(
1810        default = "false",
1811        value_type = "bool",
1812        example = r#"
1813            emit-index-annotation = true
1814        "#
1815    )]
1816    pub emit_index_annotation: Option<bool>,
1817    /// The style of the annotation comments included in the output file, used to indicate the
1818    /// source of each package.
1819    #[option(
1820        default = "\"split\"",
1821        value_type = "str",
1822        example = r#"
1823            annotation-style = "line"
1824        "#,
1825        possible_values = true
1826    )]
1827    pub annotation_style: Option<AnnotationStyle>,
1828    /// The method to use when installing packages from the global cache.
1829    ///
1830    /// Defaults to `clone` (also known as Copy-on-Write) on macOS and Linux, and `hardlink` on
1831    /// Windows.
1832    ///
1833    /// WARNING: The use of symlink link mode is discouraged, as they create tight coupling between
1834    /// the cache and the target environment. For example, clearing the cache (`uv cache clean`)
1835    /// will break all installed packages by way of removing the underlying source files. Use
1836    /// symlinks with caution.
1837    #[option(
1838        default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
1839        value_type = "str",
1840        example = r#"
1841            link-mode = "copy"
1842        "#,
1843        possible_values = true
1844    )]
1845    pub link_mode: Option<LinkMode>,
1846    /// Compile Python files to bytecode after installation.
1847    ///
1848    /// By default, uv does not compile Python (`.py`) files to bytecode (`__pycache__/*.pyc`);
1849    /// instead, compilation is performed lazily the first time a module is imported. For use-cases
1850    /// in which start time is critical, such as CLI applications and Docker containers, this option
1851    /// can be enabled to trade longer installation times for faster start times.
1852    ///
1853    /// When enabled, uv will process the entire site-packages directory (including packages that
1854    /// are not being modified by the current operation) for consistency. Like pip, it will also
1855    /// ignore errors.
1856    #[option(
1857        default = "false",
1858        value_type = "bool",
1859        example = r#"
1860            compile-bytecode = true
1861        "#
1862    )]
1863    pub compile_bytecode: Option<bool>,
1864    /// Require a matching hash for each requirement.
1865    ///
1866    /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
1867    /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
1868    /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
1869    ///
1870    /// Hash-checking mode introduces a number of additional constraints:
1871    ///
1872    /// - Git dependencies are not supported.
1873    /// - Editable installations are not supported.
1874    /// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or
1875    ///   source archive (`.zip`, `.tar.gz`), as opposed to a directory.
1876    #[option(
1877        default = "false",
1878        value_type = "bool",
1879        example = r#"
1880            require-hashes = true
1881        "#
1882    )]
1883    pub require_hashes: Option<bool>,
1884    /// Validate any hashes provided in the requirements file.
1885    ///
1886    /// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
1887    /// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
1888    /// include them.
1889    #[option(
1890        default = "true",
1891        value_type = "bool",
1892        example = r#"
1893            verify-hashes = true
1894        "#
1895    )]
1896    pub verify_hashes: Option<bool>,
1897    /// Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the
1898    /// standards-compliant, publishable package metadata, as opposed to using any local or Git
1899    /// sources.
1900    #[option(
1901        default = "false",
1902        value_type = "bool",
1903        example = r#"
1904            no-sources = true
1905        "#
1906    )]
1907    pub no_sources: Option<bool>,
1908    /// Ignore `tool.uv.sources` for the specified packages.
1909    #[option(
1910        default = "[]",
1911        value_type = "list[str]",
1912        example = r#"
1913            no-sources-package = ["ruff"]
1914        "#
1915    )]
1916    pub no_sources_package: Option<Vec<PackageName>>,
1917    /// Allow package upgrades, ignoring pinned versions in any existing output file.
1918    #[option(
1919        default = "false",
1920        value_type = "bool",
1921        example = r#"
1922            upgrade = true
1923        "#
1924    )]
1925    pub upgrade: Option<bool>,
1926    /// Allow upgrades for a specific package, ignoring pinned versions in any existing output
1927    /// file.
1928    ///
1929    /// Accepts both standalone package names (`ruff`) and version specifiers (`ruff<0.5.0`).
1930    #[option(
1931        default = "[]",
1932        value_type = "list[str]",
1933        example = r#"
1934            upgrade-package = ["ruff"]
1935        "#
1936    )]
1937    pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1938    /// Reinstall all packages, regardless of whether they're already installed. Implies `refresh`.
1939    #[option(
1940        default = "false",
1941        value_type = "bool",
1942        example = r#"
1943            reinstall = true
1944        "#
1945    )]
1946    pub reinstall: Option<bool>,
1947    /// Reinstall a specific package, regardless of whether it's already installed. Implies
1948    /// `refresh-package`.
1949    #[option(
1950        default = "[]",
1951        value_type = "list[str]",
1952        example = r#"
1953            reinstall-package = ["ruff"]
1954        "#
1955    )]
1956    pub reinstall_package: Option<Vec<PackageName>>,
1957    /// The backend to use when fetching packages in the PyTorch ecosystem.
1958    ///
1959    /// When set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,
1960    /// and will instead use the defined backend.
1961    ///
1962    /// For example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,
1963    /// uv will use the PyTorch index for CUDA 12.6.
1964    ///
1965    /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently
1966    /// installed CUDA drivers.
1967    ///
1968    /// This setting is only respected by `uv pip` commands.
1969    ///
1970    /// This option is in preview and may change in any future release.
1971    #[option(
1972        default = "null",
1973        value_type = "str",
1974        example = r#"
1975            torch-backend = "auto"
1976        "#
1977    )]
1978    pub torch_backend: Option<TorchMode>,
1979}
1980
1981impl PipOptions {
1982    /// Resolve the [`PipOptions`] relative to the given root directory.
1983    pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
1984        Ok(Self {
1985            index: self
1986                .index
1987                .map(|index| {
1988                    index
1989                        .into_iter()
1990                        .map(|index| index.relative_to(root_dir))
1991                        .collect::<Result<Vec<_>, _>>()
1992                })
1993                .transpose()?,
1994            index_url: self
1995                .index_url
1996                .map(|index_url| index_url.relative_to(root_dir))
1997                .transpose()?,
1998            extra_index_url: self
1999                .extra_index_url
2000                .map(|extra_index_url| {
2001                    extra_index_url
2002                        .into_iter()
2003                        .map(|extra_index_url| extra_index_url.relative_to(root_dir))
2004                        .collect::<Result<Vec<_>, _>>()
2005                })
2006                .transpose()?,
2007            find_links: self
2008                .find_links
2009                .map(|find_links| {
2010                    find_links
2011                        .into_iter()
2012                        .map(|find_link| find_link.relative_to(root_dir))
2013                        .collect::<Result<Vec<_>, _>>()
2014                })
2015                .transpose()?,
2016            ..self
2017        })
2018    }
2019}
2020
2021impl From<ResolverInstallerSchema> for ResolverOptions {
2022    fn from(value: ResolverInstallerSchema) -> Self {
2023        Self {
2024            index: value.index,
2025            index_url: value.index_url,
2026            extra_index_url: value.extra_index_url,
2027            no_index: value.no_index,
2028            find_links: value.find_links,
2029            index_strategy: value.index_strategy,
2030            keyring_provider: value.keyring_provider,
2031            resolution: value.resolution,
2032            prerelease: value.prerelease,
2033            fork_strategy: value.fork_strategy,
2034            dependency_metadata: value.dependency_metadata,
2035            config_settings: value.config_settings,
2036            config_settings_package: value.config_settings_package,
2037            exclude_newer: ExcludeNewer::from_args(
2038                value.exclude_newer,
2039                value
2040                    .exclude_newer_package
2041                    .unwrap_or_default()
2042                    .into_iter()
2043                    .map(Into::into)
2044                    .collect(),
2045            ),
2046            link_mode: value.link_mode,
2047            upgrade: Upgrade::from_args(
2048                value.upgrade,
2049                value
2050                    .upgrade_package
2051                    .into_iter()
2052                    .flatten()
2053                    .map(Into::into)
2054                    .collect(),
2055                Vec::new(),
2056            ),
2057            no_build: value.no_build,
2058            no_build_package: value.no_build_package,
2059            no_binary: value.no_binary,
2060            no_binary_package: value.no_binary_package,
2061            build_isolation: BuildIsolation::from_args(
2062                value.no_build_isolation,
2063                value.no_build_isolation_package.unwrap_or_default(),
2064            ),
2065            extra_build_dependencies: value.extra_build_dependencies,
2066            extra_build_variables: value.extra_build_variables,
2067            no_sources: value.no_sources,
2068            no_sources_package: value.no_sources_package,
2069            torch_backend: value.torch_backend,
2070        }
2071    }
2072}
2073
2074impl From<ResolverInstallerSchema> for InstallerOptions {
2075    fn from(value: ResolverInstallerSchema) -> Self {
2076        Self {
2077            index: value.index,
2078            index_url: value.index_url,
2079            extra_index_url: value.extra_index_url,
2080            no_index: value.no_index,
2081            find_links: value.find_links,
2082            index_strategy: value.index_strategy,
2083            keyring_provider: value.keyring_provider,
2084            config_settings: value.config_settings,
2085            exclude_newer: ExcludeNewer::from_args(
2086                value.exclude_newer,
2087                value
2088                    .exclude_newer_package
2089                    .unwrap_or_default()
2090                    .into_iter()
2091                    .map(Into::into)
2092                    .collect(),
2093            )
2094            .global,
2095            link_mode: value.link_mode,
2096            compile_bytecode: value.compile_bytecode,
2097            reinstall: Reinstall::from_args(
2098                value.reinstall,
2099                value.reinstall_package.unwrap_or_default(),
2100            ),
2101            build_isolation: BuildIsolation::from_args(
2102                value.no_build_isolation,
2103                value.no_build_isolation_package.unwrap_or_default(),
2104            ),
2105            no_build: value.no_build,
2106            no_build_package: value.no_build_package,
2107            no_binary: value.no_binary,
2108            no_binary_package: value.no_binary_package,
2109            no_sources: value.no_sources,
2110            no_sources_package: value.no_sources_package,
2111        }
2112    }
2113}
2114
2115/// The options persisted alongside an installed tool.
2116///
2117/// A mirror of [`ResolverInstallerSchema`], without upgrades and reinstalls, which shouldn't be
2118/// persisted in a tool receipt.
2119#[derive(
2120    Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata,
2121)]
2122#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2123#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2124pub struct ToolOptions {
2125    pub index: Option<Vec<Index>>,
2126    pub index_url: Option<PipIndex>,
2127    pub extra_index_url: Option<Vec<PipExtraIndex>>,
2128    pub no_index: Option<bool>,
2129    pub find_links: Option<Vec<PipFindLinks>>,
2130    pub index_strategy: Option<IndexStrategy>,
2131    pub keyring_provider: Option<KeyringProviderType>,
2132    pub resolution: Option<ResolutionMode>,
2133    pub prerelease: Option<PrereleaseMode>,
2134    pub fork_strategy: Option<ForkStrategy>,
2135    pub dependency_metadata: Option<Vec<StaticMetadata>>,
2136    pub config_settings: Option<ConfigSettings>,
2137    pub config_settings_package: Option<PackageConfigSettings>,
2138    pub build_isolation: Option<BuildIsolation>,
2139    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
2140    pub extra_build_variables: Option<ExtraBuildVariables>,
2141    pub exclude_newer: Option<ExcludeNewerValue>,
2142    pub exclude_newer_package: Option<ExcludeNewerPackage>,
2143    pub link_mode: Option<LinkMode>,
2144    pub compile_bytecode: Option<bool>,
2145    pub no_sources: Option<bool>,
2146    pub no_sources_package: Option<Vec<PackageName>>,
2147    pub no_build: Option<bool>,
2148    pub no_build_package: Option<Vec<PackageName>>,
2149    pub no_binary: Option<bool>,
2150    pub no_binary_package: Option<Vec<PackageName>>,
2151    pub torch_backend: Option<TorchMode>,
2152}
2153
2154/// The on-disk representation of [`ToolOptions`] in a tool receipt.
2155#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2156#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2157pub struct ToolOptionsWire {
2158    pub index: Option<Vec<Index>>,
2159    pub index_url: Option<PipIndex>,
2160    pub extra_index_url: Option<Vec<PipExtraIndex>>,
2161    pub no_index: Option<bool>,
2162    pub find_links: Option<Vec<PipFindLinks>>,
2163    pub index_strategy: Option<IndexStrategy>,
2164    pub keyring_provider: Option<KeyringProviderType>,
2165    pub resolution: Option<ResolutionMode>,
2166    pub prerelease: Option<PrereleaseMode>,
2167    pub fork_strategy: Option<ForkStrategy>,
2168    pub dependency_metadata: Option<Vec<StaticMetadata>>,
2169    pub config_settings: Option<ConfigSettings>,
2170    pub config_settings_package: Option<PackageConfigSettings>,
2171    pub build_isolation: Option<BuildIsolation>,
2172    pub extra_build_dependencies: Option<ExtraBuildDependencies>,
2173    pub extra_build_variables: Option<ExtraBuildVariables>,
2174    pub exclude_newer: Option<ExcludeNewerValue>,
2175    pub exclude_newer_span: Option<ExcludeNewerSpan>,
2176    #[serde(serialize_with = "serialize_exclude_newer_package_with_spans")]
2177    pub exclude_newer_package: Option<ExcludeNewerPackage>,
2178    pub link_mode: Option<LinkMode>,
2179    pub compile_bytecode: Option<bool>,
2180    pub no_sources: Option<bool>,
2181    pub no_sources_package: Option<Vec<PackageName>>,
2182    pub no_build: Option<bool>,
2183    pub no_build_package: Option<Vec<PackageName>>,
2184    pub no_binary: Option<bool>,
2185    pub no_binary_package: Option<Vec<PackageName>>,
2186    pub torch_backend: Option<TorchMode>,
2187}
2188
2189impl From<ResolverInstallerOptions> for ToolOptions {
2190    fn from(value: ResolverInstallerOptions) -> Self {
2191        Self {
2192            index: value.index.map(|indexes| {
2193                indexes
2194                    .into_iter()
2195                    .map(Index::with_promoted_auth_policy)
2196                    .collect()
2197            }),
2198            index_url: value.index_url,
2199            extra_index_url: value.extra_index_url,
2200            no_index: value.no_index,
2201            find_links: value.find_links,
2202            index_strategy: value.index_strategy,
2203            keyring_provider: value.keyring_provider,
2204            resolution: value.resolution,
2205            prerelease: value.prerelease,
2206            fork_strategy: value.fork_strategy,
2207            dependency_metadata: value.dependency_metadata,
2208            config_settings: value.config_settings,
2209            config_settings_package: value.config_settings_package,
2210            build_isolation: value.build_isolation,
2211            extra_build_dependencies: value.extra_build_dependencies,
2212            extra_build_variables: value.extra_build_variables,
2213            exclude_newer: value.exclude_newer,
2214            exclude_newer_package: value.exclude_newer_package,
2215            link_mode: value.link_mode,
2216            compile_bytecode: value.compile_bytecode,
2217            no_sources: value.no_sources,
2218            no_sources_package: value.no_sources_package,
2219            no_build: value.no_build,
2220            no_build_package: value.no_build_package,
2221            no_binary: value.no_binary,
2222            no_binary_package: value.no_binary_package,
2223            torch_backend: value.torch_backend,
2224        }
2225    }
2226}
2227
2228impl From<ToolOptionsWire> for ToolOptions {
2229    fn from(value: ToolOptionsWire) -> Self {
2230        let exclude_newer = value.exclude_newer.map(|exclude_newer| {
2231            if exclude_newer.span().is_none() {
2232                ExcludeNewerValue::new(exclude_newer.timestamp(), value.exclude_newer_span)
2233            } else {
2234                exclude_newer
2235            }
2236        });
2237
2238        Self {
2239            index: value.index,
2240            index_url: value.index_url,
2241            extra_index_url: value.extra_index_url,
2242            no_index: value.no_index,
2243            find_links: value.find_links,
2244            index_strategy: value.index_strategy,
2245            keyring_provider: value.keyring_provider,
2246            resolution: value.resolution,
2247            prerelease: value.prerelease,
2248            fork_strategy: value.fork_strategy,
2249            dependency_metadata: value.dependency_metadata,
2250            config_settings: value.config_settings,
2251            config_settings_package: value.config_settings_package,
2252            build_isolation: value.build_isolation,
2253            extra_build_dependencies: value.extra_build_dependencies,
2254            extra_build_variables: value.extra_build_variables,
2255            exclude_newer,
2256            exclude_newer_package: value.exclude_newer_package,
2257            link_mode: value.link_mode,
2258            compile_bytecode: value.compile_bytecode,
2259            no_sources: value.no_sources,
2260            no_sources_package: value.no_sources_package,
2261            no_build: value.no_build,
2262            no_build_package: value.no_build_package,
2263            no_binary: value.no_binary,
2264            no_binary_package: value.no_binary_package,
2265            torch_backend: value.torch_backend,
2266        }
2267    }
2268}
2269
2270impl From<ToolOptions> for ToolOptionsWire {
2271    fn from(value: ToolOptions) -> Self {
2272        let (exclude_newer, exclude_newer_span) = value
2273            .exclude_newer
2274            .map(ExcludeNewerValue::into_parts)
2275            .map_or((None, None), |(timestamp, span)| {
2276                (Some(ExcludeNewerValue::from(timestamp)), span)
2277            });
2278
2279        Self {
2280            index: value.index,
2281            index_url: value.index_url,
2282            extra_index_url: value.extra_index_url,
2283            no_index: value.no_index,
2284            find_links: value.find_links,
2285            index_strategy: value.index_strategy,
2286            keyring_provider: value.keyring_provider,
2287            resolution: value.resolution,
2288            prerelease: value.prerelease,
2289            fork_strategy: value.fork_strategy,
2290            dependency_metadata: value.dependency_metadata,
2291            config_settings: value.config_settings,
2292            config_settings_package: value.config_settings_package,
2293            build_isolation: value.build_isolation,
2294            extra_build_dependencies: value.extra_build_dependencies,
2295            extra_build_variables: value.extra_build_variables,
2296            exclude_newer,
2297            exclude_newer_span,
2298            exclude_newer_package: value.exclude_newer_package,
2299            link_mode: value.link_mode,
2300            compile_bytecode: value.compile_bytecode,
2301            no_sources: value.no_sources,
2302            no_sources_package: value.no_sources_package,
2303            no_build: value.no_build,
2304            no_build_package: value.no_build_package,
2305            no_binary: value.no_binary,
2306            no_binary_package: value.no_binary_package,
2307            torch_backend: value.torch_backend,
2308        }
2309    }
2310}
2311
2312impl From<ToolOptions> for ResolverInstallerOptions {
2313    fn from(value: ToolOptions) -> Self {
2314        Self {
2315            index: value.index,
2316            index_url: value.index_url,
2317            extra_index_url: value.extra_index_url,
2318            no_index: value.no_index,
2319            find_links: value.find_links,
2320            index_strategy: value.index_strategy,
2321            keyring_provider: value.keyring_provider,
2322            resolution: value.resolution,
2323            prerelease: value.prerelease,
2324            fork_strategy: value.fork_strategy,
2325            dependency_metadata: value.dependency_metadata,
2326            config_settings: value.config_settings,
2327            config_settings_package: value.config_settings_package,
2328            build_isolation: value.build_isolation,
2329            extra_build_dependencies: value.extra_build_dependencies,
2330            extra_build_variables: value.extra_build_variables,
2331            exclude_newer: value.exclude_newer,
2332            exclude_newer_package: value.exclude_newer_package,
2333            link_mode: value.link_mode,
2334            compile_bytecode: value.compile_bytecode,
2335            no_sources: value.no_sources,
2336            no_sources_package: value.no_sources_package,
2337            upgrade: None,
2338            reinstall: None,
2339            no_build: value.no_build,
2340            no_build_package: value.no_build_package,
2341            no_binary: value.no_binary,
2342            no_binary_package: value.no_binary_package,
2343            torch_backend: value.torch_backend,
2344        }
2345    }
2346}
2347
2348/// Like [`Options]`, but with any `#[serde(flatten)]` fields inlined. This leads to far, far
2349/// better error messages when deserializing.
2350#[derive(Debug, Clone, Default, Deserialize)]
2351#[serde(rename_all = "kebab-case", deny_unknown_fields)]
2352pub struct OptionsWire {
2353    // #[serde(flatten)]
2354    // globals: GlobalOptions
2355    required_version: Option<RequiredVersion>,
2356    system_certs: Option<bool>,
2357    native_tls: Option<bool>,
2358    offline: Option<bool>,
2359    no_cache: Option<bool>,
2360    cache_dir: Option<PathBuf>,
2361    preview: Option<bool>,
2362    python_preference: Option<PythonPreference>,
2363    python_downloads: Option<PythonDownloads>,
2364    concurrent_downloads: Option<NonZeroUsize>,
2365    concurrent_builds: Option<NonZeroUsize>,
2366    concurrent_installs: Option<NonZeroUsize>,
2367
2368    // #[serde(flatten)]
2369    // top_level: ResolverInstallerOptions
2370    index: Option<Vec<Index>>,
2371    index_url: Option<PipIndex>,
2372    extra_index_url: Option<Vec<PipExtraIndex>>,
2373    no_index: Option<bool>,
2374    find_links: Option<Vec<PipFindLinks>>,
2375    index_strategy: Option<IndexStrategy>,
2376    keyring_provider: Option<KeyringProviderType>,
2377    http_proxy: Option<ProxyUrl>,
2378    https_proxy: Option<ProxyUrl>,
2379    no_proxy: Option<Vec<String>>,
2380    allow_insecure_host: Option<Vec<TrustedHost>>,
2381    resolution: Option<ResolutionMode>,
2382    prerelease: Option<PrereleaseMode>,
2383    fork_strategy: Option<ForkStrategy>,
2384    dependency_metadata: Option<Vec<StaticMetadata>>,
2385    config_settings: Option<ConfigSettings>,
2386    config_settings_package: Option<PackageConfigSettings>,
2387    no_build_isolation: Option<bool>,
2388    no_build_isolation_package: Option<Vec<PackageName>>,
2389    extra_build_dependencies: Option<ExtraBuildDependencies>,
2390    extra_build_variables: Option<ExtraBuildVariables>,
2391    exclude_newer: Option<ExcludeNewerValue>,
2392    exclude_newer_package: Option<ExcludeNewerPackage>,
2393    link_mode: Option<LinkMode>,
2394    compile_bytecode: Option<bool>,
2395    no_sources: Option<bool>,
2396    no_sources_package: Option<Vec<PackageName>>,
2397    upgrade: Option<bool>,
2398    upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2399    reinstall: Option<bool>,
2400    reinstall_package: Option<Vec<PackageName>>,
2401    no_build: Option<bool>,
2402    no_build_package: Option<Vec<PackageName>>,
2403    no_binary: Option<bool>,
2404    no_binary_package: Option<Vec<PackageName>>,
2405    torch_backend: Option<TorchMode>,
2406
2407    // #[serde(flatten)]
2408    // install_mirror: PythonInstallMirrors,
2409    python_install_mirror: Option<String>,
2410    pypy_install_mirror: Option<String>,
2411    python_downloads_json_url: Option<String>,
2412
2413    // #[serde(flatten)]
2414    // publish: PublishOptions
2415    publish_url: Option<DisplaySafeUrl>,
2416    trusted_publishing: Option<TrustedPublishing>,
2417    check_url: Option<IndexUrl>,
2418
2419    // #[serde(flatten)]
2420    // add: AddOptions
2421    add_bounds: Option<AddBoundsKind>,
2422
2423    audit: Option<AuditOptions>,
2424    pip: Option<PipOptions>,
2425    cache_keys: Option<Vec<CacheKey>>,
2426
2427    // NOTE(charlie): These fields are shared with `ToolUv` in
2428    // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
2429    // They're respected in both `pyproject.toml` and `uv.toml` files.
2430    override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2431    exclude_dependencies: Option<Vec<PackageName>>,
2432    constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2433    build_constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2434    environments: Option<SupportedEnvironments>,
2435    required_environments: Option<SupportedEnvironments>,
2436
2437    // NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
2438    // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
2439    // They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
2440    conflicts: Option<serde::de::IgnoredAny>,
2441    workspace: Option<serde::de::IgnoredAny>,
2442    sources: Option<serde::de::IgnoredAny>,
2443    managed: Option<serde::de::IgnoredAny>,
2444    r#package: Option<serde::de::IgnoredAny>,
2445    default_groups: Option<serde::de::IgnoredAny>,
2446    dependency_groups: Option<serde::de::IgnoredAny>,
2447    dev_dependencies: Option<serde::de::IgnoredAny>,
2448
2449    // Build backend
2450    build_backend: Option<serde::de::IgnoredAny>,
2451}
2452
2453impl From<OptionsWire> for Options {
2454    #[allow(deprecated)]
2455    fn from(value: OptionsWire) -> Self {
2456        let OptionsWire {
2457            required_version,
2458            system_certs,
2459            native_tls,
2460            offline,
2461            no_cache,
2462            cache_dir,
2463            preview,
2464            python_preference,
2465            python_downloads,
2466            python_install_mirror,
2467            pypy_install_mirror,
2468            python_downloads_json_url,
2469            concurrent_downloads,
2470            concurrent_builds,
2471            concurrent_installs,
2472            index,
2473            index_url,
2474            extra_index_url,
2475            no_index,
2476            find_links,
2477            index_strategy,
2478            keyring_provider,
2479            http_proxy,
2480            https_proxy,
2481            no_proxy,
2482            allow_insecure_host,
2483            resolution,
2484            prerelease,
2485            fork_strategy,
2486            dependency_metadata,
2487            config_settings,
2488            config_settings_package,
2489            no_build_isolation,
2490            no_build_isolation_package,
2491            exclude_newer,
2492            exclude_newer_package,
2493            link_mode,
2494            compile_bytecode,
2495            no_sources,
2496            no_sources_package,
2497            upgrade,
2498            upgrade_package,
2499            reinstall,
2500            reinstall_package,
2501            no_build,
2502            no_build_package,
2503            no_binary,
2504            no_binary_package,
2505            torch_backend,
2506            audit,
2507            pip,
2508            cache_keys,
2509            override_dependencies,
2510            exclude_dependencies,
2511            constraint_dependencies,
2512            build_constraint_dependencies,
2513            environments,
2514            required_environments,
2515            conflicts,
2516            publish_url,
2517            trusted_publishing,
2518            check_url,
2519            workspace,
2520            sources,
2521            default_groups,
2522            dependency_groups,
2523            extra_build_dependencies,
2524            extra_build_variables,
2525            dev_dependencies,
2526            managed,
2527            package,
2528            add_bounds: bounds,
2529            // Used by the build backend
2530            build_backend,
2531        } = value;
2532
2533        Self {
2534            globals: GlobalOptions {
2535                required_version,
2536                system_certs,
2537                native_tls,
2538                offline,
2539                no_cache,
2540                cache_dir,
2541                preview,
2542                python_preference,
2543                python_downloads,
2544                concurrent_downloads,
2545                concurrent_builds,
2546                concurrent_installs,
2547                http_proxy,
2548                https_proxy,
2549                no_proxy,
2550                // Used twice for backwards compatibility
2551                allow_insecure_host: allow_insecure_host.clone(),
2552            },
2553            top_level: ResolverInstallerSchema {
2554                index,
2555                index_url,
2556                extra_index_url,
2557                no_index,
2558                find_links,
2559                index_strategy,
2560                keyring_provider,
2561                resolution,
2562                prerelease,
2563                fork_strategy,
2564                dependency_metadata,
2565                config_settings,
2566                config_settings_package,
2567                no_build_isolation,
2568                no_build_isolation_package,
2569                extra_build_dependencies,
2570                extra_build_variables,
2571                exclude_newer,
2572                exclude_newer_package,
2573                link_mode,
2574                compile_bytecode,
2575                no_sources,
2576                no_sources_package,
2577                upgrade,
2578                upgrade_package,
2579                reinstall,
2580                reinstall_package,
2581                no_build,
2582                no_build_package,
2583                no_binary,
2584                no_binary_package,
2585                torch_backend,
2586            },
2587            pip,
2588            cache_keys,
2589            build_backend,
2590            override_dependencies,
2591            exclude_dependencies,
2592            constraint_dependencies,
2593            build_constraint_dependencies,
2594            environments,
2595            required_environments,
2596            install_mirrors: PythonInstallMirrors {
2597                python_install_mirror,
2598                pypy_install_mirror,
2599                python_downloads_json_url,
2600            },
2601            conflicts,
2602            publish: PublishOptions {
2603                publish_url,
2604                trusted_publishing,
2605                check_url,
2606            },
2607            add: AddOptions { add_bounds: bounds },
2608            audit,
2609            workspace,
2610            sources,
2611            dev_dependencies,
2612            default_groups,
2613            dependency_groups,
2614            managed,
2615            package,
2616        }
2617    }
2618}
2619
2620#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2621#[serde(rename_all = "kebab-case")]
2622#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2623pub struct PublishOptions {
2624    /// The URL for publishing packages to the Python package index (by default:
2625    /// <https://upload.pypi.org/legacy/>).
2626    #[option(
2627        default = "\"https://upload.pypi.org/legacy/\"",
2628        value_type = "str",
2629        example = r#"
2630            publish-url = "https://test.pypi.org/legacy/"
2631        "#
2632    )]
2633    pub publish_url: Option<DisplaySafeUrl>,
2634
2635    /// Configure trusted publishing.
2636    ///
2637    /// By default, uv checks for trusted publishing when running in a supported environment, but
2638    /// ignores it if it isn't configured.
2639    ///
2640    /// uv's supported environments for trusted publishing include GitHub Actions and GitLab CI/CD.
2641    #[option(
2642        default = "automatic",
2643        value_type = "str",
2644        example = r#"
2645            trusted-publishing = "always"
2646        "#
2647    )]
2648    pub trusted_publishing: Option<TrustedPublishing>,
2649
2650    /// Check an index URL for existing files to skip duplicate uploads.
2651    ///
2652    /// This option allows retrying publishing that failed after only some, but not all files have
2653    /// been uploaded, and handles error due to parallel uploads of the same file.
2654    ///
2655    /// Before uploading, the index is checked. If the exact same file already exists in the index,
2656    /// the file will not be uploaded. If an error occurred during the upload, the index is checked
2657    /// again, to handle cases where the identical file was uploaded twice in parallel.
2658    ///
2659    /// The exact behavior will vary based on the index. When uploading to PyPI, uploading the same
2660    /// file succeeds even without `--check-url`, while most other indexes error.
2661    ///
2662    /// The index must provide one of the supported hashes (SHA-256, SHA-384, or SHA-512).
2663    #[option(
2664        default = "None",
2665        value_type = "str",
2666        example = r#"
2667            check-url = "https://test.pypi.org/simple"
2668        "#
2669    )]
2670    pub check_url: Option<IndexUrl>,
2671}
2672
2673#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2674#[serde(rename_all = "kebab-case")]
2675#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2676pub struct AddOptions {
2677    /// The default version specifier when adding a dependency.
2678    ///
2679    /// When adding a dependency to the project, if no constraint or URL is provided, a constraint
2680    /// is added based on the latest compatible version of the package. By default, a lower bound
2681    /// constraint is used, e.g., `>=1.2.3`.
2682    ///
2683    /// When `--frozen` is provided, no resolution is performed, and dependencies are always added
2684    /// without constraints.
2685    ///
2686    /// This option is in preview and may change in any future release.
2687    #[option(
2688        default = "\"lower\"",
2689        value_type = "str",
2690        example = r#"
2691            add-bounds = "major"
2692        "#,
2693        possible_values = true
2694    )]
2695    pub add_bounds: Option<AddBoundsKind>,
2696}
2697
2698#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2699#[serde(rename_all = "kebab-case")]
2700#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2701pub struct AuditOptions {
2702    /// A list of vulnerability IDs to ignore during auditing.
2703    ///
2704    /// Vulnerabilities matching any of the provided IDs (including aliases) will be excluded from
2705    /// the audit results.
2706    #[option(
2707        default = "[]",
2708        value_type = "list[str]",
2709        example = r#"
2710            ignore = ["PYSEC-2022-43017", "GHSA-5239-wwwm-4pmq"]
2711        "#
2712    )]
2713    pub ignore: Option<Vec<String>>,
2714
2715    /// A list of vulnerability IDs to ignore during auditing, but only while no fix is available.
2716    ///
2717    /// Vulnerabilities matching any of the provided IDs (including aliases) will be excluded from
2718    /// the audit results as long as they have no known fix versions. Once a fix version becomes
2719    /// available, the vulnerability will be reported again.
2720    #[option(
2721        default = "[]",
2722        value_type = "list[str]",
2723        example = r#"
2724            ignore-until-fixed = ["PYSEC-2022-43017"]
2725        "#
2726    )]
2727    pub ignore_until_fixed: Option<Vec<String>>,
2728}