Make cargo update more conservative.

As described in #613, this commit switches the semantics of `cargo update foo`
to updating *only* `foo`, not any of its dependencies. A new flag,
`--aggressive` was added to restore the old behavior.

The behavior of attempting to only unlock `foo`, and then if resolve fails
unlock all dependencies of `foo` is unimplemented as it's not super relevant
right now when the majority of dependencies are git dependencies and resolution
cannot fail for version-related reasons.

Closes #613
This commit is contained in:
Alex Crichton 2014-09-21 14:27:30 -07:00
parent 275c97c8b0
commit d1a332d19a
3 changed files with 16 additions and 6 deletions

View file

@ -14,6 +14,7 @@ Usage:
Options:
-h, --help Print this message
--aggressive Force updating all dependencies of <name> as well
--manifest-path PATH Path to the manifest to compile
-v, --verbose Use verbose output
@ -21,9 +22,10 @@ This command requires that a `Cargo.lock` already exists as generated by
`cargo build` or related commands.
If <name> is specified, then a conservative update of the lockfile will be
performed. This means that only the dependency <name> (and all of its transitive
dependencies) will be updated. All other dependencies will remain locked at
their currently recorded versions.
performed. This means that only the dependency <name> will be updated. Its
transitive dependencies will be updated only if <name> cannot be updated without
updating dependencies. All other dependencies will remain locked at their
currently recorded versions.
If <name> is not specified, then all dependencies will be re-resolved and
updated.
@ -34,7 +36,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>
shell.set_verbose(options.flag_verbose);
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
ops::update_lockfile(&root, shell, options.arg_name)
ops::update_lockfile(&root, shell, options.arg_name, options.flag_aggressive)
.map(|_| None).map_err(|err| CliError::from_boxed(err, 101))
}

View file

@ -35,7 +35,8 @@ pub fn generate_lockfile(manifest_path: &Path,
pub fn update_lockfile(manifest_path: &Path,
shell: &mut MultiShell,
to_update: Option<String>) -> CargoResult<()> {
to_update: Option<String>,
aggressive: bool) -> CargoResult<()> {
let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
try!(source.update());
let package = try!(source.get_root_package());
@ -54,7 +55,11 @@ pub fn update_lockfile(manifest_path: &Path,
Some(name) => {
let mut to_avoid = HashSet::new();
for dep in resolve.iter().filter(|d| d.get_name() == name.as_slice()) {
fill_with_deps(&resolve, dep, &mut to_avoid);
if aggressive {
fill_with_deps(&resolve, dep, &mut to_avoid);
} else {
to_avoid.insert(dep);
}
}
resolve.iter().filter(|pkgid| !to_avoid.contains(pkgid))
.map(|pkgid| pkgid.get_source_id().clone()).collect()

View file

@ -687,6 +687,9 @@ test!(update_with_shared_deps {
timer::sleep(Duration::milliseconds(1000));
assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1"),
execs().with_stdout(""));
assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1")
.arg("--aggressive"),
execs().with_stdout(format!("{} git repository `{}`",
UPDATING,
git_project.url())));