1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use clap::Clap;
use std::path::PathBuf;
use crate::config::{Config, Header};
#[derive(Clap, Debug, Clone)]
#[clap(about, version)]
pub enum CargoSideloadArgs {
/// Downloads all packages in your `Cargo.toml` and places them in the local Cargo cache, limited to the specified registry.
Fetch(CargoSideloadFetchArgs),
/// List some info for all published versions of the specified crate. Does not include yanked versions.
List(CargoSideloadListArgs),
/// List all crates in your `Cargo.toml` that have newer versions available, limited to the specified registry.
Outdated(CargoSideloadOutdatedArgs),
}
#[derive(Clap, Debug, Clone)]
pub struct CargoSideloadCommonArgs {
#[clap(short = 'r', long = "registry", env = "CARGO_SIDELOAD_REGISTRY")]
/// Name of the registry as it is defined in your cargo config (usually `~/.cargo/config.toml`).
pub registry: String,
#[clap(long = "path", default_value = ".")]
/// Path to the `Cargo.toml` file of the crate you're running this command on.
pub path: PathBuf,
#[clap(short = 'p', long = "packages")]
/// List of crates to run this command on.
pub packages: Option<Vec<String>>,
#[clap(short, long)]
/// Silence Cargo
pub quiet: bool,
}
#[derive(Clap, Debug, Clone)]
pub struct CargoSideloadFetchArgs {
#[clap(flatten)]
pub common: CargoSideloadCommonArgs,
#[clap(long, env = "CARGO_SIDELOAD_HEADER", hide_env_values = true)]
/// Headers to add to the download request in the format `[Header-Name]: [Header Value]`.
/// Note that only one header can be set by environment variable.
pub headers: Vec<Header>,
#[clap(short, long)]
/// Deletes any existing `.crate` file before downloading its replacement.
pub force: bool,
}
#[derive(Clap, Debug, Clone)]
pub struct CargoSideloadListArgs {
/// Name of the crate whose info will be returned
pub name: String,
#[clap(short, long, env = "CARGO_SIDELOAD_REGISTRY")]
/// Name of the registry as it is defined in your cargo config (usually `~/.cargo/config.toml`).
pub registry: String,
#[clap(short, long)]
/// Only return info for the latest version of the package
pub latest: bool,
#[clap(short, long = "version-only")]
/// Only return version numbers
pub version_only: bool,
#[clap(short, long)]
/// Silence Cargo
pub quiet: bool,
}
#[derive(Clap, Debug, Clone)]
pub struct CargoSideloadOutdatedArgs {
#[clap(flatten)]
pub common: CargoSideloadCommonArgs,
#[clap(short, long)]
/// Returns an error if any dependencies are out of date
pub error: bool,
}
impl CargoSideloadArgs {
pub fn load(config: &Config) -> Self {
// Set the default registry from the user's config file before parsing the arguments
if let Some(default_registry) = &config.default_registry {
std::env::set_var("CARGO_SIDELOAD_REGISTRY", default_registry);
}
// Running `cargo sideload` will pass "sideload" as the first argument.
// Since this isn't a real argument in the Clap definition, parsing the args will fail.
let args = std::env::args_os().enumerate().filter_map(|(index, arg)| {
if index == 1 && arg == "sideload" {
None
} else {
Some(arg)
}
});
let mut result = Self::parse_from(args);
// Add headers from the user's config file to the arg headers
if let CargoSideloadArgs::Fetch(ref mut fetch_args) = &mut result {
// Don't add default headers if headers are provided manually
if fetch_args.headers.is_empty() {
if let Some(registry) = config.registries.get(&fetch_args.common.registry) {
for header in ®istry.default_headers {
fetch_args.headers.push(header.clone());
}
}
}
}
result
}
}