Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print information about updated packages #1931

Merged
merged 1 commit into from
Aug 28, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 71 additions & 2 deletions src/cargo/ops/cargo_generate_lockfile.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
use std::path::Path;

use core::PackageId;
use core::registry::PackageRegistry;
use core::{Source, Resolve};
use core::{Source, Resolve, SourceId};
use core::resolver::Method;
use ops;
use sources::{PathSource};
@@ -91,6 +91,33 @@ pub fn update_lockfile(manifest_path: &Path,
Method::Everything,
Some(&previous_resolve),
Some(&to_avoid)));

// Summarize what is changing for the user.
let print_change = |status: &str, msg: String| {
opts.config.shell().status(status, msg)
};
for (removed, added) in compare_dependency_graphs(&previous_resolve, &resolve) {
if removed.len() == 1 && added.len() == 1 {
if removed[0].source_id().is_git() {
try!(print_change("Updating", format!("{} -> #{}",
removed[0],
&added[0].source_id().precise().unwrap()[..8])));
} else {
try!(print_change("Updating", format!("{} -> v{}",
removed[0],
added[0].version())));
}
}
else {
for package in removed.iter() {
try!(print_change("Removing", format!("{}", package)));
}
for package in added.iter() {
try!(print_change("Adding", format!("{}", package)));
}
}
}

try!(ops::write_pkg_lockfile(&package, &resolve));
return Ok(());

@@ -108,4 +135,46 @@ pub fn update_lockfile(manifest_path: &Path,
None => {}
}
}

fn compare_dependency_graphs<'a>(previous_resolve: &'a Resolve,
resolve: &'a Resolve) ->
Vec<(Vec<&'a PackageId>, Vec<&'a PackageId>)> {
// Map (package name, package source) to (removed versions, added versions).
fn changes_key<'a>(dep: &'a PackageId) -> (&'a str, &'a SourceId) {
(dep.name(), dep.source_id())
}

fn vec_subtract<T>(a: &[T], b: &[T]) -> Vec<T>
where T: Ord + Clone {
let mut result = a.to_owned();
let mut b = b.to_owned();
b.sort();
result.retain(|x| b.binary_search(x).is_err());
result
}

let mut changes = HashMap::new();

for dep in previous_resolve.iter() {
changes.insert(changes_key(dep), (vec![dep], vec![]));
}
for dep in resolve.iter() {
let (_, ref mut added) = *changes.entry(changes_key(dep))
.or_insert_with(|| (vec![], vec![]));
added.push(dep);
}

for (_, v) in changes.iter_mut() {
let (ref mut old, ref mut new) = *v;
let removed = vec_subtract(old, new);
let added = vec_subtract(new, old);
*old = removed;
*new = added;
}

