1 use crate::command_prelude::*;
2 use cargo::ops;
3 use std::path::PathBuf;
4 
cli() -> App5 pub fn cli() -> App {
6     subcommand("vendor")
7         .about("Vendor all dependencies for a project locally")
8         .arg(opt("quiet", "No output printed to stdout").short("q"))
9         .arg_manifest_path()
10         .arg(Arg::with_name("path").help("Where to vendor crates (`vendor` by default)"))
11         .arg(
12             Arg::with_name("no-delete")
13                 .long("no-delete")
14                 .help("Don't delete older crates in the vendor directory"),
15         )
16         .arg(
17             Arg::with_name("tomls")
18                 .short("s")
19                 .long("sync")
20                 .help("Additional `Cargo.toml` to sync and vendor")
21                 .value_name("TOML")
22                 .multiple(true),
23         )
24         .arg(
25             Arg::with_name("respect-source-config")
26                 .long("respect-source-config")
27                 .help("Respect `[source]` config in `.cargo/config`")
28                 .multiple(true),
29         )
30         .arg(
31             Arg::with_name("versioned-dirs")
32                 .long("versioned-dirs")
33                 .help("Always include version in subdir name"),
34         )
35         // Not supported.
36         .arg(
37             Arg::with_name("no-merge-sources")
38                 .long("no-merge-sources")
39                 .hidden(true),
40         )
41         // Not supported.
42         .arg(
43             Arg::with_name("relative-path")
44                 .long("relative-path")
45                 .hidden(true),
46         )
47         // Not supported.
48         .arg(
49             Arg::with_name("only-git-deps")
50                 .long("only-git-deps")
51                 .hidden(true),
52         )
53         // Not supported.
54         .arg(
55             Arg::with_name("disallow-duplicates")
56                 .long("disallow-duplicates")
57                 .hidden(true),
58         )
59         .after_help("Run `cargo help vendor` for more detailed information.\n")
60 }
61 
exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult62 pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
63     // We're doing the vendoring operation ourselves, so we don't actually want
64     // to respect any of the `source` configuration in Cargo itself. That's
65     // intended for other consumers of Cargo, but we want to go straight to the
66     // source, e.g. crates.io, to fetch crates.
67     if !args.is_present("respect-source-config") {
68         config.values_mut()?.remove("source");
69     }
70 
71     // When we moved `cargo vendor` into Cargo itself we didn't stabilize a few
72     // flags, so try to provide a helpful error message in that case to ensure
73     // that users currently using the flag aren't tripped up.
74     let crates_io_cargo_vendor_flag = if args.is_present("no-merge-sources") {
75         Some("--no-merge-sources")
76     } else if args.is_present("relative-path") {
77         Some("--relative-path")
78     } else if args.is_present("only-git-deps") {
79         Some("--only-git-deps")
80     } else if args.is_present("disallow-duplicates") {
81         Some("--disallow-duplicates")
82     } else {
83         None
84     };
85     if let Some(flag) = crates_io_cargo_vendor_flag {
86         return Err(anyhow::format_err!(
87             "\
88 the crates.io `cargo vendor` command has now been merged into Cargo itself
89 and does not support the flag `{}` currently; to continue using the flag you
90 can execute `cargo-vendor vendor ...`, and if you would like to see this flag
91 supported in Cargo itself please feel free to file an issue at
92 https://github.com/rust-lang/cargo/issues/new
93 ",
94             flag
95         )
96         .into());
97     }
98 
99     let ws = args.workspace(config)?;
100     let path = args
101         .value_of_os("path")
102         .map(|val| PathBuf::from(val.to_os_string()))
103         .unwrap_or_else(|| PathBuf::from("vendor"));
104     ops::vendor(
105         &ws,
106         &ops::VendorOptions {
107             no_delete: args.is_present("no-delete"),
108             destination: &path,
109             versioned_dirs: args.is_present("versioned-dirs"),
110             extra: args
111                 .values_of_os("tomls")
112                 .unwrap_or_default()
113                 .map(|s| PathBuf::from(s.to_os_string()))
114                 .collect(),
115         },
116     )?;
117     Ok(())
118 }
119