diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index a0b024f7bee..09c2ec2072e 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -62,6 +62,7 @@ macro_rules! each_subcommand( ($macro:ident) => ({ $macro!(login) $macro!(new) $macro!(package) + $macro!(pkgid) $macro!(read_manifest) $macro!(run) $macro!(test) diff --git a/src/bin/pkgid.rs b/src/bin/pkgid.rs new file mode 100644 index 00000000000..48e4b6636e7 --- /dev/null +++ b/src/bin/pkgid.rs @@ -0,0 +1,52 @@ +use docopt; + +use cargo::ops; +use cargo::core::MultiShell; +use cargo::util::{CliResult, CliError}; +use cargo::util::important_paths::{find_root_manifest_for_cwd}; + +docopt!(Options, " +Print a fully qualified package specification + +Usage: + cargo pkgid [options] [] + +Options: + -h, --help Print this message + --manifest-path PATH Path to the manifest to the package to clean + -v, --verbose Use verbose output + +Given a argument, print out the fully qualified package id specifier. +This command will generate an error if is ambiguous as to which package +it refers to in the dependency graph. If no 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 + +", flag_manifest_path: Option, arg_spec: Option) + +pub fn execute(options: Options, + shell: &mut MultiShell) -> CliResult> { + shell.set_verbose(options.flag_verbose); + let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path.clone())); + + let spec = options.arg_spec.as_ref().map(|s| s.as_slice()); + let spec = try!(ops::pkgid(&root, spec, shell).map_err(|err| { + CliError::from_boxed(err, 101) + })); + println!("{}", spec); + Ok(None) +} + diff --git a/src/bin/update.rs b/src/bin/update.rs index 79bd754dea3..f2328a23a67 100644 --- a/src/bin/update.rs +++ b/src/bin/update.rs @@ -10,7 +10,7 @@ docopt!(Options, " Update dependencies as recorded in the local lock file. Usage: - cargo update [options] [] + cargo update [options] [] Options: -h, --help Print this message @@ -21,22 +21,24 @@ Options: This command requires that a `Cargo.lock` already exists as generated by `cargo build` or related commands. -If is specified, then a conservative update of the lockfile will be -performed. This means that only the dependency will be updated. Its -transitive dependencies will be updated only if cannot be updated without -updating dependencies. All other dependencies will remain locked at their -currently recorded versions. +If is given, then a conservative update of the lockfile will be +performed. This means that only the dependency specified by will be +updated. Its transitive dependencies will be updated only if cannot be +updated without updating dependencies. All other dependencies will remain +locked at their currently recorded versions. -If is not specified, then all dependencies will be re-resolved and +If is not given, then all dependencies will be re-resolved and updated. -", flag_manifest_path: Option, arg_name: Option) + +For more information about package ids, see `cargo help pkgid`. +", flag_manifest_path: Option, arg_spec: Option) pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { debug!("executing; cmd=cargo-update; args={}", os::args()); shell.set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - ops::update_lockfile(&root, shell, options.arg_name, options.flag_aggressive) + ops::update_lockfile(&root, shell, options.arg_spec, options.flag_aggressive) .map(|_| None).map_err(|err| CliError::from_boxed(err, 101)) } diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index 0c214a99b18..fbc65c9d361 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -1,4 +1,3 @@ -#![warn(warnings)] use std::collections::HashSet; use std::io::File; diff --git a/src/cargo/ops/cargo_pkgid.rs b/src/cargo/ops/cargo_pkgid.rs new file mode 100644 index 00000000000..3b39bb0e7d7 --- /dev/null +++ b/src/cargo/ops/cargo_pkgid.rs @@ -0,0 +1,25 @@ +use ops; +use core::{MultiShell, Source, PackageIdSpec}; +use sources::{PathSource}; +use util::{CargoResult, human}; + +pub fn pkgid(manifest_path: &Path, + spec: Option<&str>, + _shell: &mut MultiShell) -> CargoResult { + let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); + try!(source.update()); + let package = try!(source.get_root_package()); + + let lockfile = package.get_root().join("Cargo.lock"); + let source_id = package.get_package_id().get_source_id(); + let resolve = match try!(ops::load_lockfile(&lockfile, source_id)) { + Some(resolve) => resolve, + None => return Err(human("A Cargo.lock must exist for this command")) + }; + + let pkgid = match spec { + Some(spec) => try!(resolve.query(spec)), + None => package.get_package_id(), + }; + Ok(PackageIdSpec::from_package_id(pkgid)) +} diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs index 7ea99eb1dd0..67e30def8a7 100644 --- a/src/cargo/ops/mod.rs +++ b/src/cargo/ops/mod.rs @@ -12,6 +12,7 @@ pub use self::cargo_package::package; pub use self::cargo_upload::{upload, upload_configuration, UploadConfig}; pub use self::cargo_upload::{upload_login, http_proxy, http_handle}; pub use self::cargo_fetch::{fetch, resolve_and_fetch}; +pub use self::cargo_pkgid::pkgid; mod cargo_clean; mod cargo_compile; @@ -25,3 +26,4 @@ mod cargo_test; mod cargo_package; mod cargo_upload; mod cargo_fetch; +mod cargo_pkgid;