-use std::collections::HashMap;
+use std::collections::{HashMap, TreeMap};
use regex::Regex;
use serialize::{Encodable, Encoder, Decodable, Decoder};
#[deriving(Encodable, Decodable, Show)]
pub struct EncodableResolve {
package: Option<Vec<EncodableDependency>>,
- root: EncodableDependency
+ root: EncodableDependency,
+ metadata: Option<Metadata>,
}
+pub type Metadata = TreeMap<String, String>;
+
impl EncodableResolve {
pub fn to_resolve(&self, default: &SourceId) -> CargoResult<Resolve> {
let mut g = Graph::new();
}
let root = self.root.to_package_id(default);
- Ok(Resolve { graph: g, root: try!(root), features: HashMap::new() })
+ Ok(Resolve {
+ graph: g,
+ root: try!(root),
+ features: HashMap::new(),
+ metadata: self.metadata.clone(),
+ })
}
}
EncodableResolve {
package: Some(encodable),
- root: encodable_resolve_node(&self.root, &self.root, &self.graph)
+ root: encodable_resolve_node(&self.root, &self.root, &self.graph),
+ metadata: self.metadata.clone(),
}.encode(s)
}
}
use util::graph::{Nodes, Edges};
pub use self::encode::{EncodableResolve, EncodableDependency, EncodablePackageId};
+pub use self::encode::Metadata;
mod encode;
pub struct Resolve {
graph: Graph<PackageId>,
features: HashMap<PackageId, HashSet<String>>,
- root: PackageId
+ root: PackageId,
+ metadata: Option<Metadata>,
}
pub enum ResolveMethod<'a> {
fn new(root: PackageId) -> Resolve {
let mut g = Graph::new();
g.add(root.clone(), []);
- Resolve { graph: g, root: root, features: HashMap::new() }
+ Resolve { graph: g, root: root, features: HashMap::new(), metadata: None }
+ }
+
+ pub fn copy_metadata(&mut self, other: &Resolve) {
+ self.metadata = other.metadata.clone();
}
pub fn iter(&self) -> Nodes<PackageId> {
let lockfile = package.get_manifest_path().dir_path().join("Cargo.lock");
let source_id = package.get_package_id().get_source_id();
- match try!(ops::load_lockfile(&lockfile, source_id)) {
- Some(r) => try!(add_lockfile_sources(registry, package, &r)),
+ let previous_resolve = try!(ops::load_lockfile(&lockfile, source_id));
+ match previous_resolve {
+ Some(ref r) => try!(add_lockfile_sources(registry, package, r)),
None => try!(registry.add_sources(package.get_source_ids())),
}
- let resolved = try!(resolver::resolve(package.get_summary(),
- resolver::ResolveEverything,
- registry));
+ let mut resolved = try!(resolver::resolve(package.get_summary(),
+ resolver::ResolveEverything,
+ registry));
+ match previous_resolve {
+ Some(ref prev) => resolved.copy_metadata(prev),
+ None => {}
+ }
try!(ops::write_resolve(package, &resolved));
Ok(resolved)
}
let lockfile = package.get_root().join("Cargo.lock");
let source_id = package.get_package_id().get_source_id();
- let resolve = match try!(load_lockfile(&lockfile, source_id)) {
+ let previous_resolve = match try!(load_lockfile(&lockfile, source_id)) {
Some(resolve) => resolve,
None => return Err(human("A Cargo.lock must exist before it is updated"))
};
match opts.to_update {
Some(name) => {
let mut to_avoid = HashSet::new();
- let dep = try!(resolve.query(name));
+ let dep = try!(previous_resolve.query(name));
if opts.aggressive {
- let mut visited = HashSet::new();
- fill_with_deps(&resolve, dep, &mut to_avoid, &mut visited);
+ fill_with_deps(&previous_resolve, dep, &mut to_avoid,
+ &mut HashSet::new());
} else {
to_avoid.insert(dep.get_source_id());
match opts.precise {
None => {}
}
}
- sources.extend(resolve.iter()
+ sources.extend(previous_resolve.iter()
.map(|p| p.get_source_id())
.filter(|s| !to_avoid.contains(s))
.map(|s| s.clone()));
}
try!(registry.add_sources(sources));
- let resolve = try!(resolver::resolve(package.get_summary(),
- resolver::ResolveEverything,
- &mut registry));
-
+ let mut resolve = try!(resolver::resolve(package.get_summary(),
+ resolver::ResolveEverything,
+ &mut registry));
+ resolve.copy_metadata(&previous_resolve);
try!(write_resolve(&package, &resolve));
return Ok(());
emit_package(dep, &mut out);
}
+ match e.toml.find(&"metadata".to_string()) {
+ Some(metadata) => {
+ out.push_str("[metadata]\n");
+ out.push_str(metadata.to_string().as_slice());
+ }
+ None => {}
+ }
+
try!(File::create(&loc).write_str(out.as_slice()));
Ok(())
}
let lock4 = File::open(&lockfile).read_to_string().assert();
assert_eq!(lock1, lock4);
})
+
+test!(preserve_metadata {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("src/main.rs", "fn main() {}")
+ .file("bar/Cargo.toml", r#"
+ [package]
+ name = "bar"
+ authors = []
+ version = "0.0.1"
+ "#)
+ .file("bar/src/lib.rs", "");
+
+ assert_that(p.cargo_process("generate-lockfile"),
+ execs().with_status(0));
+
+ let metadata = r#"
+[metadata]
+bar = "baz"
+foo = "bar"
+"#;
+ let lockfile = p.root().join("Cargo.lock");
+ {
+ let lock = File::open(&lockfile).read_to_string().assert();
+ File::create(&lockfile).write_str((lock + metadata).as_slice()).assert();
+ }
+
+ // Build and make sure the metadata is still there
+ assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
+ execs().with_status(0));
+ let lock = File::open(&lockfile).read_to_string().assert();
+ assert!(lock.as_slice().contains(metadata.trim()), "{}", lock);
+
+ // Update and make sure the metadata is still there
+ assert_that(p.process(cargo_dir().join("cargo")).arg("update"),
+ execs().with_status(0));
+ let lock = File::open(&lockfile).read_to_string().assert();
+ assert!(lock.as_slice().contains(metadata.trim()), "{}", lock);
+})