mirror of
https://github.com/rust-lang/cargo
synced 2024-10-13 11:12:25 +00:00
Generate the same lock always in a workspace
Previously the "root" of a lock file would erroneously change over time, so instead just ensure that the root of a lock file is always the root of the workspace. Otherwise the contents should always be the same. Closes #2837
This commit is contained in:
parent
d2636907a8
commit
c33dddd505
|
@ -200,21 +200,32 @@ impl Decodable for EncodablePackageId {
|
|||
}
|
||||
}
|
||||
|
||||
impl Encodable for Resolve {
|
||||
pub struct WorkspaceResolve<'a, 'cfg: 'a> {
|
||||
pub ws: &'a Workspace<'cfg>,
|
||||
pub resolve: &'a Resolve,
|
||||
}
|
||||
|
||||
impl<'a, 'cfg> Encodable for WorkspaceResolve<'a, 'cfg> {
|
||||
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||
let mut ids: Vec<&PackageId> = self.graph.iter().collect();
|
||||
let mut ids: Vec<&PackageId> = self.resolve.graph.iter().collect();
|
||||
ids.sort();
|
||||
|
||||
let encodable = ids.iter().filter_map(|&id| {
|
||||
if self.root == *id { return None; }
|
||||
let root = self.ws.members().max_by_key(|member| {
|
||||
member.name()
|
||||
}).unwrap().package_id();
|
||||
|
||||
Some(encodable_resolve_node(id, self))
|
||||
let encodable = ids.iter().filter_map(|&id| {
|
||||
if root == id {
|
||||
return None
|
||||
}
|
||||
|
||||
Some(encodable_resolve_node(id, self.resolve))
|
||||
}).collect::<Vec<EncodableDependency>>();
|
||||
|
||||
EncodableResolve {
|
||||
package: Some(encodable),
|
||||
root: encodable_resolve_node(&self.root, self),
|
||||
metadata: self.metadata.clone(),
|
||||
root: encodable_resolve_node(&root, self.resolve),
|
||||
metadata: self.resolve.metadata.clone(),
|
||||
}.encode(s)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ use util::ChainError;
|
|||
use util::graph::{Nodes, Edges};
|
||||
|
||||
pub use self::encode::{EncodableResolve, EncodableDependency, EncodablePackageId};
|
||||
pub use self::encode::Metadata;
|
||||
pub use self::encode::{Metadata, WorkspaceResolve};
|
||||
|
||||
mod encode;
|
||||
|
||||
|
@ -674,7 +674,7 @@ fn build_features(s: &Summary, method: &Method)
|
|||
match s.features().get(feat) {
|
||||
Some(wanted_features) => {
|
||||
for entry in wanted_features {
|
||||
// If the entry is of the form `foo/bar`, then we just lookup package
|
||||
// If the entry is of the form `foo/bar`, then we just lookup package
|
||||
// `foo` and enable its feature `bar`. We also add `foo` to the used
|
||||
// set because `foo` might have been an optional dependency.
|
||||
//
|
||||
|
@ -703,7 +703,7 @@ fn build_features(s: &Summary, method: &Method)
|
|||
deps.entry(feat.to_string()).or_insert(Vec::new());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
visited.remove(&feat.to_string());
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -4,6 +4,7 @@ use rustc_serialize::{Encodable, Decodable};
|
|||
use toml::{self, Encoder, Value};
|
||||
|
||||
use core::{Resolve, resolver, Workspace};
|
||||
use core::resolver::WorkspaceResolve;
|
||||
use util::{CargoResult, ChainError, human, Filesystem};
|
||||
use util::toml as cargo_toml;
|
||||
|
||||
|
@ -33,7 +34,10 @@ pub fn load_pkg_lockfile(ws: &Workspace) -> CargoResult<Option<Resolve>> {
|
|||
|
||||
pub fn write_pkg_lockfile(ws: &Workspace, resolve: &Resolve) -> CargoResult<()> {
|
||||
let mut e = Encoder::new();
|
||||
resolve.encode(&mut e).unwrap();
|
||||
WorkspaceResolve {
|
||||
ws: ws,
|
||||
resolve: resolve,
|
||||
}.encode(&mut e).unwrap();
|
||||
|
||||
let mut out = String::new();
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#[macro_use]
|
||||
extern crate cargotest;
|
||||
extern crate hamcrest;
|
||||
|
||||
use std::io::Read;
|
||||
use std::fs::File;
|
||||
|
||||
use cargotest::support::{project, execs};
|
||||
use cargotest::support::registry::Package;
|
||||
use hamcrest::{assert_that, existing_file, existing_dir, is_not};
|
||||
|
@ -774,3 +778,49 @@ this may be fixable by ensuring that this crate is depended on by the workspace
|
|||
root: [..]
|
||||
"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lock_doesnt_change_depending_on_crate() {
|
||||
let p = project("foo")
|
||||
.file("Cargo.toml", r#"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
authors = []
|
||||
|
||||
[workspace]
|
||||
members = ['baz']
|
||||
|
||||
[dependencies]
|
||||
foo = "*"
|
||||
"#)
|
||||
.file("src/lib.rs", "")
|
||||
.file("baz/Cargo.toml", r#"
|
||||
[project]
|
||||
name = "baz"
|
||||
version = "0.1.0"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
bar = "*"
|
||||
"#)
|
||||
.file("baz/src/lib.rs", "");
|
||||
p.build();
|
||||
|
||||
Package::new("foo", "1.0.0").publish();
|
||||
Package::new("bar", "1.0.0").publish();
|
||||
|
||||
assert_that(p.cargo("build"),
|
||||
execs().with_status(0));
|
||||
|
||||
let mut lockfile = String::new();
|
||||
t!(t!(File::open(p.root().join("Cargo.lock"))).read_to_string(&mut lockfile));
|
||||
|
||||
assert_that(p.cargo("build").cwd(p.root().join("baz")),
|
||||
execs().with_status(0));
|
||||
|
||||
let mut lockfile2 = String::new();
|
||||
t!(t!(File::open(p.root().join("Cargo.lock"))).read_to_string(&mut lockfile2));
|
||||
|
||||
assert_eq!(lockfile, lockfile2);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue