metadata: add --no-deps option
authorAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 5 Feb 2016 00:56:49 +0000 (03:56 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Fri, 5 Feb 2016 19:26:46 +0000 (22:26 +0300)
The intention is to eventually deprecate `cargo read-manifest`

src/bin/metadata.rs
src/cargo/ops/cargo_output_metadata.rs
tests/test_cargo_metadata.rs

index 43b9ad680977357757d15ffd35a7da912f9e7338..9093a1a78b5818854968ee431b997853aa22f4c7 100644 (file)
@@ -14,6 +14,7 @@ pub struct Options {
     flag_format_version: u32,
     flag_manifest_path: Option<String>,
     flag_no_default_features: bool,
+    flag_no_deps: bool,
     flag_quiet: bool,
     flag_verbose: bool,
 }
@@ -29,6 +30,8 @@ Options:
     -h, --help                 Print this message
     --features FEATURES        Space-separated list of features
     --no-default-features      Do not include the `default` feature
+    --no-deps                  Output information only about the root package
+                               and don't fetch dependencies.
     --manifest-path PATH       Path to the manifest
     --format-version VERSION   Format version [default: 1]
                                Valid values: 1
@@ -46,6 +49,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<ExportInfo
         features: options.flag_features,
         manifest_path: &manifest,
         no_default_features: options.flag_no_default_features,
+        no_deps: options.flag_no_deps,
         version: options.flag_format_version,
     };
 
index a5ebdc10094371e3e35561c8b7ab2909d5f59de3..17b9656f01f79f9c6409c26f2019fa6157b49258 100644 (file)
@@ -15,6 +15,7 @@ pub struct OutputMetadataOptions<'a> {
     pub features: Vec<String>,
     pub manifest_path: &'a Path,
     pub no_default_features: bool,
+    pub no_deps: bool,
     pub version: u32,
 }
 
@@ -22,16 +23,37 @@ pub struct OutputMetadataOptions<'a> {
 /// used versions - considering overrides - and writes all dependencies in a JSON
 /// format to stdout.
 pub fn output_metadata(opt: OutputMetadataOptions, config: &Config) -> CargoResult<ExportInfo> {
+    if opt.version != VERSION {
+        bail!("metadata version {} not supported, only {} is currently supported",
+              opt.version, VERSION);
+    }
+    if opt.no_deps {
+        metadata_no_deps(opt, config)
+    } else {
+        metadata_full(opt, config)
+    }
+}
+
+fn metadata_no_deps(opt: OutputMetadataOptions, config: &Config) -> CargoResult<ExportInfo> {
+    let mut source = try!(PathSource::for_path(opt.manifest_path.parent().unwrap(), config));
+
+    Ok(ExportInfo {
+        packages: vec![try!(source.root_package())],
+        resolve: None,
+        version: VERSION,
+    })
+}
+
+fn metadata_full(opt: OutputMetadataOptions, config: &Config) -> CargoResult<ExportInfo> {
     let deps = try!(resolve_dependencies(opt.manifest_path,
                                          config,
                                          opt.features,
                                          opt.no_default_features));
     let (packages, resolve) = deps;
 
-    assert_eq!(opt.version, VERSION);
     Ok(ExportInfo {
         packages: packages,
-        resolve: MetadataResolve(resolve),
+        resolve: Some(MetadataResolve(resolve)),
         version: VERSION,
     })
 }
@@ -39,7 +61,7 @@ pub fn output_metadata(opt: OutputMetadataOptions, config: &Config) -> CargoResu
 #[derive(RustcEncodable)]
 pub struct ExportInfo {
     packages: Vec<Package>,
-    resolve: MetadataResolve,
+    resolve: Option<MetadataResolve>,
     version: u32,
 }
 
index e62cb186ff0bd58e425f45506bb3dffa20a4b696..86761e3bb0aae1a274f7fac7091c6918e9a4e225 100644 (file)
@@ -1,6 +1,6 @@
 use hamcrest::assert_that;
 use support::registry::Package;
