Only force update git if -u is passed

This will become moot once we have a lockfile, because we'll be able to
check whether the last rev we used is still available and skip fetching.
This commit is contained in:
Yehuda Katz 2014-06-23 18:54:13 -07:00
parent 860ca08ad2
commit 5919fa0dfc
9 changed files with 71 additions and 34 deletions

View File

@ -20,10 +20,13 @@ use cargo::util::important_paths::find_project;
#[deriving(PartialEq,Clone,Decodable,Encodable)] #[deriving(PartialEq,Clone,Decodable,Encodable)]
pub struct Options { pub struct Options {
manifest_path: Option<String> manifest_path: Option<String>,
update_remotes: bool
} }
hammer_config!(Options "Compile the current project") hammer_config!(Options "Compile the current project", |c| {
c.short("update_remotes", 'u')
})
fn main() { fn main() {
execute_main_without_stdin(execute); execute_main_without_stdin(execute);
@ -43,7 +46,9 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
})) }))
}; };
ops::compile(&root, shell).map(|_| None).map_err(|err| { let update = options.update_remotes;
ops::compile(&root, update, shell).map(|_| None).map_err(|err| {
CliError::from_boxed(err, 101) CliError::from_boxed(err, 101)
}) })
} }

View File

@ -37,7 +37,7 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let source_id = SourceId::for_git(&url, reference.as_slice()); let source_id = SourceId::for_git(&url, reference.as_slice());
let mut config = try!(Config::new(shell).map_err(|e| CliError::from_boxed(e, 1))); let mut config = try!(Config::new(shell, true).map_err(|e| CliError::from_boxed(e, 1)));
let mut source = GitSource::new(&source_id, &mut config); let mut source = GitSource::new(&source_id, &mut config);
try!(source.update().map_err(|e| { try!(source.update().map_err(|e| {

View File

@ -1,5 +1,5 @@
use std::vec::Vec; use std::vec::Vec;
use core::{MultiShell, Source, SourceId, Summary, Dependency, PackageId, Package}; use core::{Source, SourceId, Summary, Dependency, PackageId, Package};
use util::{CargoResult, ChainError, Config, human}; use util::{CargoResult, ChainError, Config, human};
pub trait Registry { pub trait Registry {
@ -20,15 +20,15 @@ pub struct PackageRegistry<'a> {
overrides: Vec<Summary>, overrides: Vec<Summary>,
summaries: Vec<Summary>, summaries: Vec<Summary>,
searched: Vec<SourceId>, searched: Vec<SourceId>,
shell: &'a mut MultiShell config: &'a mut Config<'a>
} }
impl<'a> PackageRegistry<'a> { impl<'a> PackageRegistry<'a> {
pub fn new<'a>(source_ids: Vec<SourceId>, pub fn new<'a>(source_ids: Vec<SourceId>,
override_ids: Vec<SourceId>, override_ids: Vec<SourceId>,
shell: &'a mut MultiShell) -> CargoResult<PackageRegistry<'a>> { config: &'a mut Config<'a>) -> CargoResult<PackageRegistry<'a>> {
let mut reg = PackageRegistry::empty(shell); let mut reg = PackageRegistry::empty(config);
for id in source_ids.iter() { for id in source_ids.iter() {
try!(reg.load(id, false)); try!(reg.load(id, false));
@ -41,13 +41,13 @@ impl<'a> PackageRegistry<'a> {
Ok(reg) Ok(reg)
} }
fn empty<'a>(shell: &'a mut MultiShell) -> PackageRegistry<'a> { fn empty<'a>(config: &'a mut Config<'a>) -> PackageRegistry<'a> {
PackageRegistry { PackageRegistry {
sources: vec!(), sources: vec!(),
overrides: vec!(), overrides: vec!(),
summaries: vec!(), summaries: vec!(),
searched: vec!(), searched: vec!(),
shell: shell config: config
} }
} }
@ -82,7 +82,7 @@ impl<'a> PackageRegistry<'a> {
fn load(&mut self, namespace: &SourceId, override: bool) -> CargoResult<()> { fn load(&mut self, namespace: &SourceId, override: bool) -> CargoResult<()> {
(|| { (|| {
let mut source = namespace.load(&mut try!(Config::new(self.shell))); let mut source = namespace.load(self.config);
let dst = if override {&mut self.overrides} else {&mut self.summaries}; let dst = if override {&mut self.overrides} else {&mut self.summaries};
// Ensure the source has fetched all necessary remote data. // Ensure the source has fetched all necessary remote data.

View File

@ -23,14 +23,14 @@
//! //!
use std::os; use std::os;
use util::config::{ConfigValue}; use util::config::{Config, ConfigValue};
use core::{MultiShell, Source, SourceId, PackageSet, resolver}; use core::{MultiShell, Source, SourceId, PackageSet, resolver};
use core::registry::PackageRegistry; use core::registry::PackageRegistry;
use ops; use ops;
use sources::{PathSource}; use sources::{PathSource};
use util::{CargoResult, Wrap, config, internal, human}; use util::{CargoResult, Wrap, config, internal, human};
pub fn compile(manifest_path: &Path, shell: &mut MultiShell) -> CargoResult<()> { pub fn compile(manifest_path: &Path, update: bool, shell: &mut MultiShell) -> CargoResult<()> {
log!(4, "compile; manifest-path={}", manifest_path.display()); log!(4, "compile; manifest-path={}", manifest_path.display());
let mut source = PathSource::for_path(&manifest_path.dir_path()); let mut source = PathSource::for_path(&manifest_path.dir_path());
@ -45,8 +45,10 @@ pub fn compile(manifest_path: &Path, shell: &mut MultiShell) -> CargoResult<()>
let source_ids = package.get_source_ids(); let source_ids = package.get_source_ids();
let packages = { let packages = {
let mut config = try!(Config::new(shell, update));
let mut registry = let mut registry =
try!(PackageRegistry::new(source_ids, override_ids, shell)); try!(PackageRegistry::new(source_ids, override_ids, &mut config));
let resolved = let resolved =
try!(resolver::resolve(package.get_dependencies(), &mut registry)); try!(resolver::resolve(package.get_dependencies(), &mut registry));
@ -58,7 +60,8 @@ pub fn compile(manifest_path: &Path, shell: &mut MultiShell) -> CargoResult<()>
debug!("packages={}", packages); debug!("packages={}", packages);
try!(ops::compile_packages(&package, &PackageSet::new(packages.as_slice()), shell)); let mut config = try!(Config::new(shell, update));
try!(ops::compile_packages(&package, &PackageSet::new(packages.as_slice()), &mut config));
Ok(()) Ok(())
} }

View File

@ -10,20 +10,20 @@ use util::{Config};
type Args = Vec<String>; type Args = Vec<String>;
struct Context<'a> { struct Context<'a, 'b> {
dest: &'a Path, dest: &'a Path,
deps_dir: &'a Path, deps_dir: &'a Path,
primary: bool, primary: bool,
rustc_version: &'a str, rustc_version: &'a str,
compiled_anything: bool, compiled_anything: bool,
config: &'a mut Config<'a> config: &'b mut Config<'b>
} }
pub fn compile_packages(pkg: &Package, deps: &PackageSet, pub fn compile_packages<'a>(pkg: &Package, deps: &PackageSet,
shell: &mut MultiShell) -> CargoResult<()> { config: &'a mut Config<'a>) -> CargoResult<()> {
debug!("compile_packages; pkg={}; deps={}", pkg, deps); debug!("compile_packages; pkg={}; deps={}", pkg, deps);
let mut config = try!(Config::new(shell));
let target_dir = pkg.get_absolute_target_dir(); let target_dir = pkg.get_absolute_target_dir();
let deps_target_dir = target_dir.join("deps"); let deps_target_dir = target_dir.join("deps");
@ -47,7 +47,7 @@ pub fn compile_packages(pkg: &Package, deps: &PackageSet,
primary: false, primary: false,
rustc_version: rustc_version.as_slice(), rustc_version: rustc_version.as_slice(),
compiled_anything: false, compiled_anything: false,
config: &mut config config: config
}; };
// Traverse the dependencies in topological order // Traverse the dependencies in topological order

View File

@ -92,11 +92,20 @@ impl<'a, 'b> Show for GitSource<'a, 'b> {
impl<'a, 'b> Source for GitSource<'a, 'b> { impl<'a, 'b> Source for GitSource<'a, 'b> {
fn update(&mut self) -> CargoResult<()> { fn update(&mut self) -> CargoResult<()> {
try!(self.config.shell().status("Updating", let should_update = self.config.update_remotes() || {
format!("git repository `{}`", self.remote.get_url()))); !self.remote.has_ref(&self.db_path, self.reference.as_slice()).is_ok()
};
let repo = if should_update {
try!(self.config.shell().status("Updating",
format!("git repository `{}`", self.remote.get_url())));
log!(5, "updating git source `{}`", self.remote);
try!(self.remote.checkout(&self.db_path))
} else {
self.remote.db_at(&self.db_path)
};
log!(5, "updating git source `{}`", self.remote);
let repo = try!(self.remote.checkout(&self.db_path));
try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path)); try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));
self.path_source.update() self.path_source.update()

View File

@ -50,13 +50,13 @@ macro_rules! git(
) )
macro_rules! git_output( macro_rules! git_output(
($config:expr, $str:expr, $($rest:expr),*) => ( ($config:expr, $str:expr, $($rest:expr),*) => ({
try!(git_output(&$config, format!($str, $($rest),*))) try!(git_output(&$config, format!($str, $($rest),*)))
); });
($config:expr, $str:expr) => ( ($config:expr, $str:expr) => ({
try!(git_output(&$config, format!($str))) try!(git_output(&$config, format!($str)))
); });
) )
macro_rules! errln( macro_rules! errln(
@ -146,6 +146,11 @@ impl GitRemote {
&self.url &self.url
} }
pub fn has_ref<S: Str>(&self, path: &Path, reference: S) -> CargoResult<()> {
git_output!(*path, "rev-parse {}", reference.as_slice());
Ok(())
}
pub fn checkout(&self, into: &Path) -> CargoResult<GitDatabase> { pub fn checkout(&self, into: &Path) -> CargoResult<GitDatabase> {
if into.exists() { if into.exists() {
try!(self.fetch_into(into)); try!(self.fetch_into(into));

View File

@ -9,16 +9,18 @@ use cargo_toml = util::toml;
pub struct Config<'a> { pub struct Config<'a> {
home_path: Path, home_path: Path,
update_remotes: bool,
shell: &'a mut MultiShell shell: &'a mut MultiShell
} }
impl<'a> Config<'a> { impl<'a> Config<'a> {
pub fn new<'a>(shell: &'a mut MultiShell) -> CargoResult<Config<'a>> { pub fn new<'a>(shell: &'a mut MultiShell, update_remotes: bool) -> CargoResult<Config<'a>> {
Ok(Config { Ok(Config {
home_path: try!(os::homedir().require(|| { home_path: try!(os::homedir().require(|| {
human("Cargo couldn't find your home directory. \ human("Cargo couldn't find your home directory. \
This probably means that $HOME was not set.") This probably means that $HOME was not set.")
})), })),
update_remotes: update_remotes,
shell: shell shell: shell
}) })
} }
@ -34,6 +36,10 @@ impl<'a> Config<'a> {
pub fn shell<'a>(&'a mut self) -> &'a mut MultiShell { pub fn shell<'a>(&'a mut self) -> &'a mut MultiShell {
&mut *self.shell &mut *self.shell
} }
pub fn update_remotes(&mut self) -> bool {
self.update_remotes
}
} }
#[deriving(Eq,PartialEq,Clone,Encodable,Decodable)] #[deriving(Eq,PartialEq,Clone,Encodable,Decodable)]

View File

@ -222,25 +222,33 @@ test!(recompilation {
UPDATING, git_project.root().display(), UPDATING, git_project.root().display(),
COMPILING, git_project.root().display(), COMPILING, git_project.root().display(),
COMPILING, p.root().display()))); COMPILING, p.root().display())));
// Don't recompile the second time // Don't recompile the second time
assert_that(p.process("cargo-compile"), assert_that(p.process("cargo-compile"),
execs().with_stdout(format!("{} git repository `file:{}`\n\ execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
{} bar v0.5.0 (file:{})\n\
{} foo v0.5.0 (file:{})\n", {} foo v0.5.0 (file:{})\n",
UPDATING, git_project.root().display(),
FRESH, git_project.root().display(), FRESH, git_project.root().display(),
FRESH, p.root().display()))); FRESH, p.root().display())));
// Modify a file manually, shouldn't trigger a recompile // Modify a file manually, shouldn't trigger a recompile
File::create(&git_project.root().join("src/bar.rs")).write_str(r#" File::create(&git_project.root().join("src/bar.rs")).write_str(r#"
pub fn bar() { println!("hello!"); } pub fn bar() { println!("hello!"); }
"#).assert(); "#).assert();
assert_that(p.process("cargo-compile"), assert_that(p.process("cargo-compile"),
execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
{} foo v0.5.0 (file:{})\n",
FRESH, git_project.root().display(),
FRESH, p.root().display())));
assert_that(p.process("cargo-compile").arg("-u"),
execs().with_stdout(format!("{} git repository `file:{}`\n\ execs().with_stdout(format!("{} git repository `file:{}`\n\
{} bar v0.5.0 (file:{})\n\ {} bar v0.5.0 (file:{})\n\
{} foo v0.5.0 (file:{})\n", {} foo v0.5.0 (file:{})\n",
UPDATING, git_project.root().display(), UPDATING, git_project.root().display(),
FRESH, git_project.root().display(), FRESH, git_project.root().display(),
FRESH, p.root().display()))); FRESH, p.root().display())));
// Commit the changes and make sure we trigger a recompile // Commit the changes and make sure we trigger a recompile
File::create(&git_project.root().join("src/bar.rs")).write_str(r#" File::create(&git_project.root().join("src/bar.rs")).write_str(r#"
pub fn bar() { println!("hello!"); } pub fn bar() { println!("hello!"); }
@ -248,7 +256,8 @@ test!(recompilation {
git_project.process("git").args(["add", "."]).exec_with_output().assert(); git_project.process("git").args(["add", "."]).exec_with_output().assert();
git_project.process("git").args(["commit", "-m", "test"]).exec_with_output() git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
.assert(); .assert();
assert_that(p.process("cargo-compile"),
assert_that(p.process("cargo-compile").arg("-u"),
execs().with_stdout(format!("{} git repository `file:{}`\n\ execs().with_stdout(format!("{} git repository `file:{}`\n\
{} bar v0.5.0 (file:{})\n\ {} bar v0.5.0 (file:{})\n\
{} foo v0.5.0 (file:{})\n", {} foo v0.5.0 (file:{})\n",