// Sort the packages by their names.
let mut packages: Vec<_> = changes.keys().map(|x| *x).collect();
packages.sort();
packages.iter().map(|k| changes[k].clone()).collect()
}
}
2 changes: 2 additions & 0 deletions tests/support/mod.rs
Original file line number Diff line number Diff line change
@@ -522,6 +522,8 @@ pub static RUNNING: &'static str = " Running";
pub static COMPILING: &'static str = " Compiling";
pub static FRESH: &'static str = " Fresh";
pub static UPDATING: &'static str = " Updating";
pub static ADDING: &'static str = " Adding";
pub static REMOVING: &'static str = " Removing";
pub static DOCTEST: &'static str = " Doc-tests";
pub static PACKAGING: &'static str = " Packaging";
pub static DOWNLOADING: &'static str = " Downloading";
29 changes: 21 additions & 8 deletions tests/test_cargo_compile_git_deps.rs
Original file line number Diff line number Diff line change
@@ -539,9 +539,12 @@ test!(recompilation {

// Update the dependency and carry on!
assert_that(p.cargo("update"),
execs().with_stdout(&format!("{} git repository `{}`",
execs().with_stdout(&format!("{} git repository `{}`\n\
{} bar v0.5.0 ([..]) -> #[..]\n\
",
UPDATING,
git_project.url())));
git_project.url(),
UPDATING)));
println!("going for the last compile");
assert_that(p.cargo("build"),
execs().with_stdout(&format!("{} bar v0.5.0 ({}#[..])\n\
@@ -657,9 +660,12 @@ test!(update_with_shared_deps {
assert_that(p.cargo("update")
.arg("-p").arg("dep1")
.arg("--aggressive"),
execs().with_stdout(&format!("{} git repository `{}`",
execs().with_stdout(&format!("{} git repository `{}`\n\
{} bar v0.5.0 ([..]) -> #[..]\n\
",
UPDATING,
git_project.url())));
git_project.url(),
UPDATING)));

// Make sure we still only compile one version of the git repo
println!("build");
@@ -782,8 +788,12 @@ test!(two_deps_only_update_one {
assert_that(project.cargo("update")
.arg("-p").arg("dep1"),
execs()
.with_stdout(&format!("{} git repository `{}`\n",
UPDATING, git1.url()))
.with_stdout(&format!("{} git repository `{}`\n\
{} dep1 v0.5.0 ([..]) -> #[..]\n\
",
UPDATING,
git1.url(),
UPDATING))
.with_stderr(""));
});

@@ -941,9 +951,12 @@ test!(dep_with_changed_submodule {
assert_that(project.cargo("update").arg("-v"),
execs()
.with_stderr("")
.with_stdout(&format!("{} git repository `{}`",
.with_stdout(&format!("{} git repository `{}`\n\
{} dep1 v0.5.0 ([..]) -> #[..]\n\
",
UPDATING,
git_project.url())));
git_project.url(),
UPDATING)));

println!("last run");
assert_that(project.cargo("run"), execs()
26 changes: 25 additions & 1 deletion tests/test_cargo_registry.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use std::io::prelude::*;
use cargo::util::process;

use support::{project, execs, cargo_dir};
use support::{UPDATING, DOWNLOADING, COMPILING, PACKAGING, VERIFYING};
use support::{UPDATING, DOWNLOADING, COMPILING, PACKAGING, VERIFYING, ADDING, REMOVING};
use support::paths::{self, CargoPathExt};
use support::registry as r;
use support::git;
@@ -476,6 +476,7 @@ test!(update_lockfile {
.arg("-p").arg("bar").arg("--precise").arg("0.0.2"),
execs().with_status(0).with_stdout(&format!("\
{updating} registry `[..]`
{updating} bar v0.0.1 (registry file://[..]) -> v0.0.2
", updating = UPDATING)));

println!("0.0.2 build");
@@ -492,6 +493,7 @@ test!(update_lockfile {
.arg("-p").arg("bar"),
execs().with_status(0).with_stdout(&format!("\
{updating} registry `[..]`
{updating} bar v0.0.2 (registry file://[..]) -> v0.0.3
", updating = UPDATING)));

println!("0.0.3 build");
@@ -502,6 +504,27 @@ test!(update_lockfile {
{compiling} foo v0.0.1 ({dir})
", downloading = DOWNLOADING, compiling = COMPILING,
dir = p.url())));

println!("new dependencies update");
r::mock_pkg("bar", "0.0.4", &[("spam", "0.2.5", "")]);
r::mock_pkg("spam", "0.2.5", &[]);
assert_that(p.cargo("update")
.arg("-p").arg("bar"),
execs().with_status(0).with_stdout(&format!("\
{updating} registry `[..]`
{updating} bar v0.0.3 (registry file://[..]) -> v0.0.4
{adding} spam v0.2.5 (registry file://[..])
", updating = UPDATING, adding = ADDING)));

println!("new dependencies update");
r::mock_pkg("bar", "0.0.5", &[]);
assert_that(p.cargo("update")
.arg("-p").arg("bar"),
execs().with_status(0).with_stdout(&format!("\
{updating} registry `[..]`
{updating} bar v0.0.4 (registry file://[..]) -> v0.0.5
{removing} spam v0.2.5 (registry file://[..])
", updating = UPDATING, removing = REMOVING)));
});

test!(dev_dependency_not_used {
@@ -760,6 +783,7 @@ test!(update_transitive_dependency {
execs().with_status(0)
.with_stdout(format!("\
{updating} registry `[..]`
{updating} b v0.1.0 (registry [..]) -> v0.1.1
", updating = UPDATING)));

assert_that(p.cargo("build"),