1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use std::path::Path;
use rustc_serialize::{Encodable, Encoder};
use core::resolver::Resolve;
use core::{Source, Package, PackageId, PackageSet};
use ops;
use sources::PathSource;
use util::config::Config;
use util::CargoResult;
const VERSION: u32 = 1;
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,
}
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;
let packages = try!(packages.package_ids()
.map(|i| packages.get(i).map(|p| p.clone()))
.collect());
Ok(ExportInfo {
packages: packages,
resolve: Some(MetadataResolve(resolve)),
version: VERSION,
})
}
#[derive(RustcEncodable)]
pub struct ExportInfo {
packages: Vec<Package>,
resolve: Option<MetadataResolve>,
version: u32,
}
struct MetadataResolve(Resolve);
impl Encodable for MetadataResolve {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
#[derive(RustcEncodable)]
struct EncodableResolve<'a> {
root: &'a PackageId,
nodes: Vec<Node<'a>>,
}
#[derive(RustcEncodable)]
struct Node<'a> {
id: &'a PackageId,
dependencies: Vec<&'a PackageId>,
}
let resolve = &self.0;
let encodable = EncodableResolve {
root: resolve.root(),
nodes: resolve.iter().map(|id| {
Node {
id: id,
dependencies: resolve.deps(id)
.map(|it| it.collect())
.unwrap_or(Vec::new()),
}
}).collect(),
};
encodable.encode(s)
}
}
fn resolve_dependencies<'a>(manifest: &Path,
config: &'a Config,
features: Vec<String>,
no_default_features: bool)
-> CargoResult<(PackageSet<'a>, Resolve)> {
let mut source = try!(PathSource::for_path(manifest.parent().unwrap(), config));
try!(source.update());
let package = try!(source.root_package());
ops::resolve_dependencies(&package,
config,
Some(Box::new(source)),
features,
no_default_features)
}