extern crate clap;
-use std::cmp::min;
-use std::collections::HashMap;
-use std::fs::File;
-use std::io::{self, Read, BufRead};
-use std::process;
-
use clap::{AppSettings, Arg, ArgMatches};
-use toml;
-use cargo::{self, Config, CargoError, CliResult, CliError};
-use cargo::core::{Source, SourceId, GitReference, Package, Verbosity};
-use cargo::ops::{self, CompileMode, OutputMetadataOptions};
-use cargo::sources::{GitSource, RegistrySource};
-use cargo::util::{ToUrl, CargoResultExt};
+use cargo::{self, Config, CliResult};
use super::list_commands;
use super::commands;
}
if args.subcommand_name().is_none() {
- cli().print_help()?;
- return Ok(());
}
execute_subcommand(config, args)
&args.values_of_lossy("unstable-features").unwrap_or_default(),
)?;
- match args.subcommand() {
- ("bench", Some(args)) => {
- let ws = args.workspace(config)?;
- let mut compile_opts = args.compile_options(config, CompileMode::Bench)?;
- compile_opts.release = true;
-
- let ops = 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)
- })
- }
- }
- }
- ("build", Some(args)) => {
- let mut ws = args.workspace(config)?;
- let compile_opts = args.compile_options(config, CompileMode::Build)?;
- ops::compile(&ws, &compile_opts)?;
- Ok(())
- }
- ("check", Some(args)) => {
- 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(())
- }
- ("clean", Some(args)) => {
- let ws = args.workspace(config)?;
- let opts = ops::CleanOptions {
- config,
- spec: values(args, "package"),
- target: args.target(),
- release: args.is_present("release"),
- };
- ops::clean(&ws, &opts)?;
- Ok(())
- }
- ("doc", Some(args)) => {
- let ws = args.workspace(config)?;
- let mode = ops::CompileMode::Doc { deps: !args.is_present("no-deps") };
- let compile_opts = args.compile_options(config, mode)?;
- let doc_opts = ops::DocOptions {
- open_result: args.is_present("open"),
- compile_opts,
- };
- ops::doc(&ws, &doc_opts)?;
- Ok(())
- }
- ("fetch", Some(args)) => {
- let ws = args.workspace(config)?;
- ops::fetch(&ws)?;
- Ok(())
- }
- ("generate-lockfile", Some(args)) => {
- let ws = args.workspace(config)?;
- ops::generate_lockfile(&ws)?;
- Ok(())
- }
- ("git-checkout", Some(args)) => {
- 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(())
- }
- ("init", Some(args)) => {
- let opts = args.new_options()?;
- ops::init(&opts, config)?;
- config.shell().status("Created", format!("{} project", opts.kind))?;
- Ok(())
- }
- ("install", Some(args)) => {
- 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 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") {
- SourceId::for_path(&config.cwd().join(path))?
- } else if krates.is_empty() {
- 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, version, &compile_opts, args.is_present("force"))?;
- }
- Ok(())
- }
- ("locate-project", Some(args)) => {
- 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();
-
- #[derive(Serialize)]
- pub struct ProjectLocation {
- root: String
- }
-
- let location = ProjectLocation { root };
-
- cargo::print_json(&location);
- Ok(())
- }
- ("login", Some(args)) => {
- 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(())
+ let (cmd, args) = match args.subcommand() {
+ (cmd, Some(args)) => (cmd, args),
+ _ => {
+ cli().print_help()?;
+ return Ok(());
}
- ("metadata", Some(args)) => {
- 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)?;
- cargo::print_json(&result);
- Ok(())
- }
- ("new", Some(args)) => {
- let opts = args.new_options()?;
- ops::new(&opts, config)?;
- let path = args.value_of("path").unwrap();
- config.shell().status("Created", format!("{} `{}` project", opts.kind, path))?;
- Ok(())
- }
- ("owner", Some(args)) => {
- let registry = args.registry(config)?;
- let opts = ops::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(())
- }
- ("package", Some(args)) => {
- let ws = args.workspace(config)?;
- ops::package(&ws, &ops::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(())
- }
- ("pkgid", Some(args)) => {
- 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(())
- }
- ("publish", Some(args)) => {
- let registry = args.registry(config)?;
- let ws = args.workspace(config)?;
- let index = args.index(config)?;
-
- ops::publish(&ws, &ops::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(())
- }
- ("read-manifest", Some(args)) => {
- let root = args.root_manifest(config)?;
- let pkg = Package::for_path(&root, config)?;
- cargo::print_json(&pkg);
- Ok(())
- }
- ("run", Some(args)) => {
- 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 = ops::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)
- })
- }
- }
- }
- ("rustc", Some(args)) => {
- 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,
- )?;
- compile_opts.target_rustc_args = Some(values(args, "args"));
- ops::compile(&ws, &compile_opts)?;
- Ok(())
- }
- ("rustdoc", Some(args)) => {
- let ws = args.workspace(config)?;
- let mut compile_opts = args.compile_options_for_single_package(
- config, CompileMode::Doc { deps: false },
- )?;
- compile_opts.target_rustdoc_args = Some(values(args, "args"));
- let doc_opts = ops::DocOptions {
- open_result: args.is_present("open"),
- compile_opts,
- };
- ops::doc(&ws, &doc_opts)?;
- Ok(())
- }
- ("search", Some(args)) => {
- 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(())
- }
- ("test", Some(args)) => {
- 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),
- })
- }
- };
- }
- ("uninstall", Some(args)) => {
- 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(())
- }
- ("update", Some(args)) => {
- let ws = args.workspace(config)?;
-
- let update_opts = ops::UpdateOptions {
- aggressive: args.is_present("aggressive"),
- precise: args.value_of("precise"),
- to_update: values(args, "package"),
- config,
- };
- ops::update_lockfile(&ws, &update_opts)?;
- Ok(())
- }
- ("verify-project", Some(args)) => {
- fn fail(reason: &str, value: &str) -> ! {
- let mut h = HashMap::new();
- h.insert(reason.to_string(), value.to_string());
- cargo::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());
- cargo::print_json(&h);
- Ok(())
- }
- ("version", _) => {
- println!("{}", cargo::version());
- Ok(())
- }
- ("yank", Some(args)) => {
- let registry = args.registry(config)?;
+ if let Some(exec) = commands::builtin_exec(cmd) {
+ return exec(config, args);
+ }
- 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(())
- }
- (cmd, Some(args)) => {
- if let Some(mut alias) = super::aliased_command(config, cmd)? {
- 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 execute_subcommand(config, args);
- }
- let mut ext_args: Vec<&str> = vec![cmd];
- ext_args.extend(args.values_of("").unwrap_or_default());
- super::execute_external_subcommand(config, cmd, &ext_args)
- }
- _ => Ok(())
+ if let Some(mut alias) = super::aliased_command(config, cmd)? {
+ 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 execute_subcommand(config, args);
}
+ let mut ext_args: Vec<&str> = vec![cmd];
+ ext_args.extend(args.values_of("").unwrap_or_default());
+ super::execute_external_subcommand(config, cmd, &ext_args)
}
use std::path::PathBuf;
-use clap::{self, SubCommand, AppSettings, ArgMatches};
-use cargo::{Config, CargoResult};
+use clap::{self, SubCommand};
+use cargo::CargoResult;
use cargo::core::Workspace;
use cargo::ops::{CompileMode, CompileOptions, CompileFilter, Packages, MessageFormat,
VersionControl, NewOptions};
use cargo::util::important_paths::find_root_manifest_for_wd;
-pub use clap::Arg;
+pub use clap::{Arg, ArgMatches, AppSettings};
+pub use cargo::{Config, CliResult, CliError};
pub type App = clap::App<'static, 'static>;
use command_prelude::*;
-use clap::AppSettings;
+
+use cargo::ops::{self, CompileMode, TestOptions};
pub fn cli() -> App {
subcommand("bench")
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)
+ })
+ }
+ }
+}
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")
")
}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ let compile_opts = args.compile_options(config, CompileMode::Build)?;
+ ops::compile(&ws, &compile_opts)?;
+ Ok(())
+}
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")
`#[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(())
+}
use command_prelude::*;
+use cargo::ops::{self, CleanOptions};
+
pub fn cli() -> App {
subcommand("clean")
.about("Remove artifacts that cargo has generated in the past")
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"),
+ };
+ ops::clean(&ws, &opts)?;
+ Ok(())
+}
use command_prelude::*;
+use cargo::ops::{self, CompileMode, DocOptions};
+
pub fn cli() -> App {
subcommand("doc")
.about("Build a package's documentation")
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(())
+}
use command_prelude::*;
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("fetch")
.about("Fetch dependencies of a package from the network")
all updated.
")
}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ ops::fetch(&ws)?;
+ Ok(())
+}
use command_prelude::*;
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("generate-lockfile")
.about("Generate the lockfile for a project")
all updated.
")
}
+
+pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
+ let ws = args.workspace(config)?;
+ ops::generate_lockfile(&ws)?;
+ Ok(())
+}
use command_prelude::*;
+use cargo::core::{GitReference, SourceId, Source};
+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(())
+}
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()?;
+ ops::init(&opts, config)?;
+ config.shell().status("Created", format!("{} project", opts.kind))?;
+ Ok(())
+}
use command_prelude::*;
+use cargo::core::{GitReference, SourceId};
+use cargo::ops::{self, CompileMode};
+use cargo::util::ToUrl;
+
pub fn cli() -> App {
subcommand("install")
.about("Create a new cargo package in an existing directory")
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 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") {
+ SourceId::for_path(&config.cwd().join(path))?
+ } else if krates.is_empty() {
+ 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, version, &compile_opts, args.is_present("force"))?;
+ }
+ Ok(())
+}
use command_prelude::*;
+use cargo::print_json;
+
pub fn cli() -> App {
subcommand("locate-project")
.about("Checkout a copy of a Git repository")
.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(())
+}
use command_prelude::*;
+use std::io::{self, BufRead};
+
+use cargo::core::{SourceId, Source};
+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. \
.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(())
+}
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, \
.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(())
+}
]
}
+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)
+}
-mod bench;
-mod build;
-mod check;
-mod clean;
-mod doc;
-mod fetch;
-mod generate_lockfile;
-mod git_checkout;
-mod init;
-mod install;
-mod locate_project;
-mod login;
-mod metadata;
-mod new;
-mod owner;
-mod package;
-mod pkgid;
-mod publish;
-mod read_manifest;
-mod run;
-mod rustc;
-mod rustdoc;
-mod search;
-mod test;
-mod uninstall;
-mod update;
-mod verify_project;
-mod version;
-mod yank;
+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;
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()?;
+ ops::new(&opts, config)?;
+ let path = args.value_of("path").unwrap();
+ config.shell().status("Created", format!("{} `{}` project", opts.kind, path))?;
+ Ok(())
+}
use command_prelude::*;
+use cargo::ops::{self, OwnersOptions};
+
pub fn cli() -> App {
subcommand("owner")
.about("Manage the owners of a crate on the registry")
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(())
+}
use command_prelude::*;
+use cargo::ops::{self, PackageOpts};
+
+
pub fn cli() -> App {
subcommand("package")
.about("Assemble the local package into a distributable tarball")
.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(())
+}
use command_prelude::*;
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("pkgid")
.about("Print a fully qualified package specification")
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(())
+}
use command_prelude::*;
+use cargo::ops::{self, PublishOpts};
+
pub fn cli() -> App {
subcommand("publish")
.about("Upload a package to the registry")
)
.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(())
+}
use command_prelude::*;
+use cargo::core::Package;
+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 root = args.root_manifest(config)?;
+ let pkg = Package::for_path(&root, config)?;
+ print_json(&pkg);
+ Ok(())
+}
-use clap::AppSettings;
-
use command_prelude::*;
+use cargo::core::Verbosity;
+use cargo::ops::{self, CompileMode, CompileFilter};
+
pub fn cli() -> App {
subcommand("run").alias("r")
.setting(AppSettings::TrailingVarArg)
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)
+ })
+ }
+ }
+}
-use clap::AppSettings;
-
use command_prelude::*;
+use cargo::ops::{self, CompileMode};
+
pub fn cli() -> App {
subcommand("rustc")
.setting(AppSettings::TrailingVarArg)
`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,
+ )?;
+ compile_opts.target_rustc_args = Some(values(args, "args"));
+ ops::compile(&ws, &compile_opts)?;
+ Ok(())
+}
-use clap::AppSettings;
-
use command_prelude::*;
+use cargo::ops::{self, CompileMode, DocOptions};
+
pub fn cli() -> App {
subcommand("rustdoc")
.setting(AppSettings::TrailingVarArg)
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 },
+ )?;
+ compile_opts.target_rustdoc_args = Some(values(args, "args"));
+ let doc_opts = DocOptions {
+ open_result: args.is_present("open"),
+ compile_opts,
+ };
+ ops::doc(&ws, &doc_opts)?;
+ Ok(())
+}
use command_prelude::*;
+use std::cmp::min;
+
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("search")
.about("Search packages in crates.io")
)
.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(())
+}
use command_prelude::*;
-use clap::AppSettings;
+
+use cargo::ops::{self, CompileMode};
pub fn cli() -> App {
subcommand("test").alias("t")
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),
+ })
+ }
+ };
+}
use command_prelude::*;
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("uninstall")
.about("Remove a Rust binary")
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(())
+}
use command_prelude::*;
+use cargo::ops::{self, UpdateOptions};
+
pub fn cli() -> App {
subcommand("update")
.about("Update dependencies as recorded in the local lock file")
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(())
+}
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(())
+}
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(())
+}
use command_prelude::*;
+use cargo::ops;
+
pub fn cli() -> App {
subcommand("yank")
.about("Remove a pushed crate from the index")
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(())
+}