|
1 | 1 | //! Command-line options. |
2 | | -use std::{collections::HashMap, path::PathBuf, str::FromStr}; |
| 2 | +use std::path::PathBuf; |
3 | 3 |
|
4 | 4 | use clap::{arg, Parser}; |
5 | | -use rattler_conda_types::{ |
6 | | - utils::url_with_trailing_slash::UrlWithTrailingSlash, NamedChannelOrUrl, Platform, |
7 | | -}; |
8 | | -#[cfg(feature = "s3")] |
9 | | -use rattler_networking::s3_middleware; |
10 | | -use rattler_networking::{mirror_middleware, AuthenticationStorage}; |
11 | | -use rattler_solve::ChannelPriority; |
| 5 | +use rattler_conda_types::utils::url_with_trailing_slash::UrlWithTrailingSlash; |
| 6 | +use rattler_networking::AuthenticationStorage; |
12 | 7 | use tracing::warn; |
13 | 8 | use url::Url; |
14 | 9 |
|
15 | | -/// The configuration type for rattler-build - just extends rattler / pixi |
16 | | -/// config and can load the same TOML files. |
17 | | -pub type Config = rattler_config::config::ConfigBase<()>; |
18 | | - |
19 | | -/// Container for `rattler_solver::ChannelPriority` so that it can be parsed |
20 | | -#[derive(Clone, PartialEq, Eq, Debug)] |
21 | | -pub struct ChannelPriorityWrapper { |
22 | | - /// The `ChannelPriority` value to be used when building the Configuration |
23 | | - pub value: ChannelPriority, |
24 | | -} |
25 | | -impl FromStr for ChannelPriorityWrapper { |
26 | | - type Err = String; |
27 | | - |
28 | | - fn from_str(s: &str) -> Result<Self, Self::Err> { |
29 | | - match s.to_lowercase().as_str() { |
30 | | - "strict" => Ok(ChannelPriorityWrapper { |
31 | | - value: ChannelPriority::Strict, |
32 | | - }), |
33 | | - "disabled" => Ok(ChannelPriorityWrapper { |
34 | | - value: ChannelPriority::Disabled, |
35 | | - }), |
36 | | - _ => Err("Channel priority must be either 'strict' or 'disabled'".to_string()), |
37 | | - } |
38 | | - } |
39 | | -} |
40 | | - |
41 | | -/// Common opts that are shared between `Rebuild` and `Build` subcommands |
42 | | -#[derive(Parser, Clone, Debug)] |
| 10 | +/// Common opts for upload operations |
| 11 | +#[derive(Parser, Clone, Debug, Default)] |
43 | 12 | pub struct CommonOpts { |
44 | | - /// Output directory for build artifacts. |
45 | | - #[clap( |
46 | | - long, |
47 | | - env = "CONDA_BLD_PATH", |
48 | | - verbatim_doc_comment, |
49 | | - help_heading = "Modifying result" |
50 | | - )] |
51 | | - pub output_dir: Option<PathBuf>, |
52 | | - |
53 | | - /// Enable support for repodata.json.zst |
54 | | - #[clap(long, env = "RATTLER_ZSTD", default_value = "true", hide = true)] |
55 | | - pub use_zstd: bool, |
56 | | - |
57 | | - /// Enable support for repodata.json.bz2 |
58 | | - #[clap(long, env = "RATTLER_BZ2", default_value = "true", hide = true)] |
59 | | - pub use_bz2: bool, |
60 | | - |
61 | | - /// Enable experimental features |
62 | | - #[arg(long, env = "RATTLER_BUILD_EXPERIMENTAL")] |
63 | | - pub experimental: bool, |
64 | | - |
65 | 13 | /// List of hosts for which SSL certificate verification should be skipped |
66 | 14 | #[arg(long, value_delimiter = ',')] |
67 | 15 | pub allow_insecure_host: Option<Vec<String>>, |
68 | 16 |
|
69 | 17 | /// Path to an auth-file to read authentication information from |
70 | 18 | #[clap(long, env = "RATTLER_AUTH_FILE", hide = true)] |
71 | 19 | pub auth_file: Option<PathBuf>, |
72 | | - |
73 | | - /// Channel priority to use when solving |
74 | | - #[arg(long)] |
75 | | - pub channel_priority: Option<ChannelPriorityWrapper>, |
76 | 20 | } |
77 | 21 |
|
78 | 22 | #[derive(Clone, Debug)] |
79 | 23 | #[allow(missing_docs)] |
80 | 24 | pub struct CommonData { |
81 | | - pub output_dir: PathBuf, |
82 | | - pub experimental: bool, |
83 | 25 | pub auth_file: Option<PathBuf>, |
84 | | - pub channel_priority: ChannelPriority, |
85 | | - pub mirror_config: HashMap<Url, Vec<mirror_middleware::Mirror>>, |
86 | 26 | pub allow_insecure_host: Option<Vec<String>>, |
87 | | - #[cfg(feature = "s3")] |
88 | | - pub s3_config: HashMap<String, s3_middleware::S3Config>, |
89 | 27 | } |
90 | 28 |
|
91 | 29 | impl CommonData { |
92 | 30 | /// Create a new instance of `CommonData` |
93 | | - pub fn new( |
94 | | - output_dir: Option<PathBuf>, |
95 | | - experimental: bool, |
96 | | - auth_file: Option<PathBuf>, |
97 | | - config: Config, |
98 | | - channel_priority: Option<ChannelPriority>, |
99 | | - allow_insecure_host: Option<Vec<String>>, |
100 | | - ) -> Self { |
101 | | - // mirror config |
102 | | - // todo: this is a duplicate in pixi and pixi-pack: do it like in |
103 | | - // `compute_s3_config` |
104 | | - let mut mirror_config = HashMap::new(); |
105 | | - tracing::debug!("Using mirrors: {:?}", config.mirrors); |
106 | | - |
107 | | - #[allow(clippy::items_after_statements)] |
108 | | - fn ensure_trailing_slash(url: &url::Url) -> url::Url { |
109 | | - if url.path().ends_with('/') { |
110 | | - url.clone() |
111 | | - } else { |
112 | | - // Do not use `join` because it removes the last element |
113 | | - format!("{url}/") |
114 | | - .parse() |
115 | | - .expect("Failed to add trailing slash to URL") |
116 | | - } |
117 | | - } |
118 | | - |
119 | | - for (key, value) in &config.mirrors { |
120 | | - let mut mirrors = Vec::new(); |
121 | | - for v in value { |
122 | | - mirrors.push(mirror_middleware::Mirror { |
123 | | - url: ensure_trailing_slash(v), |
124 | | - no_jlap: false, |
125 | | - no_bz2: false, |
126 | | - no_zstd: false, |
127 | | - max_failures: None, |
128 | | - }); |
129 | | - } |
130 | | - mirror_config.insert(ensure_trailing_slash(key), mirrors); |
131 | | - } |
132 | | - #[cfg(feature = "s3")] |
133 | | - let s3_config = rattler_networking::s3_middleware::compute_s3_config(&config.s3_options.0); |
| 31 | + pub fn new(auth_file: Option<PathBuf>, allow_insecure_host: Option<Vec<String>>) -> Self { |
134 | 32 | Self { |
135 | | - output_dir: output_dir.unwrap_or_else(|| PathBuf::from("./output")), |
136 | | - experimental, |
137 | 33 | auth_file, |
138 | | - #[cfg(feature = "s3")] |
139 | | - s3_config, |
140 | | - mirror_config, |
141 | | - channel_priority: channel_priority.unwrap_or(ChannelPriority::Strict), |
142 | 34 | allow_insecure_host, |
143 | 35 | } |
144 | 36 | } |
145 | 37 |
|
146 | | - fn from_opts_and_config(value: CommonOpts, config: Config) -> Self { |
147 | | - Self::new( |
148 | | - value.output_dir, |
149 | | - value.experimental, |
150 | | - value.auth_file, |
151 | | - config, |
152 | | - value.channel_priority.map(|c| c.value), |
153 | | - value.allow_insecure_host, |
154 | | - ) |
| 38 | + /// Create from `CommonOpts` |
| 39 | + pub fn from_opts(value: CommonOpts) -> Self { |
| 40 | + Self::new(value.auth_file, value.allow_insecure_host) |
155 | 41 | } |
156 | 42 | } |
157 | 43 |
|
@@ -583,80 +469,3 @@ impl CondaForgeData { |
583 | 469 | } |
584 | 470 | } |
585 | 471 | } |
586 | | - |
587 | | -/// Debug options |
588 | | -#[derive(Parser)] |
589 | | -pub struct DebugOpts { |
590 | | - /// Recipe file to debug |
591 | | - #[arg(short, long)] |
592 | | - pub recipe: PathBuf, |
593 | | - |
594 | | - /// Output directory for build artifacts |
595 | | - #[arg(short, long)] |
596 | | - pub output: Option<PathBuf>, |
597 | | - |
598 | | - /// The target platform to build for |
599 | | - #[arg(long)] |
600 | | - pub target_platform: Option<Platform>, |
601 | | - |
602 | | - /// The host platform to build for (defaults to `target_platform`) |
603 | | - #[arg(long)] |
604 | | - pub host_platform: Option<Platform>, |
605 | | - |
606 | | - /// The build platform to build for (defaults to current platform) |
607 | | - #[arg(long)] |
608 | | - pub build_platform: Option<Platform>, |
609 | | - |
610 | | - /// Channels to use when building |
611 | | - #[arg(short = 'c', long = "channel")] |
612 | | - pub channels: Option<Vec<NamedChannelOrUrl>>, |
613 | | - |
614 | | - /// Common options |
615 | | - #[clap(flatten)] |
616 | | - pub common: CommonOpts, |
617 | | - |
618 | | - /// Name of the specific output to debug (only required when a recipe has |
619 | | - /// multiple outputs) |
620 | | - #[arg(long, help = "Name of the specific output to debug")] |
621 | | - pub output_name: Option<String>, |
622 | | -} |
623 | | - |
624 | | -#[derive(Debug, Clone)] |
625 | | -/// Data structure containing the configuration for debugging a recipe |
626 | | -pub struct DebugData { |
627 | | - /// Path to the recipe file to debug |
628 | | - pub recipe_path: PathBuf, |
629 | | - /// Directory where build artifacts will be stored |
630 | | - pub output_dir: PathBuf, |
631 | | - /// Platform where the build is being executed |
632 | | - pub build_platform: Platform, |
633 | | - /// Target platform for the build |
634 | | - pub target_platform: Platform, |
635 | | - /// Host platform for runtime dependencies |
636 | | - pub host_platform: Platform, |
637 | | - /// List of channels to search for dependencies |
638 | | - pub channels: Option<Vec<NamedChannelOrUrl>>, |
639 | | - /// Common configuration options |
640 | | - pub common: CommonData, |
641 | | - /// Name of the specific output to debug (if recipe has multiple outputs) |
642 | | - pub output_name: Option<String>, |
643 | | -} |
644 | | - |
645 | | -impl DebugData { |
646 | | - /// Generate a new `TestData` struct from `TestOpts` and an optional pixi |
647 | | - /// config. `TestOpts` have higher priority than the pixi config. |
648 | | - pub fn from_opts_and_config(opts: DebugOpts, config: Option<Config>) -> Self { |
649 | | - Self { |
650 | | - recipe_path: opts.recipe, |
651 | | - output_dir: opts.output.unwrap_or_else(|| PathBuf::from("./output")), |
652 | | - build_platform: opts.build_platform.unwrap_or(Platform::current()), |
653 | | - target_platform: opts.target_platform.unwrap_or(Platform::current()), |
654 | | - host_platform: opts |
655 | | - .host_platform |
656 | | - .unwrap_or_else(|| opts.target_platform.unwrap_or(Platform::current())), |
657 | | - channels: opts.channels, |
658 | | - common: CommonData::from_opts_and_config(opts.common, config.unwrap_or_default()), |
659 | | - output_name: opts.output_name, |
660 | | - } |
661 | | - } |
662 | | -} |
0 commit comments