/
install.rs
170 lines (155 loc) · 6.29 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
158
159
160
161
162
163
164
165
166
167
168
169
170
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(opt("quiet", "No output printed to stdout").short("q"))
.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", "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", "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(opt("root", "Directory to install packages into").value_name("DIR"))
.arg(
opt("registry", "Registry to use")
.value_name("REGISTRY")
.requires("crate")
.conflicts_with_all(&["git", "path"]),
)
.after_help(
"\
This command manages Cargo's local set of installed binary crates. Only
packages which have executable [[bin]] or [[example]] targets can be
installed, and all executables are installed into the installation root's
`bin` folder. The installation root is determined, in order of precedence, by
`--root`, `$CARGO_INSTALL_ROOT`, the `install.root` configuration key, and
finally the home directory (which is either `$CARGO_HOME` if set or
`$HOME/.cargo` by default).
There are multiple sources from which a crate can be installed. The default
location is crates.io but the `--git`, `--path`, and `--registry` flags can
change this source. If the source contains more than one package (such as
crates.io or a git repository with multiple crates) the `<crate>` argument is
required to indicate which crate should be installed.
Crates from crates.io can optionally specify the version they wish to install
via the `--version` flags, and similarly packages from git repositories can
optionally specify the branch, tag, or revision that should be installed. If a
crate has multiple binaries, the `--bin` argument can selectively install only
one of them, and if you'd rather install examples the `--example` argument can
be used as well.
If the package is already installed, Cargo will reinstall it if the installed
version does not appear to be up-to-date. Installing with `--path` will always
build and install, unless there are conflicting binaries from another package.
If the source is crates.io or `--git` then by default the crate will be built
in a temporary target directory. To avoid this, the target directory can be
specified by setting the `CARGO_TARGET_DIR` environment variable to a relative
path. In particular, this can be useful for caching build artifacts on
continuous integration systems.",
)
}
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
let registry = args.registry(config)?;
if let Some(path) = args.value_of_path("path", config) {
config.reload_rooted_at(path)?;
} else {
config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
}
let workspace = args.workspace(config).ok();
let mut compile_opts = args.compile_options(
config,
CompileMode::Build,
workspace.as_ref(),
ProfileChecking::Checked,
)?;
compile_opts.build_config.profile_kind =
args.get_profile_kind(config, ProfileKind::Release, ProfileChecking::Checked)?;
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::Branch("master".to_string())
};
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) = registry {
SourceId::alt_registry(config, ®istry)?
} else {
SourceId::crates_io(config)?
};
let version = args.value_of("version");
let root = args.value_of("root");
if args.is_present("list") {
ops::install_list(root, config)?;
} else {
ops::install(
root,
krates,
source,
from_cwd,
version,
&compile_opts,
args.is_present("force"),
args.is_present("no-track"),
)?;
}
Ok(())
}