+++ /dev/null
-extern crate cargo;
-extern crate clap;
-extern crate env_logger;
-#[macro_use]
-extern crate failure;
-extern crate git2_curl;
-extern crate log;
-#[macro_use]
-extern crate serde_derive;
-extern crate serde_json;
-extern crate toml;
-
-use std::env;
-use std::fs;
-use std::path::{Path, PathBuf};
-use std::collections::BTreeSet;
-
-use cargo::core::shell::Shell;
-use cargo::util::{self, lev_distance, CargoResult, CliResult, Config};
-use cargo::util::{CliError, ProcessError};
-
-mod cli;
-mod command_prelude;
-mod commands;
-
-fn main() {
- env_logger::init();
-
- let mut config = match Config::default() {
- Ok(cfg) => cfg,
- Err(e) => {
- let mut shell = Shell::new();
- cargo::exit_with_error(e.into(), &mut shell)
- }
- };
-
- let result = {
- init_git_transports(&mut config);
- let _token = cargo::util::job::setup();
- cli::main(&mut config)
- };
-
- match result {
- Err(e) => cargo::exit_with_error(e, &mut *config.shell()),
- Ok(()) => {}
- }
-}
-
-fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
- let alias_name = format!("alias.{}", command);
- let mut result = Ok(None);
- match config.get_string(&alias_name) {
- Ok(value) => {
- if let Some(record) = value {
- let alias_commands = record
- .val
- .split_whitespace()
- .map(|s| s.to_string())
- .collect();
- result = Ok(Some(alias_commands));
- }
- }
- Err(_) => {
- let value = config.get_list(&alias_name)?;
- if let Some(record) = value {
- let alias_commands: Vec<String> =
- record.val.iter().map(|s| s.0.to_string()).collect();
- result = Ok(Some(alias_commands));
- }
- }
- }
- result
-}
-
-/// List all runnable commands
-fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
- let prefix = "cargo-";
- let suffix = env::consts::EXE_SUFFIX;
- let mut commands = BTreeSet::new();
- for dir in search_directories(config) {
- let entries = match fs::read_dir(dir) {
- Ok(entries) => entries,
- _ => continue,
- };
- for entry in entries.filter_map(|e| e.ok()) {
- let path = entry.path();
- let filename = match path.file_name().and_then(|s| s.to_str()) {
- Some(filename) => filename,
- _ => continue,
- };
- if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
- continue;
- }
- if is_executable(entry.path()) {
- let end = filename.len() - suffix.len();
- commands.insert((
- filename[prefix.len()..end].to_string(),
- Some(path.display().to_string()),
- ));
- }
- }
- }
-
- for cmd in commands::builtin() {
- commands.insert((cmd.get_name().to_string(), None));
- }
-
- commands
-}
-
-fn find_closest(config: &Config, cmd: &str) -> Option<String> {
- let cmds = list_commands(config);
- // Only consider candidates with a lev_distance of 3 or less so we don't
- // suggest out-of-the-blue options.
- let mut filtered = cmds.iter()
- .map(|&(ref c, _)| (lev_distance(c, cmd), c))
- .filter(|&(d, _)| d < 4)
- .collect::<Vec<_>>();
- filtered.sort_by(|a, b| a.0.cmp(&b.0));
- filtered.get(0).map(|slot| slot.1.clone())
-}
-
-fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> CliResult {
- let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
- let path = search_directories(config)
- .iter()
- .map(|dir| dir.join(&command_exe))
- .find(|file| is_executable(file));
- let command = match path {
- Some(command) => command,
- None => {
- let err = match find_closest(config, cmd) {
- Some(closest) => format_err!(
- "no such subcommand: `{}`\n\n\tDid you mean `{}`?\n",
- cmd,
- closest
- ),
- None => format_err!("no such subcommand: `{}`", cmd),
- };
- return Err(CliError::new(err, 101));
- }
- };
-
- let cargo_exe = config.cargo_exe()?;
- let err = match util::process(&command)
- .env(cargo::CARGO_ENV, cargo_exe)
- .args(args)
- .exec_replace()
- {
- Ok(()) => return Ok(()),
- Err(e) => e,
- };
-
- if let Some(perr) = err.downcast_ref::<ProcessError>() {
- if let Some(code) = perr.exit.as_ref().and_then(|c| c.code()) {
- return Err(CliError::code(code));
- }
- }
- Err(CliError::new(err, 101))
-}
-
-#[cfg(unix)]
-fn is_executable<P: AsRef<Path>>(path: P) -> bool {
- use std::os::unix::prelude::*;
- fs::metadata(path)
- .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
- .unwrap_or(false)
-}
-#[cfg(windows)]
-fn is_executable<P: AsRef<Path>>(path: P) -> bool {
- fs::metadata(path)
- .map(|metadata| metadata.is_file())
- .unwrap_or(false)
-}
-
-fn search_directories(config: &Config) -> Vec<PathBuf> {
- let mut dirs = vec![config.home().clone().into_path_unlocked().join("bin")];
- if let Some(val) = env::var_os("PATH") {
- dirs.extend(env::split_paths(&val));
- }
- dirs
-}
-
-fn init_git_transports(config: &Config) {
- // Only use a custom transport if any HTTP options are specified,
- // such as proxies or custom certificate authorities. The custom
- // transport, however, is not as well battle-tested.
-
- match cargo::ops::needs_custom_http_transport(config) {
- Ok(true) => {}
- _ => return,
- }
-
- let handle = match cargo::ops::http_handle(config) {
- Ok(handle) => handle,
- Err(..) => return,
- };
-
- // The unsafety of the registration function derives from two aspects:
- //
- // 1. This call must be synchronized with all other registration calls as
- // well as construction of new transports.
- // 2. The argument is leaked.
- //
- // We're clear on point (1) because this is only called at the start of this
- // binary (we know what the state of the world looks like) and we're mostly
- // clear on point (2) because we'd only free it after everything is done
- // anyway
- unsafe {
- git2_curl::register(handle);
- }
-}
--- /dev/null
+extern crate clap;
+
+use clap::{AppSettings, Arg, ArgMatches};
+
+use cargo::{self, CliResult, Config};
+
+use super::list_commands;
+use super::commands;
+use command_prelude::*;
+
+pub fn main(config: &mut Config) -> CliResult {
+ let args = cli().get_matches_safe()?;
+
+ if args.value_of("unstable-features") == Some("help") {
+ println!(
+ "
+Available unstable (nightly-only) flags:
+
+ -Z avoid-dev-deps -- Avoid installing dev-dependencies if possible
+ -Z minimal-versions -- Install minimal dependency versions instead of maximum
+ -Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
+ -Z offline -- Offline mode that does not perform network requests
+ -Z unstable-options -- Allow the usage of unstable options such as --registry
+
+Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
+ );
+ return Ok(());
+ }
+
+ let is_verbose = args.occurrences_of("verbose") > 0;
+ if args.is_present("version") {
+ let version = cargo::version();
+ println!("{}", version);
+ if is_verbose {
+ println!(
+ "release: {}.{}.{}",
+ version.major, version.minor, version.patch
+ );
+ if let Some(ref cfg) = version.cfg_info {
+ if let Some(ref ci) = cfg.commit_info {
+ println!("commit-hash: {}", ci.commit_hash);
+ println!("commit-date: {}", ci.commit_date);
+ }
+ }
+ }
+ return Ok(());
+ }
+
+ if let Some(ref code) = args.value_of("explain") {
+ let mut procss = config.rustc(None)?.process();
+ procss.arg("--explain").arg(code).exec()?;
+ return Ok(());
+ }
+
+ if args.is_present("list") {
+ println!("Installed Commands:");
+ for command in list_commands(config) {
+ let (command, path) = command;
+ if is_verbose {
+ match path {
+ Some(p) => println!(" {:<20} {}", command, p),
+ None => println!(" {:<20}", command),
+ }
+ } else {
+ println!(" {}", command);
+ }
+ }
+ return Ok(());
+ }
+
+ let args = expand_aliases(config, args)?;
+
+ execute_subcommand(config, args)
+}
+
+fn expand_aliases(
+ config: &mut Config,
+ args: ArgMatches<'static>,
+) -> Result<ArgMatches<'static>, CliError> {
+ if let (cmd, Some(args)) = args.subcommand() {
+ match (
+ commands::builtin_exec(cmd),
+ super::aliased_command(config, cmd)?,
+ ) {
+ (None, Some(mut alias)) => {
+ alias.extend(
+ args.values_of("")
+ .unwrap_or_default()
+ .map(|s| s.to_string()),
+ );
+ let args = cli()
+ .setting(AppSettings::NoBinaryName)
+ .get_matches_from_safe(alias)?;
+ return expand_aliases(config, args);
+ }
+ (Some(_), Some(_)) => {
+ config.shell().warn(format!(
+ "alias `{}` is ignored, because it is shadowed by a built in command",
+ cmd
+ ))?;
+ }
+ (_, None) => {}
+ }
+ };
+ Ok(args)
+}
+
+fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
+ let (cmd, subcommand_args) = match args.subcommand() {
+ (cmd, Some(args)) => (cmd, args),
+ _ => {
+ cli().print_help()?;
+ return Ok(());
+ }
+ };
+
+ let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
+
+ config.configure(
+ args.occurrences_of("verbose") as u32,
+ if args.is_present("quiet") {
+ Some(true)
+ } else {
+ None
+ },
+ &args.value_of("color").map(|s| s.to_string()),
+ args.is_present("frozen"),
+ args.is_present("locked"),
+ arg_target_dir,
+ &args.values_of_lossy("unstable-features")
+ .unwrap_or_default(),
+ )?;
+
+ if let Some(exec) = commands::builtin_exec(cmd) {
+ return exec(config, subcommand_args);
+ }
+
+ let mut ext_args: Vec<&str> = vec![cmd];
+ ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
+ super::execute_external_subcommand(config, cmd, &ext_args)
+}
+
+fn cli() -> App {
+ let app = App::new("cargo")
+ .settings(&[
+ AppSettings::UnifiedHelpMessage,
+ AppSettings::DeriveDisplayOrder,
+ AppSettings::VersionlessSubcommands,
+ AppSettings::AllowExternalSubcommands,
+ ])
+ .about("")
+ .template(
+ "\
+Rust's package manager
+
+USAGE:
+ {usage}
+
+OPTIONS:
+{unified}
+
+Some common cargo commands are (see all commands with --list):
+ build Compile the current project
+ check Analyze the current project and report errors, but don't build object files
+ clean Remove the target directory
+ doc Build this project's and its dependencies' documentation
+ new Create a new cargo project
+ init Create a new cargo project in an existing directory
+ run Build and execute src/main.rs
+ test Run the tests
+ bench Run the benchmarks
+ update Update dependencies listed in Cargo.lock
+ search Search registry for crates
+ publish Package and upload this project to the registry
+ install Install a Rust binary
+ uninstall Uninstall a Rust binary
+
+See 'cargo help <command>' for more information on a specific command.\n",
+ )
+ .arg(opt("version", "Print version info and exit").short("V"))
+ .arg(opt("list", "List installed commands"))
+ .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
+ .arg(
+ opt(
+ "verbose",
+ "Use verbose output (-vv very verbose/build.rs output)",
+ ).short("v")
+ .multiple(true)
+ .global(true),
+ )
+ .arg(
+ opt("quiet", "No output printed to stdout")
+ .short("q")
+ .global(true),
+ )
+ .arg(
+ opt("color", "Coloring: auto, always, never")
+ .value_name("WHEN")
+ .global(true),
+ )
+ .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
+ .arg(opt("locked", "Require Cargo.lock is up to date").global(true))
+ .arg(
+ Arg::with_name("unstable-features")
+ .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
+ .short("Z")
+ .value_name("FLAG")
+ .multiple(true)
+ .number_of_values(1)
+ .global(true),
+ )
+ .subcommands(commands::builtin());
+ app
+}
--- /dev/null
+use std::path::PathBuf;
+use std::fs;
+
+use clap::{self, SubCommand};
+use cargo::CargoResult;
+use cargo::core::Workspace;
+use cargo::ops::{CompileFilter, CompileMode, CompileOptions, MessageFormat, NewOptions, Packages,
+ VersionControl};
+use cargo::util::paths;
+use cargo::util::important_paths::find_root_manifest_for_wd;
+
+pub use clap::{AppSettings, Arg, ArgMatches};
+pub use cargo::{CliError, CliResult, Config};
+
+pub type App = clap::App<'static, 'static>;
+
+pub trait AppExt: Sized {
+ fn _arg(self, arg: Arg<'static, 'static>) -> Self;
+
+ fn arg_package_spec(
+ self,
+ package: &'static str,
+ all: &'static str,
+ exclude: &'static str,
+ ) -> Self {
+ self.arg_package_spec_simple(package)
+ ._arg(opt("all", all))
+ ._arg(multi_opt("exclude", "SPEC", exclude))
+ }
+
+ fn arg_package_spec_simple(self, package: &'static str) -> Self {
+ self._arg(multi_opt("package", "SPEC", package).short("p"))
+ }
+
+ fn arg_package(self, package: &'static str) -> Self {
+ self._arg(opt("package", package).short("p").value_name("SPEC"))
+ }
+
+ fn arg_jobs(self) -> Self {
+ self._arg(
+ opt("jobs", "Number of parallel jobs, defaults to # of CPUs")
+ .short("j")
+ .value_name("N"),
+ )
+ }
+
+ fn arg_targets_all(
+ self,
+ lib: &'static str,
+ bin: &'static str,
+ bins: &'static str,
+ example: &'static str,
+ examples: &'static str,
+ test: &'static str,
+ tests: &'static str,
+ bench: &'static str,
+ benches: &'static str,
+ all: &'static str,
+ ) -> Self {
+ self.arg_targets_lib_bin(lib, bin, bins)
+ ._arg(multi_opt("example", "NAME", example))
+ ._arg(opt("examples", examples))
+ ._arg(multi_opt("test", "NAME", test))
+ ._arg(opt("tests", tests))
+ ._arg(multi_opt("bench", "NAME", bench))
+ ._arg(opt("benches", benches))
+ ._arg(opt("all-targets", all))
+ }
+
+ fn arg_targets_lib_bin(self, lib: &'static str, bin: &'static str, bins: &'static str) -> Self {
+ self._arg(opt("lib", lib))
+ ._arg(multi_opt("bin", "NAME", bin))
+ ._arg(opt("bins", bins))
+ }
+
+ fn arg_targets_bins_examples(
+ self,
+ bin: &'static str,
+ bins: &'static str,
+ example: &'static str,
+ examples: &'static str,
+ ) -> Self {
+ self._arg(multi_opt("bin", "NAME", bin))
+ ._arg(opt("bins", bins))
+ ._arg(multi_opt("example", "NAME", example))
+ ._arg(opt("examples", examples))
+ }
+
+ fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self {
+ self._arg(multi_opt("bin", "NAME", bin))
+ ._arg(multi_opt("example", "NAME", example))
+ }
+
+ fn arg_features(self) -> Self {
+ self._arg(
+ opt("features", "Space-separated list of features to activate").value_name("FEATURES"),
+ )._arg(opt("all-features", "Activate all available features"))
+ ._arg(opt(
+ "no-default-features",
+ "Do not activate the `default` feature",
+ ))
+ }
+
+ fn arg_release(self, release: &'static str) -> Self {
+ self._arg(opt("release", release))
+ }
+
+ fn arg_doc(self, doc: &'static str) -> Self {
+ self._arg(opt("doc", doc))
+ }
+
+ fn arg_target_triple(self, target: &'static str) -> Self {
+ self._arg(opt("target", target).value_name("TRIPLE"))
+ }
+
+ fn arg_target_dir(self) -> Self {
+ self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"))
+ }
+
+ fn arg_manifest_path(self) -> Self {
+ self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH"))
+ }
+
+ fn arg_message_format(self) -> Self {
+ self._arg(
+ opt("message-format", "Error format")
+ .value_name("FMT")
+ .case_insensitive(true)
+ .possible_values(&["human", "json"])
+ .default_value("human"),
+ )
+ }
+
+ fn arg_new_opts(self) -> Self {
+ self._arg(
+ opt(
+ "vcs",
+ "\
+ Initialize a new repository for the given version \
+ control system (git, hg, pijul, or fossil) or do not \
+ initialize any version control at all (none), overriding \
+ a global configuration.",
+ ).value_name("VCS")
+ .possible_values(&["git", "hg", "pijul", "fossil", "none"]),
+ )._arg(opt("bin", "Use a binary (application) template [default]"))
+ ._arg(opt("lib", "Use a library template"))
+ ._arg(
+ opt(
+ "name",
+ "Set the resulting package name, defaults to the directory name",
+ ).value_name("NAME"),
+ )
+ }
+
+ fn arg_index(self) -> Self {
+ self._arg(opt("index", "Registry index to upload the package to").value_name("INDEX"))
+ ._arg(
+ opt("host", "DEPRECATED, renamed to '--index'")
+ .value_name("HOST")
+ .hidden(true),
+ )
+ }
+}
+
+impl AppExt for App {
+ fn _arg(self, arg: Arg<'static, 'static>) -> Self {
+ self.arg(arg)
+ }
+}
+
+pub fn opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> {
+ Arg::with_name(name).long(name).help(help)
+}
+
+pub fn multi_opt(
+ name: &'static str,
+ value_name: &'static str,
+ help: &'static str,
+) -> Arg<'static, 'static> {
+ // Note that all `.multiple(true)` arguments in Cargo should specify
+ // `.number_of_values(1)` as well, so that `--foo val1 val2` is
+ // **not** parsed as `foo` with values ["val1", "val2"].
+ // `number_of_values` should become the default in clap 3.
+ opt(name, help)
+ .value_name(value_name)
+ .multiple(true)
+ .number_of_values(1)
+}
+
+pub fn subcommand(name: &'static str) -> App {
+ SubCommand::with_name(name).settings(&[
+ AppSettings::UnifiedHelpMessage,
+ AppSettings::DeriveDisplayOrder,
+ AppSettings::DontCollapseArgsInUsage,
+ ])
+}
+
+pub trait ArgMatchesExt {
+ fn value_of_u32(&self, name: &str) -> CargoResult<Option<u32>> {
+ let arg = match self._value_of(name) {
+ None => None,
+ Some(arg) => Some(arg.parse::<u32>().map_err(|_| {
+ clap::Error::value_validation_auto(format!("could not parse `{}` as a number", arg))
+ })?),
+ };
+ Ok(arg)
+ }
+
+ /// Returns value of the `name` command-line argument as an absolute path
+ fn value_of_path(&self, name: &str, config: &Config) -> Option<PathBuf> {
+ self._value_of(name).map(|path| config.cwd().join(path))
+ }
+
+ fn root_manifest(&self, config: &Config) -> CargoResult<PathBuf> {
+ if let Some(path) = self.value_of_path("manifest-path", config) {
+ // In general, we try to avoid normalizing paths in Cargo,
+ // but in this particular case we need it to fix #3586.
+ let path = paths::normalize_path(&path);
+ if !path.ends_with("Cargo.toml") {
+ bail!("the manifest-path must be a path to a Cargo.toml file")
+ }
+ if !fs::metadata(&path).is_ok() {
+ bail!(
+ "manifest path `{}` does not exist",
+ self._value_of("manifest-path").unwrap()
+ )
+ }
+ return Ok(path);
+ }
+ find_root_manifest_for_wd(config.cwd())
+ }
+
+ fn workspace<'a>(&self, config: &'a Config) -> CargoResult<Workspace<'a>> {
+ let root = self.root_manifest(config)?;
+ let mut ws = Workspace::new(&root, config)?;
+ if config.cli_unstable().avoid_dev_deps {
+ ws.set_require_optional_deps(false);
+ }
+ Ok(ws)
+ }
+
+ fn jobs(&self) -> CargoResult<Option<u32>> {
+ self.value_of_u32("jobs")
+ }
+
+ fn target(&self) -> Option<String> {
+ self._value_of("target").map(|s| s.to_string())
+ }
+
+ fn compile_options<'a>(
+ &self,
+ config: &'a Config,
+ mode: CompileMode,
+ ) -> CargoResult<CompileOptions<'a>> {
+ let spec = Packages::from_flags(
+ self._is_present("all"),
+ self._values_of("exclude"),
+ self._values_of("package"),
+ )?;
+
+ let message_format = match self._value_of("message-format") {
+ None => MessageFormat::Human,
+ Some(f) => {
+ if f.eq_ignore_ascii_case("json") {
+ MessageFormat::Json
+ } else if f.eq_ignore_ascii_case("human") {
+ MessageFormat::Human
+ } else {
+ panic!("Impossible message format: {:?}", f)
+ }
+ }
+ };
+
+ let opts = CompileOptions {
+ config,
+ jobs: self.jobs()?,
+ target: self.target(),
+ features: self._values_of("features"),
+ all_features: self._is_present("all-features"),
+ no_default_features: self._is_present("no-default-features"),
+ spec,
+ mode,
+ release: self._is_present("release"),
+ filter: CompileFilter::new(
+ self._is_present("lib"),
+ self._values_of("bin"),
+ self._is_present("bins"),
+ self._values_of("test"),
+ self._is_present("tests"),
+ self._values_of("example"),
+ self._is_present("examples"),
+ self._values_of("bench"),
+ self._is_present("benches"),
+ self._is_present("all-targets"),
+ ),
+ message_format,
+ target_rustdoc_args: None,
+ target_rustc_args: None,
+ export_dir: None,
+ };
+ Ok(opts)
+ }
+
+ fn compile_options_for_single_package<'a>(
+ &self,
+ config: &'a Config,
+ mode: CompileMode,
+ ) -> CargoResult<CompileOptions<'a>> {
+ let mut compile_opts = self.compile_options(config, mode)?;
+ compile_opts.spec = Packages::Packages(self._values_of("package"));
+ Ok(compile_opts)
+ }
+
+ fn new_options(&self, config: &Config) -> CargoResult<NewOptions> {
+ let vcs = self._value_of("vcs").map(|vcs| match vcs {
+ "git" => VersionControl::Git,
+ "hg" => VersionControl::Hg,
+ "pijul" => VersionControl::Pijul,
+ "fossil" => VersionControl::Fossil,
+ "none" => VersionControl::NoVcs,
+ vcs => panic!("Impossible vcs: {:?}", vcs),
+ });
+ NewOptions::new(
+ vcs,
+ self._is_present("bin"),
+ self._is_present("lib"),
+ self.value_of_path("path", config).unwrap(),
+ self._value_of("name").map(|s| s.to_string()),
+ )
+ }
+
+ fn registry(&self, config: &Config) -> CargoResult<Option<String>> {
+ match self._value_of("registry") {
+ Some(registry) => {
+ if !config.cli_unstable().unstable_options {
+ return Err(format_err!(
+ "registry option is an unstable feature and \
+ requires -Zunstable-options to use."
+ ).into());
+ }
+ Ok(Some(registry.to_string()))
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn index(&self, config: &Config) -> CargoResult<Option<String>> {
+ // TODO: Deprecated
+ // remove once it has been decided --host can be removed
+ // We may instead want to repurpose the host flag, as
+ // mentioned in this issue
+ // https://github.com/rust-lang/cargo/issues/4208
+ let msg = "The flag '--host' is no longer valid.
+
+Previous versions of Cargo accepted this flag, but it is being
+deprecated. The flag is being renamed to 'index', as the flag
+wants the location of the index. Please use '--index' instead.
+
+This will soon become a hard error, so it's either recommended
+to update to a fixed version or contact the upstream maintainer
+about this warning.";
+
+ let index = match self._value_of("host") {
+ Some(host) => {
+ config.shell().warn(&msg)?;
+ Some(host.to_string())
+ }
+ None => self._value_of("index").map(|s| s.to_string()),
+ };
+ Ok(index)
+ }
+
+ fn _value_of(&self, name: &str) -> Option<&str>;
+
+ fn _values_of(&self, name: &str) -> Vec<String>;
+
+ fn _is_present(&self, name: &str) -> bool;
+}
+
+impl<'a> ArgMatchesExt for ArgMatches<'a> {
+ fn _value_of(&self, name: &str) -> Option<&str> {
+ self.value_of(name)
+ }
+
+ fn _values_of(&self, name: &str) -> Vec<String> {
+ self.values_of(name)
+ .unwrap_or_default()
+ .map(|s| s.to_string())
+ .collect()
+ }
+
+ fn _is_present(&self, name: &str) -> bool {
+ self.is_present(name)
+ }
+}
+
+pub fn values(args: &ArgMatches, name: &str) -> Vec<String> {
+ args.values_of(name)
+ .unwrap_or_default()
+ .map(|s| s.to_string())
+ .collect()
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode, TestOptions};
+
+pub fn cli() -> App {
+ subcommand("bench")
+ .setting(AppSettings::TrailingVarArg)
+ .about("Execute all benchmarks of a local package")
+ .arg(
+ Arg::with_name("BENCHNAME")
+ .help("If specified, only run benches containing this string in their names"),
+ )
+ .arg(
+ Arg::with_name("args")
+ .help("Arguments for the bench binary")
+ .multiple(true)
+ .last(true),
+ )
+ .arg_targets_all(
+ "Benchmark only this package's library",
+ "Benchmark only the specified binary",
+ "Benchmark all binaries",
+ "Benchmark only the specified example",
+ "Benchmark all examples",
+ "Benchmark only the specified test target",
+ "Benchmark all tests",
+ "Benchmark only the specified bench target",
+ "Benchmark all benches",
+ "Benchmark all targets (default)",
+ )
+ .arg(opt("no-run", "Compile, but don't run benchmarks"))
+ .arg_package_spec(
+ "Package to run benchmarks for",
+ "Benchmark all packages in the workspace",
+ "Exclude packages from the benchmark",
+ )
+ .arg_jobs()
+ .arg_features()
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .arg(opt(
+ "no-fail-fast",
+ "Run all benchmarks regardless of failure",
+ ))
+ .after_help(
+ "\
+The benchmark filtering argument `BENCHNAME` and all the arguments following the
+two dashes (`--`) are passed to the benchmark binaries and thus to libtest
+(rustc's built in unit-test and micro-benchmarking framework). If you're
+passing arguments to both Cargo and the binary, the ones after `--` go to the
+binary, the ones before go to Cargo. For details about libtest's arguments see
+the output of `cargo bench -- --help`.
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be benchmarked. If it is not given, then
+the current package is benchmarked. For more information on SPEC and its format,
+see the `cargo help pkgid` command.
+
+All packages in the workspace are benchmarked if the `--all` flag is supplied. The
+`--all` flag is automatically assumed for a virtual manifest.
+Note that `--exclude` has to be specified in conjunction with the `--all` flag.
+
+The --jobs argument affects the building of the benchmark executable but does
+not affect how many jobs are used when running the benchmarks.
+
+Compilation can be customized with the `bench` profile in the manifest.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let mut compile_opts = args.compile_options(config, CompileMode::Bench)?;
+ compile_opts.release = true;
+
+ let ops = TestOptions {
+ no_run: args.is_present("no-run"),
+ no_fail_fast: args.is_present("no-fail-fast"),
+ only_doc: false,
+ compile_opts,
+ };
+
+ let mut bench_args = vec![];
+ bench_args.extend(
+ args.value_of("BENCHNAME")
+ .into_iter()
+ .map(|s| s.to_string()),
+ );
+ bench_args.extend(
+ args.values_of("args")
+ .unwrap_or_default()
+ .map(|s| s.to_string()),
+ );
+
+ let err = ops::run_benches(&ws, &ops, &bench_args)?;
+ match err {
+ None => Ok(()),
+ Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
+ Some(i) => CliError::new(format_err!("bench failed"), i),
+ None => CliError::new(err.into(), 101),
+ }),
+ }
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode};
+
+pub fn cli() -> App {
+ subcommand("build")
+ .alias("b")
+ .about("Compile a local package and all of its dependencies")
+ .arg_package_spec(
+ "Package to build",
+ "Build all packages in the workspace",
+ "Exclude packages from the build",
+ )
+ .arg_jobs()
+ .arg_targets_all(
+ "Build only this package's library",
+ "Build only the specified binary",
+ "Build all binaries",
+ "Build only the specified example",
+ "Build all examples",
+ "Build only the specified test target",
+ "Build all tests",
+ "Build only the specified bench target",
+ "Build all benches",
+ "Build all targets (lib and bin targets by default)",
+ )
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg_features()
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH"))
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be built. If it is not given, then the
+current package is built. For more information on SPEC and its format, see the
+`cargo help pkgid` command.
+
+All packages in the workspace are built if the `--all` flag is supplied. The
+`--all` flag is automatically assumed for a virtual manifest.
+Note that `--exclude` has to be specified in conjunction with the `--all` flag.
+
+Compilation can be configured via the use of profiles which are configured in
+the manifest. The default profile for this command is `dev`, but passing
+the --release flag will use the `release` profile instead.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let mut compile_opts = args.compile_options(config, CompileMode::Build)?;
+ compile_opts.export_dir = args.value_of_path("out-dir", config);
+ if compile_opts.export_dir.is_some() && !config.cli_unstable().unstable_options {
+ Err(format_err!(
+ "`--out-dir` flag is unstable, pass `-Z unstable-options` to enable it"
+ ))?;
+ };
+ ops::compile(&ws, &compile_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode};
+
+pub fn cli() -> App {
+ subcommand("check")
+ .about("Check a local package and all of its dependencies for errors")
+ .arg_package_spec(
+ "Package(s) to check",
+ "Check all packages in the workspace",
+ "Exclude packages from the check",
+ )
+ .arg_jobs()
+ .arg_targets_all(
+ "Check only this package's library",
+ "Check only the specified binary",
+ "Check all binaries",
+ "Check only the specified example",
+ "Check all examples",
+ "Check only the specified test target",
+ "Check all tests",
+ "Check only the specified bench target",
+ "Check all benches",
+ "Check all targets (lib and bin targets by default)",
+ )
+ .arg_release("Check artifacts in release mode, with optimizations")
+ .arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
+ .arg_features()
+ .arg_target_triple("Check for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be built. If it is not given, then the
+current package is built. For more information on SPEC and its format, see the
+`cargo help pkgid` command.
+
+All packages in the workspace are checked if the `--all` flag is supplied. The
+`--all` flag is automatically assumed for a virtual manifest.
+Note that `--exclude` has to be specified in conjunction with the `--all` flag.
+
+Compilation can be configured via the use of profiles which are configured in
+the manifest. The default profile for this command is `dev`, but passing
+the --release flag will use the `release` profile instead.
+
+The `--profile test` flag can be used to check unit tests with the
+`#[cfg(test)]` attribute.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let test = match args.value_of("profile") {
+ Some("test") => true,
+ None => false,
+ Some(profile) => {
+ let err = format_err!(
+ "unknown profile: `{}`, only `test` is \
+ currently supported",
+ profile
+ );
+ return Err(CliError::new(err, 101));
+ }
+ };
+ let mode = CompileMode::Check { test };
+ let compile_opts = args.compile_options(config, mode)?;
+ ops::compile(&ws, &compile_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CleanOptions};
+
+pub fn cli() -> App {
+ subcommand("clean")
+ .about("Remove artifacts that cargo has generated in the past")
+ .arg_package_spec_simple("Package to clean artifacts for")
+ .arg_manifest_path()
+ .arg_target_triple("Target triple to clean output for (default all)")
+ .arg_target_dir()
+ .arg_release("Whether or not to clean release artifacts")
+ .arg_doc("Whether or not to clean just the documentation directory")
+ .after_help(
+ "\
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package's artifacts should be cleaned out. If it is not
+given, then all packages' artifacts are removed. For more information on SPEC
+and its format, see the `cargo help pkgid` command.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let opts = CleanOptions {
+ config,
+ spec: values(args, "package"),
+ target: args.target(),
+ release: args.is_present("release"),
+ doc: args.is_present("doc"),
+ };
+ ops::clean(&ws, &opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode, DocOptions};
+
+pub fn cli() -> App {
+ subcommand("doc")
+ .about("Build a package's documentation")
+ .arg(opt(
+ "open",
+ "Opens the docs in a browser after the operation",
+ ))
+ .arg_package_spec(
+ "Package to document",
+ "Document all packages in the workspace",
+ "Exclude packages from the build",
+ )
+ .arg(opt("no-deps", "Don't build documentation for dependencies"))
+ .arg_jobs()
+ .arg_targets_lib_bin(
+ "Document only this package's library",
+ "Document only the specified binary",
+ "Document all binaries",
+ )
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg_features()
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+By default the documentation for the local package and all dependencies is
+built. The output is all placed in `target/doc` in rustdoc's usual format.
+
+All packages in the workspace are documented if the `--all` flag is supplied. The
+`--all` flag is automatically assumed for a virtual manifest.
+Note that `--exclude` has to be specified in conjunction with the `--all` flag.
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be documented. If it is not given, then the
+current package is documented. For more information on SPEC and its format, see
+the `cargo help pkgid` command.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let mode = CompileMode::Doc {
+ deps: !args.is_present("no-deps"),
+ };
+ let compile_opts = args.compile_options(config, mode)?;
+ let doc_opts = DocOptions {
+ open_result: args.is_present("open"),
+ compile_opts,
+ };
+ ops::doc(&ws, &doc_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+use cargo::ops::FetchOptions;
+
+pub fn cli() -> App {
+ subcommand("fetch")
+ .about("Fetch dependencies of a package from the network")
+ .arg_manifest_path()
+ .arg_target_triple("Fetch dependencies for the target triple")
+ .after_help(
+ "\
+If a lockfile is available, this command will ensure that all of the git
+dependencies and/or registries dependencies are downloaded and locally
+available. The network is never touched after a `cargo fetch` unless
+the lockfile changes.
+
+If the lockfile is not available, then this is the equivalent of
+`cargo generate-lockfile`. A lockfile is generated and dependencies are also
+all updated.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+
+ let opts = FetchOptions {
+ config,
+ target: args.target(),
+ };
+ ops::fetch(&ws, &opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("generate-lockfile")
+ .about("Generate the lockfile for a project")
+ .arg_manifest_path()
+ .after_help(
+ "\
+If a lockfile is available, this command will ensure that all of the git
+dependencies and/or registries dependencies are downloaded and locally
+available. The network is never touched after a `cargo fetch` unless
+the lockfile changes.
+
+If the lockfile is not available, then this is the equivalent of
+`cargo generate-lockfile`. A lockfile is generated and dependencies are also
+all updated.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ ops::generate_lockfile(&ws)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::core::{GitReference, Source, SourceId};
+use cargo::sources::GitSource;
+use cargo::util::ToUrl;
+
+pub fn cli() -> App {
+ subcommand("git-checkout")
+ .about("Checkout a copy of a Git repository")
+ .arg(
+ Arg::with_name("url")
+ .long("url")
+ .value_name("URL")
+ .required(true),
+ )
+ .arg(
+ Arg::with_name("reference")
+ .long("reference")
+ .value_name("REF")
+ .required(true),
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let url = args.value_of("url").unwrap().to_url()?;
+ let reference = args.value_of("reference").unwrap();
+
+ let reference = GitReference::Branch(reference.to_string());
+ let source_id = SourceId::for_git(&url, reference)?;
+
+ let mut source = GitSource::new(&source_id, config)?;
+
+ source.update()?;
+
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("init")
+ .about("Create a new cargo package in an existing directory")
+ .arg(Arg::with_name("path").default_value("."))
+ .arg_new_opts()
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let opts = args.new_options(config)?;
+ ops::init(&opts, config)?;
+ config
+ .shell()
+ .status("Created", format!("{} project", opts.kind))?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::core::{GitReference, SourceId};
+use cargo::ops::{self, CompileMode};
+use cargo::util::ToUrl;
+
+pub fn cli() -> App {
+ subcommand("install")
+ .about("Install a Rust binary")
+ .arg(Arg::with_name("crate").empty_values(false).multiple(true))
+ .arg(
+ opt("version", "Specify a version to install from crates.io")
+ .alias("vers")
+ .value_name("VERSION"),
+ )
+ .arg(opt("git", "Git URL to install the specified crate from").value_name("URL"))
+ .arg(opt("branch", "Branch to use when installing from git").value_name("BRANCH"))
+ .arg(opt("tag", "Tag to use when installing from git").value_name("TAG"))
+ .arg(opt("rev", "Specific commit to use when installing from git").value_name("SHA"))
+ .arg(opt("path", "Filesystem path to local crate to install").value_name("PATH"))
+ .arg(opt(
+ "list",
+ "list all installed packages and their versions",
+ ))
+ .arg_jobs()
+ .arg(opt("force", "Force overwriting existing crates or binaries").short("f"))
+ .arg_features()
+ .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(opt("root", "Directory to install packages into").value_name("DIR"))
+ .after_help(
+ "\
+This command manages Cargo's local set of installed binary crates. Only packages
+which have [[bin]] targets can be installed, and all binaries 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` and `--path` 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 `--vers` 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.
+
+By default cargo will refuse to overwrite existing binaries. The `--force` flag
+enables overwriting existing binaries. Thus you can reinstall a crate with
+`cargo install --force <crate>`.
+
+As a special convenience, omitting the <crate> specification entirely will
+install the crate in the current directory. That is, `install` is equivalent to
+the more explicit `install --path .`.
+
+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 mut compile_opts = args.compile_options(config, CompileMode::Build)?;
+ compile_opts.release = !args.is_present("debug");
+
+ 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.to_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 {
+ 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"),
+ )?;
+ }
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::print_json;
+
+pub fn cli() -> App {
+ subcommand("locate-project")
+ .about("Print a JSON representation of a Cargo.toml file's location")
+ .arg_manifest_path()
+}
+
+#[derive(Serialize)]
+pub struct ProjectLocation {
+ root: String,
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let root = args.root_manifest(config)?;
+
+ let root = root.to_str()
+ .ok_or_else(|| {
+ format_err!(
+ "your project path contains characters \
+ not representable in Unicode"
+ )
+ })
+ .map_err(|e| CliError::new(e, 1))?
+ .to_string();
+
+ let location = ProjectLocation { root };
+
+ print_json(&location);
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use std::io::{self, BufRead};
+
+use cargo::core::{Source, SourceId};
+use cargo::sources::RegistrySource;
+use cargo::util::{CargoError, CargoResultExt};
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("login")
+ .about(
+ "Save an api token from the registry locally. \
+ If token is not specified, it will be read from stdin.",
+ )
+ .arg(Arg::with_name("token"))
+ .arg(opt("host", "Host to set the token for").value_name("HOST"))
+ .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let registry = args.registry(config)?;
+
+ let token = match args.value_of("token") {
+ Some(token) => token.to_string(),
+ None => {
+ let host = match registry {
+ Some(ref _registry) => {
+ return Err(format_err!(
+ "token must be provided when \
+ --registry is provided."
+ ).into());
+ }
+ None => {
+ let src = SourceId::crates_io(config)?;
+ let mut src = RegistrySource::remote(&src, config);
+ src.update()?;
+ let config = src.config()?.unwrap();
+ args.value_of("host")
+ .map(|s| s.to_string())
+ .unwrap_or(config.api.unwrap())
+ }
+ };
+ println!("please visit {}me and paste the API Token below", host);
+ let mut line = String::new();
+ let input = io::stdin();
+ input
+ .lock()
+ .read_line(&mut line)
+ .chain_err(|| "failed to read stdin")
+ .map_err(CargoError::from)?;
+ line.trim().to_string()
+ }
+ };
+
+ ops::registry_login(config, token, registry)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, OutputMetadataOptions};
+use cargo::print_json;
+
+pub fn cli() -> App {
+ subcommand("metadata")
+ .about(
+ "Output the resolved dependencies of a project, \
+ the concrete used versions including overrides, \
+ in machine-readable format",
+ )
+ .arg_features()
+ .arg(opt(
+ "no-deps",
+ "Output information only about the root package \
+ and don't fetch dependencies",
+ ))
+ .arg_manifest_path()
+ .arg(
+ opt("format-version", "Format version")
+ .value_name("VERSION")
+ .possible_value("1"),
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+
+ let version = match args.value_of("format-version") {
+ None => {
+ config.shell().warn(
+ "\
+ please specify `--format-version` flag explicitly \
+ to avoid compatibility problems",
+ )?;
+ 1
+ }
+ Some(version) => version.parse().unwrap(),
+ };
+
+ let options = OutputMetadataOptions {
+ features: values(args, "features"),
+ all_features: args.is_present("all-features"),
+ no_default_features: args.is_present("no-default-features"),
+ no_deps: args.is_present("no-deps"),
+ version,
+ };
+
+ let result = ops::output_metadata(&ws, &options)?;
+ print_json(&result);
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+pub fn builtin() -> Vec<App> {
+ vec![
+ bench::cli(),
+ build::cli(),
+ check::cli(),
+ clean::cli(),
+ doc::cli(),
+ fetch::cli(),
+ generate_lockfile::cli(),
+ git_checkout::cli(),
+ init::cli(),
+ install::cli(),
+ locate_project::cli(),
+ login::cli(),
+ metadata::cli(),
+ new::cli(),
+ owner::cli(),
+ package::cli(),
+ pkgid::cli(),
+ publish::cli(),
+ read_manifest::cli(),
+ run::cli(),
+ rustc::cli(),
+ rustdoc::cli(),
+ search::cli(),
+ test::cli(),
+ uninstall::cli(),
+ update::cli(),
+ verify_project::cli(),
+ version::cli(),
+ yank::cli(),
+ ]
+}
+
+pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches) -> CliResult> {
+ let f = match cmd {
+ "bench" => bench::exec,
+ "build" => build::exec,
+ "check" => check::exec,
+ "clean" => clean::exec,
+ "doc" => doc::exec,
+ "fetch" => fetch::exec,
+ "generate-lockfile" => generate_lockfile::exec,
+ "git-checkout" => git_checkout::exec,
+ "init" => init::exec,
+ "install" => install::exec,
+ "locate-project" => locate_project::exec,
+ "login" => login::exec,
+ "metadata" => metadata::exec,
+ "new" => new::exec,
+ "owner" => owner::exec,
+ "package" => package::exec,
+ "pkgid" => pkgid::exec,
+ "publish" => publish::exec,
+ "read-manifest" => read_manifest::exec,
+ "run" => run::exec,
+ "rustc" => rustc::exec,
+ "rustdoc" => rustdoc::exec,
+ "search" => search::exec,
+ "test" => test::exec,
+ "uninstall" => uninstall::exec,
+ "update" => update::exec,
+ "verify-project" => verify_project::exec,
+ "version" => version::exec,
+ "yank" => yank::exec,
+ _ => return None,
+ };
+ Some(f)
+}
+
+pub mod bench;
+pub mod build;
+pub mod check;
+pub mod clean;
+pub mod doc;
+pub mod fetch;
+pub mod generate_lockfile;
+pub mod git_checkout;
+pub mod init;
+pub mod install;
+pub mod locate_project;
+pub mod login;
+pub mod metadata;
+pub mod new;
+pub mod owner;
+pub mod package;
+pub mod pkgid;
+pub mod publish;
+pub mod read_manifest;
+pub mod run;
+pub mod rustc;
+pub mod rustdoc;
+pub mod search;
+pub mod test;
+pub mod uninstall;
+pub mod update;
+pub mod verify_project;
+pub mod version;
+pub mod yank;
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("new")
+ .about("Create a new cargo package at <path>")
+ .arg(Arg::with_name("path").required(true))
+ .arg_new_opts()
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let opts = args.new_options(config)?;
+
+ ops::new(&opts, config)?;
+ let path = args.value_of("path").unwrap();
+ let project_name = if let Some(name) = args.value_of("name") {
+ name
+ } else {
+ path
+ };
+ config
+ .shell()
+ .status("Created", format!("{} `{}` project", opts.kind, project_name))?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, OwnersOptions};
+
+pub fn cli() -> App {
+ subcommand("owner")
+ .about("Manage the owners of a crate on the registry")
+ .arg(Arg::with_name("crate"))
+ .arg(multi_opt("add", "LOGIN", "Name of a user or team to add as an owner").short("a"))
+ .arg(
+ multi_opt(
+ "remove",
+ "LOGIN",
+ "Name of a user or team to remove as an owner",
+ ).short("r"),
+ )
+ .arg(opt("list", "List owners of a crate").short("l"))
+ .arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
+ .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
+ .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .after_help(
+ "\
+ This command will modify the owners for a package
+ on the specified registry(or
+ default).Note that owners of a package can upload new versions, yank old
+ versions.Explicitly named owners can also modify the set of owners, so take
+ caution!
+
+ See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
+ and troubleshooting.",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let registry = args.registry(config)?;
+ let opts = OwnersOptions {
+ krate: args.value_of("crate").map(|s| s.to_string()),
+ token: args.value_of("token").map(|s| s.to_string()),
+ index: args.value_of("index").map(|s| s.to_string()),
+ to_add: args.values_of("add")
+ .map(|xs| xs.map(|s| s.to_string()).collect()),
+ to_remove: args.values_of("remove")
+ .map(|xs| xs.map(|s| s.to_string()).collect()),
+ list: args.is_present("list"),
+ registry,
+ };
+ ops::modify_owners(config, &opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, PackageOpts};
+
+pub fn cli() -> App {
+ subcommand("package")
+ .about("Assemble the local package into a distributable tarball")
+ .arg(
+ opt(
+ "list",
+ "Print files included in a package without making one",
+ ).short("l"),
+ )
+ .arg(opt(
+ "no-verify",
+ "Don't verify the contents by building them",
+ ))
+ .arg(opt(
+ "no-metadata",
+ "Ignore warnings about a lack of human-usable metadata",
+ ))
+ .arg(opt(
+ "allow-dirty",
+ "Allow dirty working directories to be packaged",
+ ))
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_jobs()
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ ops::package(
+ &ws,
+ &PackageOpts {
+ config,
+ verify: !args.is_present("no-verify"),
+ list: args.is_present("list"),
+ check_metadata: !args.is_present("no-metadata"),
+ allow_dirty: args.is_present("allow-dirty"),
+ target: args.target(),
+ jobs: args.jobs()?,
+ registry: None,
+ },
+ )?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("pkgid")
+ .about("Print a fully qualified package specification")
+ .arg(Arg::with_name("spec"))
+ .arg_package("Argument to get the package id specifier for")
+ .arg_manifest_path()
+ .after_help(
+ "\
+Given a <spec> argument, print out the fully qualified package id specifier.
+This command will generate an error if <spec> is ambiguous as to which package
+it refers to in the dependency graph. If no <spec> is given, then the pkgid for
+the local package is printed.
+
+This command requires that a lockfile is available and dependencies have been
+fetched.
+
+Example Package IDs
+
+ pkgid | name | version | url
+ |-----------------------------|--------|-----------|---------------------|
+ foo | foo | * | *
+ foo:1.2.3 | foo | 1.2.3 | *
+ crates.io/foo | foo | * | *://crates.io/foo
+ crates.io/foo#1.2.3 | foo | 1.2.3 | *://crates.io/foo
+ crates.io/bar#foo:1.2.3 | foo | 1.2.3 | *://crates.io/bar
+ http://crates.io/foo#1.2.3 | foo | 1.2.3 | http://crates.io/foo
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let spec = args.value_of("spec").or(args.value_of("package"));
+ let spec = ops::pkgid(&ws, spec)?;
+ println!("{}", spec);
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, PublishOpts};
+
+pub fn cli() -> App {
+ subcommand("publish")
+ .about("Upload a package to the registry")
+ .arg_index()
+ .arg(opt("token", "Token to use when uploading").value_name("TOKEN"))
+ .arg(opt(
+ "no-verify",
+ "Don't verify the contents by building them",
+ ))
+ .arg(opt(
+ "allow-dirty",
+ "Allow dirty working directories to be packaged",
+ ))
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_jobs()
+ .arg(opt("dry-run", "Perform all checks without uploading"))
+ .arg(opt("registry", "Registry to publish to").value_name("REGISTRY"))
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let registry = args.registry(config)?;
+ let ws = args.workspace(config)?;
+ let index = args.index(config)?;
+
+ ops::publish(
+ &ws,
+ &PublishOpts {
+ config,
+ token: args.value_of("token").map(|s| s.to_string()),
+ index,
+ verify: !args.is_present("no-verify"),
+ allow_dirty: args.is_present("allow-dirty"),
+ target: args.target(),
+ jobs: args.jobs()?,
+ dry_run: args.is_present("dry-run"),
+ registry,
+ },
+ )?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::print_json;
+
+pub fn cli() -> App {
+ subcommand("read-manifest")
+ .about(
+ "Deprecated, use `cargo metadata --no-deps` instead.
+Print a JSON representation of a Cargo.toml manifest.",
+ )
+ .arg_manifest_path()
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ print_json(&ws.current()?);
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::core::Verbosity;
+use cargo::ops::{self, CompileFilter, CompileMode};
+
+pub fn cli() -> App {
+ subcommand("run")
+ .alias("r")
+ .setting(AppSettings::TrailingVarArg)
+ .about("Run the main binary of the local package (src/main.rs)")
+ .arg(Arg::with_name("args").multiple(true))
+ .arg_targets_bin_example(
+ "Name of the bin target to run",
+ "Name of the example target to run",
+ )
+ .arg_package("Package with the target to run")
+ .arg_jobs()
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg_features()
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+If neither `--bin` nor `--example` are given, then if the project only has one
+bin target it will be run. Otherwise `--bin` specifies the bin target to run,
+and `--example` specifies the example target to run. At most one of `--bin` or
+`--example` can be provided.
+
+All the arguments following the two dashes (`--`) are passed to the binary to
+run. If you're passing arguments to both Cargo and the binary, the ones after
+`--` go to the binary, the ones before go to Cargo.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+
+ let mut compile_opts = args.compile_options_for_single_package(config, CompileMode::Build)?;
+ if !args.is_present("example") && !args.is_present("bin") {
+ compile_opts.filter = CompileFilter::Default {
+ required_features_filterable: false,
+ };
+ };
+ match ops::run(&ws, &compile_opts, &values(args, "args"))? {
+ None => Ok(()),
+ Some(err) => {
+ // If we never actually spawned the process then that sounds pretty
+ // bad and we always want to forward that up.
+ let exit = match err.exit {
+ Some(exit) => exit,
+ None => return Err(CliError::new(err.into(), 101)),
+ };
+
+ // If `-q` was passed then we suppress extra error information about
+ // a failed process, we assume the process itself printed out enough
+ // information about why it failed so we don't do so as well
+ let exit_code = exit.code().unwrap_or(101);
+ let is_quiet = config.shell().verbosity() == Verbosity::Quiet;
+ Err(if is_quiet {
+ CliError::code(exit_code)
+ } else {
+ CliError::new(err.into(), exit_code)
+ })
+ }
+ }
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode};
+
+pub fn cli() -> App {
+ subcommand("rustc")
+ .setting(AppSettings::TrailingVarArg)
+ .about("Compile a package and all of its dependencies")
+ .arg(Arg::with_name("args").multiple(true))
+ .arg_package("Package to build")
+ .arg_jobs()
+ .arg_targets_all(
+ "Build only this package's library",
+ "Build only the specified binary",
+ "Build all binaries",
+ "Build only the specified example",
+ "Build all examples",
+ "Build only the specified test target",
+ "Build all tests",
+ "Build only the specified bench target",
+ "Build all benches",
+ "Build all targets (lib and bin targets by default)",
+ )
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
+ .arg_features()
+ .arg_target_triple("Target triple which compiles will be for")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+The specified target for the current package (or package specified by SPEC if
+provided) will be compiled along with all of its dependencies. The specified
+<args>... will all be passed to the final compiler invocation, not any of the
+dependencies. Note that the compiler will still unconditionally receive
+arguments such as -L, --extern, and --crate-type, and the specified <args>...
+will simply be added to the compiler invocation.
+
+This command requires that only one target is being compiled. If more than one
+target is available for the current package the filters of --lib, --bin, etc,
+must be used to select which target is compiled. To pass flags to all compiler
+processes spawned by Cargo, use the $RUSTFLAGS environment variable or the
+`build.rustflags` configuration option.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let mode = match args.value_of("profile") {
+ Some("dev") | None => CompileMode::Build,
+ Some("test") => CompileMode::Test,
+ Some("bench") => CompileMode::Bench,
+ Some("check") => CompileMode::Check { test: false },
+ Some(mode) => {
+ let err = format_err!(
+ "unknown profile: `{}`, use dev,
+ test, or bench",
+ mode
+ );
+ return Err(CliError::new(err, 101));
+ }
+ };
+ let mut compile_opts = args.compile_options_for_single_package(config, mode)?;
+ let target_args = values(args, "args");
+ compile_opts.target_rustc_args = if target_args.is_empty() {
+ None
+ } else {
+ Some(target_args)
+ };
+ ops::compile(&ws, &compile_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode, DocOptions};
+
+pub fn cli() -> App {
+ subcommand("rustdoc")
+ .setting(AppSettings::TrailingVarArg)
+ .about("Build a package's documentation, using specified custom flags.")
+ .arg(Arg::with_name("args").multiple(true))
+ .arg(opt(
+ "open",
+ "Opens the docs in a browser after the operation",
+ ))
+ .arg_package("Package to document")
+ .arg_jobs()
+ .arg_targets_all(
+ "Build only this package's library",
+ "Build only the specified binary",
+ "Build all binaries",
+ "Build only the specified example",
+ "Build all examples",
+ "Build only the specified test target",
+ "Build all tests",
+ "Build only the specified bench target",
+ "Build all benches",
+ "Build all targets (default)",
+ )
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg_features()
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+The specified target for the current package (or package specified by SPEC if
+provided) will be documented with the specified <opts>... being passed to the
+final rustdoc invocation. Dependencies will not be documented as part of this
+command. Note that rustdoc will still unconditionally receive arguments such
+as -L, --extern, and --crate-type, and the specified <opts>... will simply be
+added to the rustdoc invocation.
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be documented. If it is not given, then the
+current package is documented. For more information on SPEC and its format, see
+the `cargo help pkgid` command.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let mut compile_opts =
+ args.compile_options_for_single_package(config, CompileMode::Doc { deps: false })?;
+ let target_args = values(args, "args");
+ compile_opts.target_rustdoc_args = if target_args.is_empty() {
+ None
+ } else {
+ Some(target_args)
+ };
+ let doc_opts = DocOptions {
+ open_result: args.is_present("open"),
+ compile_opts,
+ };
+ ops::doc(&ws, &doc_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use std::cmp::min;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("search")
+ .about("Search packages in crates.io")
+ .arg(Arg::with_name("query").multiple(true))
+ .arg_index()
+ .arg(
+ opt(
+ "limit",
+ "Limit the number of results (default: 10, max: 100)",
+ ).value_name("LIMIT"),
+ )
+ .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let registry = args.registry(config)?;
+ let index = args.index(config)?;
+ let limit = args.value_of_u32("limit")?;
+ let limit = min(100, limit.unwrap_or(10));
+ let query: Vec<&str> = args.values_of("query").unwrap_or_default().collect();
+ let query: String = query.join("+");
+ ops::search(&query, config, index, limit, registry)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, CompileMode};
+
+pub fn cli() -> App {
+ subcommand("test")
+ .alias("t")
+ .setting(AppSettings::TrailingVarArg)
+ .about("Execute all unit and integration tests of a local package")
+ .arg(
+ Arg::with_name("TESTNAME")
+ .help("If specified, only run tests containing this string in their names"),
+ )
+ .arg(
+ Arg::with_name("args")
+ .help("Arguments for the test binary")
+ .multiple(true)
+ .last(true),
+ )
+ .arg_targets_all(
+ "Test only this package's library",
+ "Test only the specified binary",
+ "Test all binaries",
+ "Check that the specified examples compile",
+ "Check that all examples compile",
+ "Test only the specified test target",
+ "Test all tests",
+ "Test only the specified bench target",
+ "Test all benches",
+ "Test all targets (default)",
+ )
+ .arg(opt("doc", "Test only this library's documentation"))
+ .arg(opt("no-run", "Compile, but don't run tests"))
+ .arg(opt("no-fail-fast", "Run all tests regardless of failure"))
+ .arg_package_spec(
+ "Package to run tests for",
+ "Test all packages in the workspace",
+ "Exclude packages from the test",
+ )
+ .arg_jobs()
+ .arg_release("Build artifacts in release mode, with optimizations")
+ .arg_features()
+ .arg_target_triple("Build for the target triple")
+ .arg_target_dir()
+ .arg_manifest_path()
+ .arg_message_format()
+ .after_help(
+ "\
+The test filtering argument `TESTNAME` and all the arguments following the
+two dashes (`--`) are passed to the test binaries and thus to libtest
+(rustc's built in unit-test and micro-benchmarking framework). If you're
+passing arguments to both Cargo and the binary, the ones after `--` go to the
+binary, the ones before go to Cargo. For details about libtest's arguments see
+the output of `cargo test -- --help`. As an example, this will run all
+tests with `foo` in their name on 3 threads in parallel:
+
+ cargo test foo -- --test-threads 3
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be tested. If it is not given, then the
+current package is tested. For more information on SPEC and its format, see the
+`cargo help pkgid` command.
+
+All packages in the workspace are tested if the `--all` flag is supplied. The
+`--all` flag is automatically assumed for a virtual manifest.
+Note that `--exclude` has to be specified in conjunction with the `--all` flag.
+
+The --jobs argument affects the building of the test executable but does
+not affect how many jobs are used when running the tests. The default value
+for the --jobs argument is the number of CPUs. If you want to control the
+number of simultaneous running test cases, pass the `--test-threads` option
+to the test binaries:
+
+ cargo test -- --test-threads=1
+
+Compilation can be configured via the `test` profile in the manifest.
+
+By default the rust test harness hides output from test execution to
+keep results readable. Test output can be recovered (e.g. for debugging)
+by passing `--nocapture` to the test binaries:
+
+ cargo test -- --nocapture
+
+To get the list of all options available for the test binaries use this:
+
+ cargo test -- --help
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+
+ let mut compile_opts = args.compile_options(config, CompileMode::Test)?;
+ let doc = args.is_present("doc");
+ if doc {
+ compile_opts.mode = ops::CompileMode::Doctest;
+ compile_opts.filter = ops::CompileFilter::new(
+ true,
+ Vec::new(),
+ false,
+ Vec::new(),
+ false,
+ Vec::new(),
+ false,
+ Vec::new(),
+ false,
+ false,
+ );
+ }
+
+ let ops = ops::TestOptions {
+ no_run: args.is_present("no-run"),
+ no_fail_fast: args.is_present("no-fail-fast"),
+ only_doc: doc,
+ compile_opts,
+ };
+
+ // TESTNAME is actually an argument of the test binary, but it's
+ // important so we explicitly mention it and reconfigure
+ let mut test_args = vec![];
+ test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
+ test_args.extend(
+ args.values_of("args")
+ .unwrap_or_default()
+ .map(|s| s.to_string()),
+ );
+
+ let err = ops::run_tests(&ws, &ops, &test_args)?;
+ return match err {
+ None => Ok(()),
+ Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
+ Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i),
+ None => CliError::new(err.into(), 101),
+ }),
+ };
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("uninstall")
+ .about("Remove a Rust binary")
+ .arg(Arg::with_name("spec").multiple(true))
+ .arg(multi_opt("bin", "NAME", "Only uninstall the binary NAME"))
+ .arg(opt("root", "Directory to uninstall packages from").value_name("DIR"))
+ .after_help(
+ "\
+The argument SPEC is a package id specification (see `cargo help pkgid`) to
+specify which crate should be uninstalled. By default all binaries are
+uninstalled for a crate but the `--bin` and `--example` flags can be used to
+only uninstall particular binaries.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let root = args.value_of("root");
+ let specs = args.values_of("spec").unwrap_or_default().collect();
+ ops::uninstall(root, specs, &values(args, "bin"), config)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops::{self, UpdateOptions};
+
+pub fn cli() -> App {
+ subcommand("update")
+ .about("Update dependencies as recorded in the local lock file")
+ .arg_package_spec_simple("Package to update")
+ .arg(opt(
+ "aggressive",
+ "Force updating all dependencies of <name> as well",
+ ))
+ .arg(opt("precise", "Update a single dependency to exactly PRECISE").value_name("PRECISE"))
+ .arg_manifest_path()
+ .after_help(
+ "\
+This command requires that a `Cargo.lock` already exists as generated by
+`cargo build` or related commands.
+
+If SPEC is given, then a conservative update of the lockfile will be
+performed. This means that only the dependency specified by SPEC will be
+updated. Its transitive dependencies will be updated only if SPEC cannot be
+updated without updating dependencies. All other dependencies will remain
+locked at their currently recorded versions.
+
+If PRECISE is specified, then --aggressive must not also be specified. The
+argument PRECISE is a string representing a precise revision that the package
+being updated should be updated to. For example, if the package comes from a git
+repository, then PRECISE would be the exact revision that the repository should
+be updated to.
+
+If SPEC is not given, then all dependencies will be re-resolved and
+updated.
+
+For more information about package id specifications, see `cargo help pkgid`.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+
+ let update_opts = UpdateOptions {
+ aggressive: args.is_present("aggressive"),
+ precise: args.value_of("precise"),
+ to_update: values(args, "package"),
+ config,
+ };
+ ops::update_lockfile(&ws, &update_opts)?;
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use std::collections::HashMap;
+use std::process;
+use std::fs::File;
+use std::io::Read;
+
+use toml;
+
+use cargo::print_json;
+
+pub fn cli() -> App {
+ subcommand("verify-project")
+ .about("Check correctness of crate manifest")
+ .arg_manifest_path()
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ fn fail(reason: &str, value: &str) -> ! {
+ let mut h = HashMap::new();
+ h.insert(reason.to_string(), value.to_string());
+ print_json(&h);
+ process::exit(1)
+ }
+
+ let mut contents = String::new();
+ let filename = match args.root_manifest(config) {
+ Ok(filename) => filename,
+ Err(e) => fail("invalid", &e.to_string()),
+ };
+
+ let file = File::open(&filename);
+ match file.and_then(|mut f| f.read_to_string(&mut contents)) {
+ Ok(_) => {}
+ Err(e) => fail("invalid", &format!("error reading file: {}", e)),
+ };
+ if contents.parse::<toml::Value>().is_err() {
+ fail("invalid", "invalid-format");
+ }
+
+ let mut h = HashMap::new();
+ h.insert("success".to_string(), "true".to_string());
+ print_json(&h);
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo;
+
+pub fn cli() -> App {
+ subcommand("version").about("Show version information")
+}
+
+pub fn exec(_config: &mut Config, _args: &ArgMatches) -> CliResult {
+ println!("{}", cargo::version());
+ Ok(())
+}
--- /dev/null
+use command_prelude::*;
+
+use cargo::ops;
+
+pub fn cli() -> App {
+ subcommand("yank")
+ .about("Remove a pushed crate from the index")
+ .arg(Arg::with_name("crate"))
+ .arg(opt("vers", "The version to yank or un-yank").value_name("VERSION"))
+ .arg(opt(
+ "undo",
+ "Undo a yank, putting a version back into the index",
+ ))
+ .arg(opt("index", "Registry index to yank from").value_name("INDEX"))
+ .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
+ .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+ .after_help(
+ "\
+The yank command removes a previously pushed crate's version from the server's
+index. This command does not delete any data, and the crate will still be
+available for download via the registry's download link.
+
+Note that existing crates locked to a yanked version will still be able to
+download the yanked version to use it. Cargo will, however, not allow any new
+crates to be locked to any yanked version.
+",
+ )
+}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let registry = args.registry(config)?;
+
+ ops::yank(
+ config,
+ args.value_of("crate").map(|s| s.to_string()),
+ args.value_of("vers").map(|s| s.to_string()),
+ args.value_of("token").map(|s| s.to_string()),
+ args.value_of("index").map(|s| s.to_string()),
+ args.is_present("undo"),
+ registry,
+ )?;
+ Ok(())
+}
--- /dev/null
+extern crate cargo;
+extern crate clap;
+extern crate env_logger;
+#[macro_use]
+extern crate failure;
+extern crate git2_curl;
+extern crate log;
+#[macro_use]
+extern crate serde_derive;
+extern crate serde_json;
+extern crate toml;
+
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::collections::BTreeSet;
+
+use cargo::core::shell::Shell;
+use cargo::util::{self, lev_distance, CargoResult, CliResult, Config};
+use cargo::util::{CliError, ProcessError};
+
+mod cli;
+mod command_prelude;
+mod commands;
+
+fn main() {
+ env_logger::init();
+
+ let mut config = match Config::default() {
+ Ok(cfg) => cfg,
+ Err(e) => {
+ let mut shell = Shell::new();
+ cargo::exit_with_error(e.into(), &mut shell)
+ }
+ };
+
+ let result = {
+ init_git_transports(&mut config);
+ let _token = cargo::util::job::setup();
+ cli::main(&mut config)
+ };
+
+ match result {
+ Err(e) => cargo::exit_with_error(e, &mut *config.shell()),
+ Ok(()) => {}
+ }
+}
+
+fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
+ let alias_name = format!("alias.{}", command);
+ let mut result = Ok(None);
+ match config.get_string(&alias_name) {
+ Ok(value) => {
+ if let Some(record) = value {
+ let alias_commands = record
+ .val
+ .split_whitespace()
+ .map(|s| s.to_string())
+ .collect();
+ result = Ok(Some(alias_commands));
+ }
+ }
+ Err(_) => {
+ let value = config.get_list(&alias_name)?;
+ if let Some(record) = value {
+ let alias_commands: Vec<String> =
+ record.val.iter().map(|s| s.0.to_string()).collect();
+ result = Ok(Some(alias_commands));
+ }
+ }
+ }
+ result
+}
+
+/// List all runnable commands
+fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
+ let prefix = "cargo-";
+ let suffix = env::consts::EXE_SUFFIX;
+ let mut commands = BTreeSet::new();
+ for dir in search_directories(config) {
+ let entries = match fs::read_dir(dir) {
+ Ok(entries) => entries,
+ _ => continue,
+ };
+ for entry in entries.filter_map(|e| e.ok()) {
+ let path = entry.path();
+ let filename = match path.file_name().and_then(|s| s.to_str()) {
+ Some(filename) => filename,
+ _ => continue,
+ };
+ if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
+ continue;
+ }
+ if is_executable(entry.path()) {
+ let end = filename.len() - suffix.len();
+ commands.insert((
+ filename[prefix.len()..end].to_string(),
+ Some(path.display().to_string()),
+ ));
+ }
+ }
+ }
+
+ for cmd in commands::builtin() {
+ commands.insert((cmd.get_name().to_string(), None));
+ }
+
+ commands
+}
+
+fn find_closest(config: &Config, cmd: &str) -> Option<String> {
+ let cmds = list_commands(config);
+ // Only consider candidates with a lev_distance of 3 or less so we don't
+ // suggest out-of-the-blue options.
+ let mut filtered = cmds.iter()
+ .map(|&(ref c, _)| (lev_distance(c, cmd), c))
+ .filter(|&(d, _)| d < 4)
+ .collect::<Vec<_>>();
+ filtered.sort_by(|a, b| a.0.cmp(&b.0));
+ filtered.get(0).map(|slot| slot.1.clone())
+}
+
+fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> CliResult {
+ let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
+ let path = search_directories(config)
+ .iter()
+ .map(|dir| dir.join(&command_exe))
+ .find(|file| is_executable(file));
+ let command = match path {
+ Some(command) => command,
+ None => {
+ let err = match find_closest(config, cmd) {
+ Some(closest) => format_err!(
+ "no such subcommand: `{}`\n\n\tDid you mean `{}`?\n",
+ cmd,
+ closest
+ ),
+ None => format_err!("no such subcommand: `{}`", cmd),
+ };
+ return Err(CliError::new(err, 101));
+ }
+ };
+
+ let cargo_exe = config.cargo_exe()?;
+ let err = match util::process(&command)
+ .env(cargo::CARGO_ENV, cargo_exe)
+ .args(args)
+ .exec_replace()
+ {
+ Ok(()) => return Ok(()),
+ Err(e) => e,
+ };
+
+ if let Some(perr) = err.downcast_ref::<ProcessError>() {
+ if let Some(code) = perr.exit.as_ref().and_then(|c| c.code()) {
+ return Err(CliError::code(code));
+ }
+ }
+ Err(CliError::new(err, 101))
+}
+
+#[cfg(unix)]
+fn is_executable<P: AsRef<Path>>(path: P) -> bool {
+ use std::os::unix::prelude::*;
+ fs::metadata(path)
+ .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
+ .unwrap_or(false)
+}
+#[cfg(windows)]
+fn is_executable<P: AsRef<Path>>(path: P) -> bool {
+ fs::metadata(path)
+ .map(|metadata| metadata.is_file())
+ .unwrap_or(false)
+}
+
+fn search_directories(config: &Config) -> Vec<PathBuf> {
+ let mut dirs = vec![config.home().clone().into_path_unlocked().join("bin")];
+ if let Some(val) = env::var_os("PATH") {
+ dirs.extend(env::split_paths(&val));
+ }
+ dirs
+}
+
+fn init_git_transports(config: &Config) {
+ // Only use a custom transport if any HTTP options are specified,
+ // such as proxies or custom certificate authorities. The custom
+ // transport, however, is not as well battle-tested.
+
+ match cargo::ops::needs_custom_http_transport(config) {
+ Ok(true) => {}
+ _ => return,
+ }
+
+ let handle = match cargo::ops::http_handle(config) {
+ Ok(handle) => handle,
+ Err(..) => return,
+ };
+
+ // The unsafety of the registration function derives from two aspects:
+ //
+ // 1. This call must be synchronized with all other registration calls as
+ // well as construction of new transports.
+ // 2. The argument is leaked.
+ //
+ // We're clear on point (1) because this is only called at the start of this
+ // binary (we know what the state of the world looks like) and we're mostly
+ // clear on point (2) because we'd only free it after everything is done
+ // anyway
+ unsafe {
+ git2_curl::register(handle);
+ }
+}
+++ /dev/null
-extern crate clap;
-
-use clap::{AppSettings, Arg, ArgMatches};
-
-use cargo::{self, CliResult, Config};
-
-use super::list_commands;
-use super::commands;
-use command_prelude::*;
-
-pub fn main(config: &mut Config) -> CliResult {
- let args = cli().get_matches_safe()?;
-
- if args.value_of("unstable-features") == Some("help") {
- println!(
- "
-Available unstable (nightly-only) flags:
-
- -Z avoid-dev-deps -- Avoid installing dev-dependencies if possible
- -Z minimal-versions -- Install minimal dependency versions instead of maximum
- -Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
- -Z offline -- Offline mode that does not perform network requests
- -Z unstable-options -- Allow the usage of unstable options such as --registry
-
-Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
- );
- return Ok(());
- }
-
- let is_verbose = args.occurrences_of("verbose") > 0;
- if args.is_present("version") {
- let version = cargo::version();
- println!("{}", version);
- if is_verbose {
- println!(
- "release: {}.{}.{}",
- version.major, version.minor, version.patch
- );
- if let Some(ref cfg) = version.cfg_info {
- if let Some(ref ci) = cfg.commit_info {
- println!("commit-hash: {}", ci.commit_hash);
- println!("commit-date: {}", ci.commit_date);
- }
- }
- }
- return Ok(());
- }
-
- if let Some(ref code) = args.value_of("explain") {
- let mut procss = config.rustc(None)?.process();
- procss.arg("--explain").arg(code).exec()?;
- return Ok(());
- }
-
- if args.is_present("list") {
- println!("Installed Commands:");
- for command in list_commands(config) {
- let (command, path) = command;
- if is_verbose {
- match path {
- Some(p) => println!(" {:<20} {}", command, p),
- None => println!(" {:<20}", command),
- }
- } else {
- println!(" {}", command);
- }
- }
- return Ok(());
- }
-
- let args = expand_aliases(config, args)?;
-
- execute_subcommand(config, args)
-}
-
-fn expand_aliases(
- config: &mut Config,
- args: ArgMatches<'static>,
-) -> Result<ArgMatches<'static>, CliError> {
- if let (cmd, Some(args)) = args.subcommand() {
- match (
- commands::builtin_exec(cmd),
- super::aliased_command(config, cmd)?,
- ) {
- (None, Some(mut alias)) => {
- alias.extend(
- args.values_of("")
- .unwrap_or_default()
- .map(|s| s.to_string()),
- );
- let args = cli()
- .setting(AppSettings::NoBinaryName)
- .get_matches_from_safe(alias)?;
- return expand_aliases(config, args);
- }
- (Some(_), Some(_)) => {
- config.shell().warn(format!(
- "alias `{}` is ignored, because it is shadowed by a built in command",
- cmd
- ))?;
- }
- (_, None) => {}
- }
- };
- Ok(args)
-}
-
-fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
- let (cmd, subcommand_args) = match args.subcommand() {
- (cmd, Some(args)) => (cmd, args),
- _ => {
- cli().print_help()?;
- return Ok(());
- }
- };
-
- let arg_target_dir = &subcommand_args.value_of_path("target-dir", config);
-
- config.configure(
- args.occurrences_of("verbose") as u32,
- if args.is_present("quiet") {
- Some(true)
- } else {
- None
- },
- &args.value_of("color").map(|s| s.to_string()),
- args.is_present("frozen"),
- args.is_present("locked"),
- arg_target_dir,
- &args.values_of_lossy("unstable-features")
- .unwrap_or_default(),
- )?;
-
- if let Some(exec) = commands::builtin_exec(cmd) {
- return exec(config, subcommand_args);
- }
-
- let mut ext_args: Vec<&str> = vec![cmd];
- ext_args.extend(subcommand_args.values_of("").unwrap_or_default());
- super::execute_external_subcommand(config, cmd, &ext_args)
-}
-
-fn cli() -> App {
- let app = App::new("cargo")
- .settings(&[
- AppSettings::UnifiedHelpMessage,
- AppSettings::DeriveDisplayOrder,
- AppSettings::VersionlessSubcommands,
- AppSettings::AllowExternalSubcommands,
- ])
- .about("")
- .template(
- "\
-Rust's package manager
-
-USAGE:
- {usage}
-
-OPTIONS:
-{unified}
-
-Some common cargo commands are (see all commands with --list):
- build Compile the current project
- check Analyze the current project and report errors, but don't build object files
- clean Remove the target directory
- doc Build this project's and its dependencies' documentation
- new Create a new cargo project
- init Create a new cargo project in an existing directory
- run Build and execute src/main.rs
- test Run the tests
- bench Run the benchmarks
- update Update dependencies listed in Cargo.lock
- search Search registry for crates
- publish Package and upload this project to the registry
- install Install a Rust binary
- uninstall Uninstall a Rust binary
-
-See 'cargo help <command>' for more information on a specific command.\n",
- )
- .arg(opt("version", "Print version info and exit").short("V"))
- .arg(opt("list", "List installed commands"))
- .arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
- .arg(
- opt(
- "verbose",
- "Use verbose output (-vv very verbose/build.rs output)",
- ).short("v")
- .multiple(true)
- .global(true),
- )
- .arg(
- opt("quiet", "No output printed to stdout")
- .short("q")
- .global(true),
- )
- .arg(
- opt("color", "Coloring: auto, always, never")
- .value_name("WHEN")
- .global(true),
- )
- .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
- .arg(opt("locked", "Require Cargo.lock is up to date").global(true))
- .arg(
- Arg::with_name("unstable-features")
- .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
- .short("Z")
- .value_name("FLAG")
- .multiple(true)
- .number_of_values(1)
- .global(true),
- )
- .subcommands(commands::builtin());
- app
-}
+++ /dev/null
-use std::path::PathBuf;
-use std::fs;
-
-use clap::{self, SubCommand};
-use cargo::CargoResult;
-use cargo::core::Workspace;
-use cargo::ops::{CompileFilter, CompileMode, CompileOptions, MessageFormat, NewOptions, Packages,
- VersionControl};
-use cargo::util::paths;
-use cargo::util::important_paths::find_root_manifest_for_wd;
-
-pub use clap::{AppSettings, Arg, ArgMatches};
-pub use cargo::{CliError, CliResult, Config};
-
-pub type App = clap::App<'static, 'static>;
-
-pub trait AppExt: Sized {
- fn _arg(self, arg: Arg<'static, 'static>) -> Self;
-
- fn arg_package_spec(
- self,
- package: &'static str,
- all: &'static str,
- exclude: &'static str,
- ) -> Self {
- self.arg_package_spec_simple(package)
- ._arg(opt("all", all))
- ._arg(multi_opt("exclude", "SPEC", exclude))
- }
-
- fn arg_package_spec_simple(self, package: &'static str) -> Self {
- self._arg(multi_opt("package", "SPEC", package).short("p"))
- }
-
- fn arg_package(self, package: &'static str) -> Self {
- self._arg(opt("package", package).short("p").value_name("SPEC"))
- }
-
- fn arg_jobs(self) -> Self {
- self._arg(
- opt("jobs", "Number of parallel jobs, defaults to # of CPUs")
- .short("j")
- .value_name("N"),
- )
- }
-
- fn arg_targets_all(
- self,
- lib: &'static str,
- bin: &'static str,
- bins: &'static str,
- example: &'static str,
- examples: &'static str,
- test: &'static str,
- tests: &'static str,
- bench: &'static str,
- benches: &'static str,
- all: &'static str,
- ) -> Self {
- self.arg_targets_lib_bin(lib, bin, bins)
- ._arg(multi_opt("example", "NAME", example))
- ._arg(opt("examples", examples))
- ._arg(multi_opt("test", "NAME", test))
- ._arg(opt("tests", tests))
- ._arg(multi_opt("bench", "NAME", bench))
- ._arg(opt("benches", benches))
- ._arg(opt("all-targets", all))
- }
-
- fn arg_targets_lib_bin(self, lib: &'static str, bin: &'static str, bins: &'static str) -> Self {
- self._arg(opt("lib", lib))
- ._arg(multi_opt("bin", "NAME", bin))
- ._arg(opt("bins", bins))
- }
-
- fn arg_targets_bins_examples(
- self,
- bin: &'static str,
- bins: &'static str,
- example: &'static str,
- examples: &'static str,
- ) -> Self {
- self._arg(multi_opt("bin", "NAME", bin))
- ._arg(opt("bins", bins))
- ._arg(multi_opt("example", "NAME", example))
- ._arg(opt("examples", examples))
- }
-
- fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self {
- self._arg(multi_opt("bin", "NAME", bin))
- ._arg(multi_opt("example", "NAME", example))
- }
-
- fn arg_features(self) -> Self {
- self._arg(
- opt("features", "Space-separated list of features to activate").value_name("FEATURES"),
- )._arg(opt("all-features", "Activate all available features"))
- ._arg(opt(
- "no-default-features",
- "Do not activate the `default` feature",
- ))
- }
-
- fn arg_release(self, release: &'static str) -> Self {
- self._arg(opt("release", release))
- }
-
- fn arg_doc(self, doc: &'static str) -> Self {
- self._arg(opt("doc", doc))
- }
-
- fn arg_target_triple(self, target: &'static str) -> Self {
- self._arg(opt("target", target).value_name("TRIPLE"))
- }
-
- fn arg_target_dir(self) -> Self {
- self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY"))
- }
-
- fn arg_manifest_path(self) -> Self {
- self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH"))
- }
-
- fn arg_message_format(self) -> Self {
- self._arg(
- opt("message-format", "Error format")
- .value_name("FMT")
- .case_insensitive(true)
- .possible_values(&["human", "json"])
- .default_value("human"),
- )
- }
-
- fn arg_new_opts(self) -> Self {
- self._arg(
- opt(
- "vcs",
- "\
- Initialize a new repository for the given version \
- control system (git, hg, pijul, or fossil) or do not \
- initialize any version control at all (none), overriding \
- a global configuration.",
- ).value_name("VCS")
- .possible_values(&["git", "hg", "pijul", "fossil", "none"]),
- )._arg(opt("bin", "Use a binary (application) template [default]"))
- ._arg(opt("lib", "Use a library template"))
- ._arg(
- opt(
- "name",
- "Set the resulting package name, defaults to the directory name",
- ).value_name("NAME"),
- )
- }
-
- fn arg_index(self) -> Self {
- self._arg(opt("index", "Registry index to upload the package to").value_name("INDEX"))
- ._arg(
- opt("host", "DEPRECATED, renamed to '--index'")
- .value_name("HOST")
- .hidden(true),
- )
- }
-}
-
-impl AppExt for App {
- fn _arg(self, arg: Arg<'static, 'static>) -> Self {
- self.arg(arg)
- }
-}
-
-pub fn opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> {
- Arg::with_name(name).long(name).help(help)
-}
-
-pub fn multi_opt(
- name: &'static str,
- value_name: &'static str,
- help: &'static str,
-) -> Arg<'static, 'static> {
- // Note that all `.multiple(true)` arguments in Cargo should specify
- // `.number_of_values(1)` as well, so that `--foo val1 val2` is
- // **not** parsed as `foo` with values ["val1", "val2"].
- // `number_of_values` should become the default in clap 3.
- opt(name, help)
- .value_name(value_name)
- .multiple(true)
- .number_of_values(1)
-}
-
-pub fn subcommand(name: &'static str) -> App {
- SubCommand::with_name(name).settings(&[
- AppSettings::UnifiedHelpMessage,
- AppSettings::DeriveDisplayOrder,
- AppSettings::DontCollapseArgsInUsage,
- ])
-}
-
-pub trait ArgMatchesExt {
- fn value_of_u32(&self, name: &str) -> CargoResult<Option<u32>> {
- let arg = match self._value_of(name) {
- None => None,
- Some(arg) => Some(arg.parse::<u32>().map_err(|_| {
- clap::Error::value_validation_auto(format!("could not parse `{}` as a number", arg))
- })?),
- };
- Ok(arg)
- }
-
- /// Returns value of the `name` command-line argument as an absolute path
- fn value_of_path(&self, name: &str, config: &Config) -> Option<PathBuf> {
- self._value_of(name).map(|path| config.cwd().join(path))
- }
-
- fn root_manifest(&self, config: &Config) -> CargoResult<PathBuf> {
- if let Some(path) = self.value_of_path("manifest-path", config) {
- // In general, we try to avoid normalizing paths in Cargo,
- // but in this particular case we need it to fix #3586.
- let path = paths::normalize_path(&path);
- if !path.ends_with("Cargo.toml") {
- bail!("the manifest-path must be a path to a Cargo.toml file")
- }
- if !fs::metadata(&path).is_ok() {
- bail!(
- "manifest path `{}` does not exist",
- self._value_of("manifest-path").unwrap()
- )
- }
- return Ok(path);
- }
- find_root_manifest_for_wd(config.cwd())
- }
-
- fn workspace<'a>(&self, config: &'a Config) -> CargoResult<Workspace<'a>> {
- let root = self.root_manifest(config)?;
- let mut ws = Workspace::new(&root, config)?;
- if config.cli_unstable().avoid_dev_deps {
- ws.set_require_optional_deps(false);
- }
- Ok(ws)
- }
-
- fn jobs(&self) -> CargoResult<Option<u32>> {
- self.value_of_u32("jobs")
- }
-
- fn target(&self) -> Option<String> {
- self._value_of("target").map(|s| s.to_string())
- }
-
- fn compile_options<'a>(
- &self,
- config: &'a Config,
- mode: CompileMode,
- ) -> CargoResult<CompileOptions<'a>> {
- let spec = Packages::from_flags(
- self._is_present("all"),
- self._values_of("exclude"),
- self._values_of("package"),
- )?;
-
- let message_format = match self._value_of("message-format") {
- None => MessageFormat::Human,
- Some(f) => {
- if f.eq_ignore_ascii_case("json") {
- MessageFormat::Json
- } else if f.eq_ignore_ascii_case("human") {
- MessageFormat::Human
- } else {
- panic!("Impossible message format: {:?}", f)
- }
- }
- };
-
- let opts = CompileOptions {
- config,
- jobs: self.jobs()?,
- target: self.target(),
- features: self._values_of("features"),
- all_features: self._is_present("all-features"),
- no_default_features: self._is_present("no-default-features"),
- spec,
- mode,
- release: self._is_present("release"),
- filter: CompileFilter::new(
- self._is_present("lib"),
- self._values_of("bin"),
- self._is_present("bins"),
- self._values_of("test"),
- self._is_present("tests"),
- self._values_of("example"),
- self._is_present("examples"),
- self._values_of("bench"),
- self._is_present("benches"),
- self._is_present("all-targets"),
- ),
- message_format,
- target_rustdoc_args: None,
- target_rustc_args: None,
- export_dir: None,
- };
- Ok(opts)
- }
-
- fn compile_options_for_single_package<'a>(
- &self,
- config: &'a Config,
- mode: CompileMode,
- ) -> CargoResult<CompileOptions<'a>> {
- let mut compile_opts = self.compile_options(config, mode)?;
- compile_opts.spec = Packages::Packages(self._values_of("package"));
- Ok(compile_opts)
- }
-
- fn new_options(&self, config: &Config) -> CargoResult<NewOptions> {
- let vcs = self._value_of("vcs").map(|vcs| match vcs {
- "git" => VersionControl::Git,
- "hg" => VersionControl::Hg,
- "pijul" => VersionControl::Pijul,
- "fossil" => VersionControl::Fossil,
- "none" => VersionControl::NoVcs,
- vcs => panic!("Impossible vcs: {:?}", vcs),
- });
- NewOptions::new(
- vcs,
- self._is_present("bin"),
- self._is_present("lib"),
- self.value_of_path("path", config).unwrap(),
- self._value_of("name").map(|s| s.to_string()),
- )
- }
-
- fn registry(&self, config: &Config) -> CargoResult<Option<String>> {
- match self._value_of("registry") {
- Some(registry) => {
- if !config.cli_unstable().unstable_options {
- return Err(format_err!(
- "registry option is an unstable feature and \
- requires -Zunstable-options to use."
- ).into());
- }
- Ok(Some(registry.to_string()))
- }
- None => Ok(None),
- }
- }
-
- fn index(&self, config: &Config) -> CargoResult<Option<String>> {
- // TODO: Deprecated
- // remove once it has been decided --host can be removed
- // We may instead want to repurpose the host flag, as
- // mentioned in this issue
- // https://github.com/rust-lang/cargo/issues/4208
- let msg = "The flag '--host' is no longer valid.
-
-Previous versions of Cargo accepted this flag, but it is being
-deprecated. The flag is being renamed to 'index', as the flag
-wants the location of the index. Please use '--index' instead.
-
-This will soon become a hard error, so it's either recommended
-to update to a fixed version or contact the upstream maintainer
-about this warning.";
-
- let index = match self._value_of("host") {
- Some(host) => {
- config.shell().warn(&msg)?;
- Some(host.to_string())
- }
- None => self._value_of("index").map(|s| s.to_string()),
- };
- Ok(index)
- }
-
- fn _value_of(&self, name: &str) -> Option<&str>;
-
- fn _values_of(&self, name: &str) -> Vec<String>;
-
- fn _is_present(&self, name: &str) -> bool;
-}
-
-impl<'a> ArgMatchesExt for ArgMatches<'a> {
- fn _value_of(&self, name: &str) -> Option<&str> {
- self.value_of(name)
- }
-
- fn _values_of(&self, name: &str) -> Vec<String> {
- self.values_of(name)
- .unwrap_or_default()
- .map(|s| s.to_string())
- .collect()
- }
-
- fn _is_present(&self, name: &str) -> bool {
- self.is_present(name)
- }
-}
-
-pub fn values(args: &ArgMatches, name: &str) -> Vec<String> {
- args.values_of(name)
- .unwrap_or_default()
- .map(|s| s.to_string())
- .collect()
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode, TestOptions};
-
-pub fn cli() -> App {
- subcommand("bench")
- .setting(AppSettings::TrailingVarArg)
- .about("Execute all benchmarks of a local package")
- .arg(
- Arg::with_name("BENCHNAME")
- .help("If specified, only run benches containing this string in their names"),
- )
- .arg(
- Arg::with_name("args")
- .help("Arguments for the bench binary")
- .multiple(true)
- .last(true),
- )
- .arg_targets_all(
- "Benchmark only this package's library",
- "Benchmark only the specified binary",
- "Benchmark all binaries",
- "Benchmark only the specified example",
- "Benchmark all examples",
- "Benchmark only the specified test target",
- "Benchmark all tests",
- "Benchmark only the specified bench target",
- "Benchmark all benches",
- "Benchmark all targets (default)",
- )
- .arg(opt("no-run", "Compile, but don't run benchmarks"))
- .arg_package_spec(
- "Package to run benchmarks for",
- "Benchmark all packages in the workspace",
- "Exclude packages from the benchmark",
- )
- .arg_jobs()
- .arg_features()
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .arg(opt(
- "no-fail-fast",
- "Run all benchmarks regardless of failure",
- ))
- .after_help(
- "\
-The benchmark filtering argument `BENCHNAME` and all the arguments following the
-two dashes (`--`) are passed to the benchmark binaries and thus to libtest
-(rustc's built in unit-test and micro-benchmarking framework). If you're
-passing arguments to both Cargo and the binary, the ones after `--` go to the
-binary, the ones before go to Cargo. For details about libtest's arguments see
-the output of `cargo bench -- --help`.
-
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be benchmarked. If it is not given, then
-the current package is benchmarked. For more information on SPEC and its format,
-see the `cargo help pkgid` command.
-
-All packages in the workspace are benchmarked if the `--all` flag is supplied. The
-`--all` flag is automatically assumed for a virtual manifest.
-Note that `--exclude` has to be specified in conjunction with the `--all` flag.
-
-The --jobs argument affects the building of the benchmark executable but does
-not affect how many jobs are used when running the benchmarks.
-
-Compilation can be customized with the `bench` profile in the manifest.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let mut compile_opts = args.compile_options(config, CompileMode::Bench)?;
- compile_opts.release = true;
-
- let ops = TestOptions {
- no_run: args.is_present("no-run"),
- no_fail_fast: args.is_present("no-fail-fast"),
- only_doc: false,
- compile_opts,
- };
-
- let mut bench_args = vec![];
- bench_args.extend(
- args.value_of("BENCHNAME")
- .into_iter()
- .map(|s| s.to_string()),
- );
- bench_args.extend(
- args.values_of("args")
- .unwrap_or_default()
- .map(|s| s.to_string()),
- );
-
- let err = ops::run_benches(&ws, &ops, &bench_args)?;
- match err {
- None => Ok(()),
- Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
- Some(i) => CliError::new(format_err!("bench failed"), i),
- None => CliError::new(err.into(), 101),
- }),
- }
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode};
-
-pub fn cli() -> App {
- subcommand("build")
- .alias("b")
- .about("Compile a local package and all of its dependencies")
- .arg_package_spec(
- "Package to build",
- "Build all packages in the workspace",
- "Exclude packages from the build",
- )
- .arg_jobs()
- .arg_targets_all(
- "Build only this package's library",
- "Build only the specified binary",
- "Build all binaries",
- "Build only the specified example",
- "Build all examples",
- "Build only the specified test target",
- "Build all tests",
- "Build only the specified bench target",
- "Build all benches",
- "Build all targets (lib and bin targets by default)",
- )
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg_features()
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH"))
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be built. If it is not given, then the
-current package is built. For more information on SPEC and its format, see the
-`cargo help pkgid` command.
-
-All packages in the workspace are built if the `--all` flag is supplied. The
-`--all` flag is automatically assumed for a virtual manifest.
-Note that `--exclude` has to be specified in conjunction with the `--all` flag.
-
-Compilation can be configured via the use of profiles which are configured in
-the manifest. The default profile for this command is `dev`, but passing
-the --release flag will use the `release` profile instead.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let mut compile_opts = args.compile_options(config, CompileMode::Build)?;
- compile_opts.export_dir = args.value_of_path("out-dir", config);
- if compile_opts.export_dir.is_some() && !config.cli_unstable().unstable_options {
- Err(format_err!(
- "`--out-dir` flag is unstable, pass `-Z unstable-options` to enable it"
- ))?;
- };
- ops::compile(&ws, &compile_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode};
-
-pub fn cli() -> App {
- subcommand("check")
- .about("Check a local package and all of its dependencies for errors")
- .arg_package_spec(
- "Package(s) to check",
- "Check all packages in the workspace",
- "Exclude packages from the check",
- )
- .arg_jobs()
- .arg_targets_all(
- "Check only this package's library",
- "Check only the specified binary",
- "Check all binaries",
- "Check only the specified example",
- "Check all examples",
- "Check only the specified test target",
- "Check all tests",
- "Check only the specified bench target",
- "Check all benches",
- "Check all targets (lib and bin targets by default)",
- )
- .arg_release("Check artifacts in release mode, with optimizations")
- .arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
- .arg_features()
- .arg_target_triple("Check for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be built. If it is not given, then the
-current package is built. For more information on SPEC and its format, see the
-`cargo help pkgid` command.
-
-All packages in the workspace are checked if the `--all` flag is supplied. The
-`--all` flag is automatically assumed for a virtual manifest.
-Note that `--exclude` has to be specified in conjunction with the `--all` flag.
-
-Compilation can be configured via the use of profiles which are configured in
-the manifest. The default profile for this command is `dev`, but passing
-the --release flag will use the `release` profile instead.
-
-The `--profile test` flag can be used to check unit tests with the
-`#[cfg(test)]` attribute.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let test = match args.value_of("profile") {
- Some("test") => true,
- None => false,
- Some(profile) => {
- let err = format_err!(
- "unknown profile: `{}`, only `test` is \
- currently supported",
- profile
- );
- return Err(CliError::new(err, 101));
- }
- };
- let mode = CompileMode::Check { test };
- let compile_opts = args.compile_options(config, mode)?;
- ops::compile(&ws, &compile_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CleanOptions};
-
-pub fn cli() -> App {
- subcommand("clean")
- .about("Remove artifacts that cargo has generated in the past")
- .arg_package_spec_simple("Package to clean artifacts for")
- .arg_manifest_path()
- .arg_target_triple("Target triple to clean output for (default all)")
- .arg_target_dir()
- .arg_release("Whether or not to clean release artifacts")
- .arg_doc("Whether or not to clean just the documentation directory")
- .after_help(
- "\
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package's artifacts should be cleaned out. If it is not
-given, then all packages' artifacts are removed. For more information on SPEC
-and its format, see the `cargo help pkgid` command.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let opts = CleanOptions {
- config,
- spec: values(args, "package"),
- target: args.target(),
- release: args.is_present("release"),
- doc: args.is_present("doc"),
- };
- ops::clean(&ws, &opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode, DocOptions};
-
-pub fn cli() -> App {
- subcommand("doc")
- .about("Build a package's documentation")
- .arg(opt(
- "open",
- "Opens the docs in a browser after the operation",
- ))
- .arg_package_spec(
- "Package to document",
- "Document all packages in the workspace",
- "Exclude packages from the build",
- )
- .arg(opt("no-deps", "Don't build documentation for dependencies"))
- .arg_jobs()
- .arg_targets_lib_bin(
- "Document only this package's library",
- "Document only the specified binary",
- "Document all binaries",
- )
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg_features()
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-By default the documentation for the local package and all dependencies is
-built. The output is all placed in `target/doc` in rustdoc's usual format.
-
-All packages in the workspace are documented if the `--all` flag is supplied. The
-`--all` flag is automatically assumed for a virtual manifest.
-Note that `--exclude` has to be specified in conjunction with the `--all` flag.
-
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be documented. If it is not given, then the
-current package is documented. For more information on SPEC and its format, see
-the `cargo help pkgid` command.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let mode = CompileMode::Doc {
- deps: !args.is_present("no-deps"),
- };
- let compile_opts = args.compile_options(config, mode)?;
- let doc_opts = DocOptions {
- open_result: args.is_present("open"),
- compile_opts,
- };
- ops::doc(&ws, &doc_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-use cargo::ops::FetchOptions;
-
-pub fn cli() -> App {
- subcommand("fetch")
- .about("Fetch dependencies of a package from the network")
- .arg_manifest_path()
- .arg_target_triple("Fetch dependencies for the target triple")
- .after_help(
- "\
-If a lockfile is available, this command will ensure that all of the git
-dependencies and/or registries dependencies are downloaded and locally
-available. The network is never touched after a `cargo fetch` unless
-the lockfile changes.
-
-If the lockfile is not available, then this is the equivalent of
-`cargo generate-lockfile`. A lockfile is generated and dependencies are also
-all updated.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
-
- let opts = FetchOptions {
- config,
- target: args.target(),
- };
- ops::fetch(&ws, &opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("generate-lockfile")
- .about("Generate the lockfile for a project")
- .arg_manifest_path()
- .after_help(
- "\
-If a lockfile is available, this command will ensure that all of the git
-dependencies and/or registries dependencies are downloaded and locally
-available. The network is never touched after a `cargo fetch` unless
-the lockfile changes.
-
-If the lockfile is not available, then this is the equivalent of
-`cargo generate-lockfile`. A lockfile is generated and dependencies are also
-all updated.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- ops::generate_lockfile(&ws)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::core::{GitReference, Source, SourceId};
-use cargo::sources::GitSource;
-use cargo::util::ToUrl;
-
-pub fn cli() -> App {
- subcommand("git-checkout")
- .about("Checkout a copy of a Git repository")
- .arg(
- Arg::with_name("url")
- .long("url")
- .value_name("URL")
- .required(true),
- )
- .arg(
- Arg::with_name("reference")
- .long("reference")
- .value_name("REF")
- .required(true),
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let url = args.value_of("url").unwrap().to_url()?;
- let reference = args.value_of("reference").unwrap();
-
- let reference = GitReference::Branch(reference.to_string());
- let source_id = SourceId::for_git(&url, reference)?;
-
- let mut source = GitSource::new(&source_id, config)?;
-
- source.update()?;
-
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("init")
- .about("Create a new cargo package in an existing directory")
- .arg(Arg::with_name("path").default_value("."))
- .arg_new_opts()
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let opts = args.new_options(config)?;
- ops::init(&opts, config)?;
- config
- .shell()
- .status("Created", format!("{} project", opts.kind))?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::core::{GitReference, SourceId};
-use cargo::ops::{self, CompileMode};
-use cargo::util::ToUrl;
-
-pub fn cli() -> App {
- subcommand("install")
- .about("Install a Rust binary")
- .arg(Arg::with_name("crate").empty_values(false).multiple(true))
- .arg(
- opt("version", "Specify a version to install from crates.io")
- .alias("vers")
- .value_name("VERSION"),
- )
- .arg(opt("git", "Git URL to install the specified crate from").value_name("URL"))
- .arg(opt("branch", "Branch to use when installing from git").value_name("BRANCH"))
- .arg(opt("tag", "Tag to use when installing from git").value_name("TAG"))
- .arg(opt("rev", "Specific commit to use when installing from git").value_name("SHA"))
- .arg(opt("path", "Filesystem path to local crate to install").value_name("PATH"))
- .arg(opt(
- "list",
- "list all installed packages and their versions",
- ))
- .arg_jobs()
- .arg(opt("force", "Force overwriting existing crates or binaries").short("f"))
- .arg_features()
- .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(opt("root", "Directory to install packages into").value_name("DIR"))
- .after_help(
- "\
-This command manages Cargo's local set of installed binary crates. Only packages
-which have [[bin]] targets can be installed, and all binaries 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` and `--path` 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 `--vers` 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.
-
-By default cargo will refuse to overwrite existing binaries. The `--force` flag
-enables overwriting existing binaries. Thus you can reinstall a crate with
-`cargo install --force <crate>`.
-
-As a special convenience, omitting the <crate> specification entirely will
-install the crate in the current directory. That is, `install` is equivalent to
-the more explicit `install --path .`.
-
-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 mut compile_opts = args.compile_options(config, CompileMode::Build)?;
- compile_opts.release = !args.is_present("debug");
-
- 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.to_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 {
- 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"),
- )?;
- }
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::print_json;
-
-pub fn cli() -> App {
- subcommand("locate-project")
- .about("Print a JSON representation of a Cargo.toml file's location")
- .arg_manifest_path()
-}
-
-#[derive(Serialize)]
-pub struct ProjectLocation {
- root: String,
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let root = args.root_manifest(config)?;
-
- let root = root.to_str()
- .ok_or_else(|| {
- format_err!(
- "your project path contains characters \
- not representable in Unicode"
- )
- })
- .map_err(|e| CliError::new(e, 1))?
- .to_string();
-
- let location = ProjectLocation { root };
-
- print_json(&location);
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use std::io::{self, BufRead};
-
-use cargo::core::{Source, SourceId};
-use cargo::sources::RegistrySource;
-use cargo::util::{CargoError, CargoResultExt};
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("login")
- .about(
- "Save an api token from the registry locally. \
- If token is not specified, it will be read from stdin.",
- )
- .arg(Arg::with_name("token"))
- .arg(opt("host", "Host to set the token for").value_name("HOST"))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
-
- let token = match args.value_of("token") {
- Some(token) => token.to_string(),
- None => {
- let host = match registry {
- Some(ref _registry) => {
- return Err(format_err!(
- "token must be provided when \
- --registry is provided."
- ).into());
- }
- None => {
- let src = SourceId::crates_io(config)?;
- let mut src = RegistrySource::remote(&src, config);
- src.update()?;
- let config = src.config()?.unwrap();
- args.value_of("host")
- .map(|s| s.to_string())
- .unwrap_or(config.api.unwrap())
- }
- };
- println!("please visit {}me and paste the API Token below", host);
- let mut line = String::new();
- let input = io::stdin();
- input
- .lock()
- .read_line(&mut line)
- .chain_err(|| "failed to read stdin")
- .map_err(CargoError::from)?;
- line.trim().to_string()
- }
- };
-
- ops::registry_login(config, token, registry)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, OutputMetadataOptions};
-use cargo::print_json;
-
-pub fn cli() -> App {
- subcommand("metadata")
- .about(
- "Output the resolved dependencies of a project, \
- the concrete used versions including overrides, \
- in machine-readable format",
- )
- .arg_features()
- .arg(opt(
- "no-deps",
- "Output information only about the root package \
- and don't fetch dependencies",
- ))
- .arg_manifest_path()
- .arg(
- opt("format-version", "Format version")
- .value_name("VERSION")
- .possible_value("1"),
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
-
- let version = match args.value_of("format-version") {
- None => {
- config.shell().warn(
- "\
- please specify `--format-version` flag explicitly \
- to avoid compatibility problems",
- )?;
- 1
- }
- Some(version) => version.parse().unwrap(),
- };
-
- let options = OutputMetadataOptions {
- features: values(args, "features"),
- all_features: args.is_present("all-features"),
- no_default_features: args.is_present("no-default-features"),
- no_deps: args.is_present("no-deps"),
- version,
- };
-
- let result = ops::output_metadata(&ws, &options)?;
- print_json(&result);
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-pub fn builtin() -> Vec<App> {
- vec![
- bench::cli(),
- build::cli(),
- check::cli(),
- clean::cli(),
- doc::cli(),
- fetch::cli(),
- generate_lockfile::cli(),
- git_checkout::cli(),
- init::cli(),
- install::cli(),
- locate_project::cli(),
- login::cli(),
- metadata::cli(),
- new::cli(),
- owner::cli(),
- package::cli(),
- pkgid::cli(),
- publish::cli(),
- read_manifest::cli(),
- run::cli(),
- rustc::cli(),
- rustdoc::cli(),
- search::cli(),
- test::cli(),
- uninstall::cli(),
- update::cli(),
- verify_project::cli(),
- version::cli(),
- yank::cli(),
- ]
-}
-
-pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches) -> CliResult> {
- let f = match cmd {
- "bench" => bench::exec,
- "build" => build::exec,
- "check" => check::exec,
- "clean" => clean::exec,
- "doc" => doc::exec,
- "fetch" => fetch::exec,
- "generate-lockfile" => generate_lockfile::exec,
- "git-checkout" => git_checkout::exec,
- "init" => init::exec,
- "install" => install::exec,
- "locate-project" => locate_project::exec,
- "login" => login::exec,
- "metadata" => metadata::exec,
- "new" => new::exec,
- "owner" => owner::exec,
- "package" => package::exec,
- "pkgid" => pkgid::exec,
- "publish" => publish::exec,
- "read-manifest" => read_manifest::exec,
- "run" => run::exec,
- "rustc" => rustc::exec,
- "rustdoc" => rustdoc::exec,
- "search" => search::exec,
- "test" => test::exec,
- "uninstall" => uninstall::exec,
- "update" => update::exec,
- "verify-project" => verify_project::exec,
- "version" => version::exec,
- "yank" => yank::exec,
- _ => return None,
- };
- Some(f)
-}
-
-pub mod bench;
-pub mod build;
-pub mod check;
-pub mod clean;
-pub mod doc;
-pub mod fetch;
-pub mod generate_lockfile;
-pub mod git_checkout;
-pub mod init;
-pub mod install;
-pub mod locate_project;
-pub mod login;
-pub mod metadata;
-pub mod new;
-pub mod owner;
-pub mod package;
-pub mod pkgid;
-pub mod publish;
-pub mod read_manifest;
-pub mod run;
-pub mod rustc;
-pub mod rustdoc;
-pub mod search;
-pub mod test;
-pub mod uninstall;
-pub mod update;
-pub mod verify_project;
-pub mod version;
-pub mod yank;
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("new")
- .about("Create a new cargo package at <path>")
- .arg(Arg::with_name("path").required(true))
- .arg_new_opts()
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let opts = args.new_options(config)?;
-
- ops::new(&opts, config)?;
- let path = args.value_of("path").unwrap();
- let project_name = if let Some(name) = args.value_of("name") {
- name
- } else {
- path
- };
- config
- .shell()
- .status("Created", format!("{} `{}` project", opts.kind, project_name))?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, OwnersOptions};
-
-pub fn cli() -> App {
- subcommand("owner")
- .about("Manage the owners of a crate on the registry")
- .arg(Arg::with_name("crate"))
- .arg(multi_opt("add", "LOGIN", "Name of a user or team to add as an owner").short("a"))
- .arg(
- multi_opt(
- "remove",
- "LOGIN",
- "Name of a user or team to remove as an owner",
- ).short("r"),
- )
- .arg(opt("list", "List owners of a crate").short("l"))
- .arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
- .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
- .after_help(
- "\
- This command will modify the owners for a package
- on the specified registry(or
- default).Note that owners of a package can upload new versions, yank old
- versions.Explicitly named owners can also modify the set of owners, so take
- caution!
-
- See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
- and troubleshooting.",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
- let opts = OwnersOptions {
- krate: args.value_of("crate").map(|s| s.to_string()),
- token: args.value_of("token").map(|s| s.to_string()),
- index: args.value_of("index").map(|s| s.to_string()),
- to_add: args.values_of("add")
- .map(|xs| xs.map(|s| s.to_string()).collect()),
- to_remove: args.values_of("remove")
- .map(|xs| xs.map(|s| s.to_string()).collect()),
- list: args.is_present("list"),
- registry,
- };
- ops::modify_owners(config, &opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, PackageOpts};
-
-pub fn cli() -> App {
- subcommand("package")
- .about("Assemble the local package into a distributable tarball")
- .arg(
- opt(
- "list",
- "Print files included in a package without making one",
- ).short("l"),
- )
- .arg(opt(
- "no-verify",
- "Don't verify the contents by building them",
- ))
- .arg(opt(
- "no-metadata",
- "Ignore warnings about a lack of human-usable metadata",
- ))
- .arg(opt(
- "allow-dirty",
- "Allow dirty working directories to be packaged",
- ))
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_jobs()
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- ops::package(
- &ws,
- &PackageOpts {
- config,
- verify: !args.is_present("no-verify"),
- list: args.is_present("list"),
- check_metadata: !args.is_present("no-metadata"),
- allow_dirty: args.is_present("allow-dirty"),
- target: args.target(),
- jobs: args.jobs()?,
- registry: None,
- },
- )?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("pkgid")
- .about("Print a fully qualified package specification")
- .arg(Arg::with_name("spec"))
- .arg_package("Argument to get the package id specifier for")
- .arg_manifest_path()
- .after_help(
- "\
-Given a <spec> argument, print out the fully qualified package id specifier.
-This command will generate an error if <spec> is ambiguous as to which package
-it refers to in the dependency graph. If no <spec> is given, then the pkgid for
-the local package is printed.
-
-This command requires that a lockfile is available and dependencies have been
-fetched.
-
-Example Package IDs
-
- pkgid | name | version | url
- |-----------------------------|--------|-----------|---------------------|
- foo | foo | * | *
- foo:1.2.3 | foo | 1.2.3 | *
- crates.io/foo | foo | * | *://crates.io/foo
- crates.io/foo#1.2.3 | foo | 1.2.3 | *://crates.io/foo
- crates.io/bar#foo:1.2.3 | foo | 1.2.3 | *://crates.io/bar
- http://crates.io/foo#1.2.3 | foo | 1.2.3 | http://crates.io/foo
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let spec = args.value_of("spec").or(args.value_of("package"));
- let spec = ops::pkgid(&ws, spec)?;
- println!("{}", spec);
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, PublishOpts};
-
-pub fn cli() -> App {
- subcommand("publish")
- .about("Upload a package to the registry")
- .arg_index()
- .arg(opt("token", "Token to use when uploading").value_name("TOKEN"))
- .arg(opt(
- "no-verify",
- "Don't verify the contents by building them",
- ))
- .arg(opt(
- "allow-dirty",
- "Allow dirty working directories to be packaged",
- ))
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_jobs()
- .arg(opt("dry-run", "Perform all checks without uploading"))
- .arg(opt("registry", "Registry to publish to").value_name("REGISTRY"))
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
- let ws = args.workspace(config)?;
- let index = args.index(config)?;
-
- ops::publish(
- &ws,
- &PublishOpts {
- config,
- token: args.value_of("token").map(|s| s.to_string()),
- index,
- verify: !args.is_present("no-verify"),
- allow_dirty: args.is_present("allow-dirty"),
- target: args.target(),
- jobs: args.jobs()?,
- dry_run: args.is_present("dry-run"),
- registry,
- },
- )?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::print_json;
-
-pub fn cli() -> App {
- subcommand("read-manifest")
- .about(
- "Deprecated, use `cargo metadata --no-deps` instead.
-Print a JSON representation of a Cargo.toml manifest.",
- )
- .arg_manifest_path()
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- print_json(&ws.current()?);
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::core::Verbosity;
-use cargo::ops::{self, CompileFilter, CompileMode};
-
-pub fn cli() -> App {
- subcommand("run")
- .alias("r")
- .setting(AppSettings::TrailingVarArg)
- .about("Run the main binary of the local package (src/main.rs)")
- .arg(Arg::with_name("args").multiple(true))
- .arg_targets_bin_example(
- "Name of the bin target to run",
- "Name of the example target to run",
- )
- .arg_package("Package with the target to run")
- .arg_jobs()
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg_features()
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-If neither `--bin` nor `--example` are given, then if the project only has one
-bin target it will be run. Otherwise `--bin` specifies the bin target to run,
-and `--example` specifies the example target to run. At most one of `--bin` or
-`--example` can be provided.
-
-All the arguments following the two dashes (`--`) are passed to the binary to
-run. If you're passing arguments to both Cargo and the binary, the ones after
-`--` go to the binary, the ones before go to Cargo.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
-
- let mut compile_opts = args.compile_options_for_single_package(config, CompileMode::Build)?;
- if !args.is_present("example") && !args.is_present("bin") {
- compile_opts.filter = CompileFilter::Default {
- required_features_filterable: false,
- };
- };
- match ops::run(&ws, &compile_opts, &values(args, "args"))? {
- None => Ok(()),
- Some(err) => {
- // If we never actually spawned the process then that sounds pretty
- // bad and we always want to forward that up.
- let exit = match err.exit {
- Some(exit) => exit,
- None => return Err(CliError::new(err.into(), 101)),
- };
-
- // If `-q` was passed then we suppress extra error information about
- // a failed process, we assume the process itself printed out enough
- // information about why it failed so we don't do so as well
- let exit_code = exit.code().unwrap_or(101);
- let is_quiet = config.shell().verbosity() == Verbosity::Quiet;
- Err(if is_quiet {
- CliError::code(exit_code)
- } else {
- CliError::new(err.into(), exit_code)
- })
- }
- }
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode};
-
-pub fn cli() -> App {
- subcommand("rustc")
- .setting(AppSettings::TrailingVarArg)
- .about("Compile a package and all of its dependencies")
- .arg(Arg::with_name("args").multiple(true))
- .arg_package("Package to build")
- .arg_jobs()
- .arg_targets_all(
- "Build only this package's library",
- "Build only the specified binary",
- "Build all binaries",
- "Build only the specified example",
- "Build all examples",
- "Build only the specified test target",
- "Build all tests",
- "Build only the specified bench target",
- "Build all benches",
- "Build all targets (lib and bin targets by default)",
- )
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg(opt("profile", "Profile to build the selected target for").value_name("PROFILE"))
- .arg_features()
- .arg_target_triple("Target triple which compiles will be for")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-The specified target for the current package (or package specified by SPEC if
-provided) will be compiled along with all of its dependencies. The specified
-<args>... will all be passed to the final compiler invocation, not any of the
-dependencies. Note that the compiler will still unconditionally receive
-arguments such as -L, --extern, and --crate-type, and the specified <args>...
-will simply be added to the compiler invocation.
-
-This command requires that only one target is being compiled. If more than one
-target is available for the current package the filters of --lib, --bin, etc,
-must be used to select which target is compiled. To pass flags to all compiler
-processes spawned by Cargo, use the $RUSTFLAGS environment variable or the
-`build.rustflags` configuration option.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let mode = match args.value_of("profile") {
- Some("dev") | None => CompileMode::Build,
- Some("test") => CompileMode::Test,
- Some("bench") => CompileMode::Bench,
- Some("check") => CompileMode::Check { test: false },
- Some(mode) => {
- let err = format_err!(
- "unknown profile: `{}`, use dev,
- test, or bench",
- mode
- );
- return Err(CliError::new(err, 101));
- }
- };
- let mut compile_opts = args.compile_options_for_single_package(config, mode)?;
- let target_args = values(args, "args");
- compile_opts.target_rustc_args = if target_args.is_empty() {
- None
- } else {
- Some(target_args)
- };
- ops::compile(&ws, &compile_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode, DocOptions};
-
-pub fn cli() -> App {
- subcommand("rustdoc")
- .setting(AppSettings::TrailingVarArg)
- .about("Build a package's documentation, using specified custom flags.")
- .arg(Arg::with_name("args").multiple(true))
- .arg(opt(
- "open",
- "Opens the docs in a browser after the operation",
- ))
- .arg_package("Package to document")
- .arg_jobs()
- .arg_targets_all(
- "Build only this package's library",
- "Build only the specified binary",
- "Build all binaries",
- "Build only the specified example",
- "Build all examples",
- "Build only the specified test target",
- "Build all tests",
- "Build only the specified bench target",
- "Build all benches",
- "Build all targets (default)",
- )
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg_features()
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-The specified target for the current package (or package specified by SPEC if
-provided) will be documented with the specified <opts>... being passed to the
-final rustdoc invocation. Dependencies will not be documented as part of this
-command. Note that rustdoc will still unconditionally receive arguments such
-as -L, --extern, and --crate-type, and the specified <opts>... will simply be
-added to the rustdoc invocation.
-
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be documented. If it is not given, then the
-current package is documented. For more information on SPEC and its format, see
-the `cargo help pkgid` command.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
- let mut compile_opts =
- args.compile_options_for_single_package(config, CompileMode::Doc { deps: false })?;
- let target_args = values(args, "args");
- compile_opts.target_rustdoc_args = if target_args.is_empty() {
- None
- } else {
- Some(target_args)
- };
- let doc_opts = DocOptions {
- open_result: args.is_present("open"),
- compile_opts,
- };
- ops::doc(&ws, &doc_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use std::cmp::min;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("search")
- .about("Search packages in crates.io")
- .arg(Arg::with_name("query").multiple(true))
- .arg_index()
- .arg(
- opt(
- "limit",
- "Limit the number of results (default: 10, max: 100)",
- ).value_name("LIMIT"),
- )
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
- let index = args.index(config)?;
- let limit = args.value_of_u32("limit")?;
- let limit = min(100, limit.unwrap_or(10));
- let query: Vec<&str> = args.values_of("query").unwrap_or_default().collect();
- let query: String = query.join("+");
- ops::search(&query, config, index, limit, registry)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, CompileMode};
-
-pub fn cli() -> App {
- subcommand("test")
- .alias("t")
- .setting(AppSettings::TrailingVarArg)
- .about("Execute all unit and integration tests of a local package")
- .arg(
- Arg::with_name("TESTNAME")
- .help("If specified, only run tests containing this string in their names"),
- )
- .arg(
- Arg::with_name("args")
- .help("Arguments for the test binary")
- .multiple(true)
- .last(true),
- )
- .arg_targets_all(
- "Test only this package's library",
- "Test only the specified binary",
- "Test all binaries",
- "Check that the specified examples compile",
- "Check that all examples compile",
- "Test only the specified test target",
- "Test all tests",
- "Test only the specified bench target",
- "Test all benches",
- "Test all targets (default)",
- )
- .arg(opt("doc", "Test only this library's documentation"))
- .arg(opt("no-run", "Compile, but don't run tests"))
- .arg(opt("no-fail-fast", "Run all tests regardless of failure"))
- .arg_package_spec(
- "Package to run tests for",
- "Test all packages in the workspace",
- "Exclude packages from the test",
- )
- .arg_jobs()
- .arg_release("Build artifacts in release mode, with optimizations")
- .arg_features()
- .arg_target_triple("Build for the target triple")
- .arg_target_dir()
- .arg_manifest_path()
- .arg_message_format()
- .after_help(
- "\
-The test filtering argument `TESTNAME` and all the arguments following the
-two dashes (`--`) are passed to the test binaries and thus to libtest
-(rustc's built in unit-test and micro-benchmarking framework). If you're
-passing arguments to both Cargo and the binary, the ones after `--` go to the
-binary, the ones before go to Cargo. For details about libtest's arguments see
-the output of `cargo test -- --help`. As an example, this will run all
-tests with `foo` in their name on 3 threads in parallel:
-
- cargo test foo -- --test-threads 3
-
-If the --package argument is given, then SPEC is a package id specification
-which indicates which package should be tested. If it is not given, then the
-current package is tested. For more information on SPEC and its format, see the
-`cargo help pkgid` command.
-
-All packages in the workspace are tested if the `--all` flag is supplied. The
-`--all` flag is automatically assumed for a virtual manifest.
-Note that `--exclude` has to be specified in conjunction with the `--all` flag.
-
-The --jobs argument affects the building of the test executable but does
-not affect how many jobs are used when running the tests. The default value
-for the --jobs argument is the number of CPUs. If you want to control the
-number of simultaneous running test cases, pass the `--test-threads` option
-to the test binaries:
-
- cargo test -- --test-threads=1
-
-Compilation can be configured via the `test` profile in the manifest.
-
-By default the rust test harness hides output from test execution to
-keep results readable. Test output can be recovered (e.g. for debugging)
-by passing `--nocapture` to the test binaries:
-
- cargo test -- --nocapture
-
-To get the list of all options available for the test binaries use this:
-
- cargo test -- --help
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
-
- let mut compile_opts = args.compile_options(config, CompileMode::Test)?;
- let doc = args.is_present("doc");
- if doc {
- compile_opts.mode = ops::CompileMode::Doctest;
- compile_opts.filter = ops::CompileFilter::new(
- true,
- Vec::new(),
- false,
- Vec::new(),
- false,
- Vec::new(),
- false,
- Vec::new(),
- false,
- false,
- );
- }
-
- let ops = ops::TestOptions {
- no_run: args.is_present("no-run"),
- no_fail_fast: args.is_present("no-fail-fast"),
- only_doc: doc,
- compile_opts,
- };
-
- // TESTNAME is actually an argument of the test binary, but it's
- // important so we explicitly mention it and reconfigure
- let mut test_args = vec![];
- test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
- test_args.extend(
- args.values_of("args")
- .unwrap_or_default()
- .map(|s| s.to_string()),
- );
-
- let err = ops::run_tests(&ws, &ops, &test_args)?;
- return match err {
- None => Ok(()),
- Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) {
- Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i),
- None => CliError::new(err.into(), 101),
- }),
- };
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("uninstall")
- .about("Remove a Rust binary")
- .arg(Arg::with_name("spec").multiple(true))
- .arg(multi_opt("bin", "NAME", "Only uninstall the binary NAME"))
- .arg(opt("root", "Directory to uninstall packages from").value_name("DIR"))
- .after_help(
- "\
-The argument SPEC is a package id specification (see `cargo help pkgid`) to
-specify which crate should be uninstalled. By default all binaries are
-uninstalled for a crate but the `--bin` and `--example` flags can be used to
-only uninstall particular binaries.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let root = args.value_of("root");
- let specs = args.values_of("spec").unwrap_or_default().collect();
- ops::uninstall(root, specs, &values(args, "bin"), config)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops::{self, UpdateOptions};
-
-pub fn cli() -> App {
- subcommand("update")
- .about("Update dependencies as recorded in the local lock file")
- .arg_package_spec_simple("Package to update")
- .arg(opt(
- "aggressive",
- "Force updating all dependencies of <name> as well",
- ))
- .arg(opt("precise", "Update a single dependency to exactly PRECISE").value_name("PRECISE"))
- .arg_manifest_path()
- .after_help(
- "\
-This command requires that a `Cargo.lock` already exists as generated by
-`cargo build` or related commands.
-
-If SPEC is given, then a conservative update of the lockfile will be
-performed. This means that only the dependency specified by SPEC will be
-updated. Its transitive dependencies will be updated only if SPEC cannot be
-updated without updating dependencies. All other dependencies will remain
-locked at their currently recorded versions.
-
-If PRECISE is specified, then --aggressive must not also be specified. The
-argument PRECISE is a string representing a precise revision that the package
-being updated should be updated to. For example, if the package comes from a git
-repository, then PRECISE would be the exact revision that the repository should
-be updated to.
-
-If SPEC is not given, then all dependencies will be re-resolved and
-updated.
-
-For more information about package id specifications, see `cargo help pkgid`.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let ws = args.workspace(config)?;
-
- let update_opts = UpdateOptions {
- aggressive: args.is_present("aggressive"),
- precise: args.value_of("precise"),
- to_update: values(args, "package"),
- config,
- };
- ops::update_lockfile(&ws, &update_opts)?;
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use std::collections::HashMap;
-use std::process;
-use std::fs::File;
-use std::io::Read;
-
-use toml;
-
-use cargo::print_json;
-
-pub fn cli() -> App {
- subcommand("verify-project")
- .about("Check correctness of crate manifest")
- .arg_manifest_path()
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- fn fail(reason: &str, value: &str) -> ! {
- let mut h = HashMap::new();
- h.insert(reason.to_string(), value.to_string());
- print_json(&h);
- process::exit(1)
- }
-
- let mut contents = String::new();
- let filename = match args.root_manifest(config) {
- Ok(filename) => filename,
- Err(e) => fail("invalid", &e.to_string()),
- };
-
- let file = File::open(&filename);
- match file.and_then(|mut f| f.read_to_string(&mut contents)) {
- Ok(_) => {}
- Err(e) => fail("invalid", &format!("error reading file: {}", e)),
- };
- if contents.parse::<toml::Value>().is_err() {
- fail("invalid", "invalid-format");
- }
-
- let mut h = HashMap::new();
- h.insert("success".to_string(), "true".to_string());
- print_json(&h);
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo;
-
-pub fn cli() -> App {
- subcommand("version").about("Show version information")
-}
-
-pub fn exec(_config: &mut Config, _args: &ArgMatches) -> CliResult {
- println!("{}", cargo::version());
- Ok(())
-}
+++ /dev/null
-use command_prelude::*;
-
-use cargo::ops;
-
-pub fn cli() -> App {
- subcommand("yank")
- .about("Remove a pushed crate from the index")
- .arg(Arg::with_name("crate"))
- .arg(opt("vers", "The version to yank or un-yank").value_name("VERSION"))
- .arg(opt(
- "undo",
- "Undo a yank, putting a version back into the index",
- ))
- .arg(opt("index", "Registry index to yank from").value_name("INDEX"))
- .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
- .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
- .after_help(
- "\
-The yank command removes a previously pushed crate's version from the server's
-index. This command does not delete any data, and the crate will still be
-available for download via the registry's download link.
-
-Note that existing crates locked to a yanked version will still be able to
-download the yanked version to use it. Cargo will, however, not allow any new
-crates to be locked to any yanked version.
-",
- )
-}
-
-pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
- let registry = args.registry(config)?;
-
- ops::yank(
- config,
- args.value_of("crate").map(|s| s.to_string()),
- args.value_of("vers").map(|s| s.to_string()),
- args.value_of("token").map(|s| s.to_string()),
- args.value_of("index").map(|s| s.to_string()),
- args.is_present("undo"),
- registry,
- )?;
- Ok(())
-}