-use support::{project, execs, basic_bin_manifest};
+use support::{project, execs, basic_bin_manifest, main_file};
 
 
 fn setup() {}
@@ -45,7 +45,7 @@ test!(cargo_metadata_simple {
 });
 
 
-test!(cargo_metadata_with_deps {
+test!(cargo_metadata_with_deps_and_version {
     let p = project("foo")
         .file("Cargo.toml", r#"
             [project]
@@ -64,7 +64,10 @@ test!(cargo_metadata_with_deps {
     Package::new("baz", "0.0.1").publish();
     Package::new("bar", "0.0.1").dep("baz", "0.0.1").publish();
 
-    assert_that(p.cargo_process("metadata").arg("-q"), execs().with_json(r#"
+    assert_that(p.cargo_process("metadata")
+                 .arg("-q")
+                 .arg("--format-version").arg("1"),
+                execs().with_json(r#"
     {
         "packages": [
             {
@@ -180,3 +183,95 @@ failed to parse manifest at `[..]`
 Caused by:
   no `package` or `project` section found."))
 });
+
+const MANIFEST_OUTPUT: &'static str=
+    r#"
+{
+    "packages": [{
+        "name":"foo",
+        "version":"0.5.0",
+        "id":"foo[..]0.5.0[..](path+file://[..]/foo)",
+        "source":null,
+        "dependencies":[],
+        "targets":[{
+            "kind":["bin"],
+            "name":"foo",
+            "src_path":"src[..]foo.rs"
+        }],
+        "features":{},
+        "manifest_path":"[..]Cargo.toml"
+    }],
+    "resolve": null,
+    "version": 1
+}"#;
+
+test!(cargo_metadata_no_deps_path_to_cargo_toml_relative {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+        assert_that(p.cargo_process("metadata").arg("--no-deps")
+                     .arg("--manifest-path").arg("foo/Cargo.toml")
+                     .cwd(p.root().parent().unwrap()),
+                    execs().with_status(0)
+                           .with_json(MANIFEST_OUTPUT));
+});
+
+test!(cargo_metadata_no_deps_path_to_cargo_toml_absolute {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+    assert_that(p.cargo_process("metadata").arg("--no-deps")
+                 .arg("--manifest-path").arg(p.root().join("Cargo.toml"))
+                 .cwd(p.root().parent().unwrap()),
+                execs().with_status(0)
+                       .with_json(MANIFEST_OUTPUT));
+});
+
+test!(cargo_metadata_no_deps_path_to_cargo_toml_parent_relative {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+    assert_that(p.cargo_process("metadata").arg("--no-deps")
+                 .arg("--manifest-path").arg("foo")
+                 .cwd(p.root().parent().unwrap()),
+                execs().with_status(101)
+                       .with_stderr("the manifest-path must be a path to a Cargo.toml file"));
+});
+
+test!(cargo_metadata_no_deps_path_to_cargo_toml_parent_absolute {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+    assert_that(p.cargo_process("metadata").arg("--no-deps")
+                 .arg("--manifest-path").arg(p.root())
+                 .cwd(p.root().parent().unwrap()),
+                execs().with_status(101)
+                       .with_stderr("the manifest-path must be a path to a Cargo.toml file"));
+});
+
+test!(cargo_metadata_no_deps_cwd {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+    assert_that(p.cargo_process("metadata").arg("--no-deps")
+                 .cwd(p.root()),
+                execs().with_status(0)
+                       .with_json(MANIFEST_OUTPUT));
+});
+
+test!(carg_metadata_bad_version {
+    let p = project("foo")
+        .file("Cargo.toml", &basic_bin_manifest("foo"))
+        .file("src/foo.rs", &main_file(r#""i am foo""#, &[]));
+
+    assert_that(p.cargo_process("metadata").arg("--no-deps")
+                 .arg("--format-version").arg("2")
+                 .cwd(p.root()),
+                execs().with_status(101)
+    .with_stderr("metadata version 2 not supported, only 1 is currently supported"));
+});