forked from rust-lang/cargo
/
install.rs
157 lines (146 loc) · 5.25 KB
/
install.rs
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use crate::command_prelude::*;
use cargo::core::{GitReference, SourceId};
use cargo::ops;
use cargo::util::IntoUrl;
pub fn cli() -> App {
subcommand("install")
.about("Install a Rust binary. Default location is $HOME/.cargo/bin")
.arg_quiet()
.arg(Arg::with_name("crate").empty_values(false).multiple(true))
.arg(
opt("version", "Specify a version to install")
.alias("vers")
.value_name("VERSION")
.requires("crate"),
)
.arg(
opt("git", "Git URL to install the specified crate from")
.value_name("URL")
.conflicts_with_all(&["path", "index", "registry"]),
)
.arg(
opt("branch", "Branch to use when installing from git")
.value_name("BRANCH")
.requires("git"),
)
.arg(
opt("tag", "Tag to use when installing from git")
.value_name("TAG")
.requires("git"),
)
.arg(
opt("rev", "Specific commit to use when installing from git")
.value_name("SHA")
.requires("git"),
)
.arg(
opt("path", "Filesystem path to local crate to install")
.value_name("PATH")
.conflicts_with_all(&["git", "index", "registry"]),
)
.arg(opt(
"list",
"list all installed packages and their versions",
))
.arg_jobs()
.arg(opt("force", "Force overwriting existing crates or binaries").short('f'))
.arg(opt("no-track", "Do not save tracking information"))
.arg_features()
.arg_profile("Install artifacts with the specified profile")
.arg(opt("debug", "Build in debug mode instead of release mode"))
.arg_targets_bins_examples(
"Install only the specified binary",
"Install all binaries",
"Install only the specified example",
"Install all examples",
)
.arg_target_triple("Build for the target triple")
.arg_target_dir()
.arg(opt("root", "Directory to install packages into").value_name("DIR"))
.arg(
opt("index", "Registry index to install from")
.value_name("INDEX")
.requires("crate")
.conflicts_with_all(&["git", "path", "registry"]),
)
.arg(
opt("registry", "Registry to use")
.value_name("REGISTRY")
.requires("crate")
.conflicts_with_all(&["git", "path", "index"]),
)
.arg_message_format()
.after_help("Run `cargo help install` for more detailed information.\n")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
if let Some(path) = args.value_of_path("path", config) {
config.reload_rooted_at(path)?;
} else {
// TODO: Consider calling set_search_stop_path(home).
config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
}
let krates = args
.values_of("crate")
.unwrap_or_default()
.collect::<Vec<_>>();
let mut from_cwd = false;
let source = if let Some(url) = args.value_of("git") {
let url = url.into_url()?;
let gitref = if let Some(branch) = args.value_of("branch") {
GitReference::Branch(branch.to_string())
} else if let Some(tag) = args.value_of("tag") {
GitReference::Tag(tag.to_string())
} else if let Some(rev) = args.value_of("rev") {
GitReference::Rev(rev.to_string())
} else {
GitReference::DefaultBranch
};
SourceId::for_git(&url, gitref)?
} else if let Some(path) = args.value_of_path("path", config) {
SourceId::for_path(&path)?
} else if krates.is_empty() {
from_cwd = true;
SourceId::for_path(config.cwd())?
} else if let Some(registry) = args.registry(config)? {
SourceId::alt_registry(config, ®istry)?
} else if let Some(index) = args.value_of("index") {
SourceId::for_registry(&index.into_url()?)?
} else {
SourceId::crates_io(config)?
};
let version = args.value_of("version");
let root = args.value_of("root");
// We only provide workspace information for local crate installation from
// one of the following sources:
// - From current working directory (only work for edition 2015).
// - From a specific local file path.
let workspace = if from_cwd || args.is_present("path") {
args.workspace(config).ok()
} else {
None
};
let mut compile_opts = args.compile_options(
config,
CompileMode::Build,
workspace.as_ref(),
ProfileChecking::Custom,
)?;
compile_opts.build_config.requested_profile =
args.get_profile_name(config, "release", ProfileChecking::Custom)?;
if args.is_present("list") {
ops::install_list(root, config)?;
} else {
ops::install(
config,
root,
krates,
source,
from_cwd,
version,
&compile_opts,
args.is_present("force"),
args.is_present("no-track"),
)?;
}
Ok(())
}