]> git.proxmox.com Git - cargo.git/commitdiff
Thread the shell through more of the system
authorYehuda Katz <wycats@gmail.com>
Sun, 22 Jun 2014 05:22:56 +0000 (22:22 -0700)
committerYehuda Katz <wycats@gmail.com>
Sun, 22 Jun 2014 05:22:56 +0000 (22:22 -0700)
18 files changed:
src/bin/cargo-compile.rs
src/bin/cargo-git-checkout.rs
src/bin/cargo-read-manifest.rs
src/bin/cargo.rs
src/cargo/core/mod.rs
src/cargo/core/package.rs
src/cargo/core/registry.rs
src/cargo/core/shell.rs
src/cargo/core/source.rs
src/cargo/lib.rs
src/cargo/ops/cargo_compile.rs
src/cargo/ops/cargo_rustc.rs
src/cargo/sources/git/source.rs
src/cargo/util/config.rs
tests/support/mod.rs
tests/test_cargo_compile.rs
tests/test_cargo_compile_git_deps.rs
tests/test_cargo_compile_path_deps.rs

index d410131e1840a0daf83616ea42fb28c3c6e9e06d..818d52ec1bb125efc60b84fa78e8c15c7f63e9e5 100644 (file)
@@ -14,6 +14,7 @@ extern crate serialize;
 use std::os;
 use cargo::{execute_main_without_stdin};
 use cargo::ops;
+use cargo::core::MultiShell;
 use cargo::util::{CliResult, CliError};
 use cargo::util::important_paths::find_project;
 
@@ -28,7 +29,7 @@ fn main() {
     execute_main_without_stdin(execute);
 }
 
-fn execute(options: Options) -> CliResult<Option<()>> {
+fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
     debug!("executing; cmd=cargo-compile; args={}", os::args());
 
     let root = match options.manifest_path {
@@ -42,7 +43,7 @@ fn execute(options: Options) -> CliResult<Option<()>> {
                     }))
     };
 
-    ops::compile(&root).map(|_| None).map_err(|err| {
+    ops::compile(&root, shell).map(|_| None).map_err(|err| {
         CliError::from_boxed(err, 101)
     })
 }
index a9a7698747846e76103b8834345df80618277483..64fefed8ca800f6fc66474ee87458f9714dc43b7 100644 (file)
@@ -9,6 +9,7 @@ extern crate url;
 extern crate hammer;
 
 use cargo::{execute_main_without_stdin};
+use cargo::core::MultiShell;
 use cargo::core::source::{Source,SourceId};
 use cargo::sources::git::{GitSource};
 use cargo::util::{Config, CliResult, CliError, Require, human};
@@ -26,7 +27,7 @@ fn main() {
     execute_main_without_stdin(execute);
 }
 
-fn execute(options: Options) -> CliResult<Option<()>> {
+fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
     let Options { url, reference, .. } = options;
 
     let url: Url = try!(from_str(url.as_slice())
@@ -36,8 +37,8 @@ fn execute(options: Options) -> CliResult<Option<()>> {
 
     let source_id = SourceId::for_git(&url, reference.as_slice());
 
-    let config = try!(Config::new().map_err(|e| CliError::from_boxed(e, 1)));
-    let mut source = GitSource::new(&source_id, &config);
+    let mut config = try!(Config::new(shell).map_err(|e| CliError::from_boxed(e, 1)));
+    let mut source = GitSource::new(&source_id, &mut config);
 
     try!(source.update().map_err(|e| {
         CliError::new(format!("Couldn't update {}: {}", source, e), 1)
index 9772a1275fe0f42cf2fe273b5750e22fab79b927..e77e9cb909bb984aefbb2ba9c8274a40d5105ba8 100644 (file)
@@ -8,7 +8,7 @@ extern crate serialize;
 extern crate hammer;
 
 use cargo::{execute_main_without_stdin};
-use cargo::core::{Package, Source, SourceId};
+use cargo::core::{MultiShell, Package, Source, SourceId};
 use cargo::util::{CliResult, CliError};
 use cargo::sources::{PathSource};
 
@@ -23,7 +23,7 @@ fn main() {
     execute_main_without_stdin(execute);
 }
 
-fn execute(options: Options) -> CliResult<Option<Package>> {
+fn execute(options: Options, _: &mut MultiShell) -> CliResult<Option<Package>> {
     let path = Path::new(options.manifest_path.as_slice());
     let source_id = SourceId::for_path(&path);
     let mut source = PathSource::new(&source_id);
index ffe3f454a10fa666d5c5ac3afa968532311cf1d5..562164e34c7846aab5f1632b5c00ecf85bab6920 100644 (file)
@@ -11,7 +11,8 @@ use hammer::{FlagConfig,FlagConfiguration};
 use std::os;
 use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};
 use serialize::Encodable;
-use cargo::{GlobalFlags, NoFlags, execute_main_without_stdin, handle_error};
+use cargo::{GlobalFlags, NoFlags, execute_main_without_stdin, handle_error, shell};
+use cargo::core::MultiShell;
 use cargo::util::important_paths::find_project;
 use cargo::util::{CliError, CliResult, Require, config, human};
 
@@ -34,7 +35,7 @@ fn execute() {
 
     let (cmd, args) = match process(os::args()) {
         Ok((cmd, args)) => (cmd, args),
-        Err(err) => return handle_error(err, false)
+        Err(err) => return handle_error(err, &mut shell(), false)
     };
 
     match cmd.as_slice() {
@@ -68,9 +69,9 @@ fn execute() {
             match command {
                 Ok(ExitStatus(0)) => (),
                 Ok(ExitStatus(i)) | Ok(ExitSignal(i)) => {
-                    handle_error(CliError::new("", i as uint), false)
+                    handle_error(CliError::new("", i as uint), &mut shell(), false)
                 }
-                Err(_) => handle_error(CliError::new("No such subcommand", 127), false)
+                Err(_) => handle_error(CliError::new("No such subcommand", 127), &mut shell(), false)
             }
         }
     }
@@ -104,7 +105,7 @@ impl FlagConfig for ConfigForKeyFlags {
     }
 }
 
-fn config_for_key(args: ConfigForKeyFlags) -> CliResult<Option<ConfigOut>> {
+fn config_for_key(args: ConfigForKeyFlags, _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
     let value = try!(config::get_config(os::getcwd(),
                                         args.key.as_slice()).map_err(|_| {
         CliError::new("Couldn't load configuration",  1)
@@ -132,7 +133,7 @@ impl FlagConfig for ConfigListFlags {
     }
 }
 
-fn config_list(args: ConfigListFlags) -> CliResult<Option<ConfigOut>> {
+fn config_list(args: ConfigListFlags, _: &mut MultiShell) -> CliResult<Option<ConfigOut>> {
     let configs = try!(config::all_configs(os::getcwd()).map_err(|_|
         CliError::new("Couldn't load configuration", 1)));
 
@@ -146,7 +147,7 @@ fn config_list(args: ConfigListFlags) -> CliResult<Option<ConfigOut>> {
     }
 }
 
-fn locate_project(_: NoFlags) -> CliResult<Option<ProjectLocation>> {
+fn locate_project(_: NoFlags, _: &mut MultiShell) -> CliResult<Option<ProjectLocation>> {
     let root = try!(find_project(os::getcwd(), "Cargo.toml").map_err(|e| {
         CliError::from_boxed(e, 1)
     }));
index fd6ff3211ac8aac720f222c442a77203e8ebab6a..b14bbd6e259fb96707f45e70756feb8d93ecffe0 100644 (file)
@@ -32,6 +32,7 @@ pub use self::summary::{
 
 pub use self::shell::{
     Shell,
+    MultiShell,
     ShellConfig
 };
 
index 4fe1a76523f2ad97d5f9e7f38fef926383c2cec0..1bf19fab62436c281659181880e0b5ad88e97211 100644 (file)
@@ -118,7 +118,7 @@ impl Package {
         ret
     }
 
-    pub fn get_fingerprint(&self, config: &Config) -> CargoResult<String> {
+    pub fn get_fingerprint(&self, config: &mut Config) -> CargoResult<String> {
         let mut sources = self.get_source_ids();
         // Sort the sources just to make sure we have a consistent fingerprint.
         sources.sort_by(|a, b| {
index b43d91499a3337baef26ebcd28b70fa8540274d1..169137df52b659dc71805c875963a2df2f2e9ecd 100644 (file)
@@ -1,5 +1,5 @@
 use std::vec::Vec;
-use core::{Source, SourceId, Summary, Dependency, PackageId, Package};
+use core::{MultiShell, Source, SourceId, Summary, Dependency, PackageId, Package};
 use util::{CargoResult, ChainError, Config, human};
 
 pub trait Registry {
@@ -15,17 +15,20 @@ impl Registry for Vec<Summary> {
     }
 }
 
-pub struct PackageRegistry {
+pub struct PackageRegistry<'a> {
     sources: Vec<Box<Source>>,
     overrides: Vec<Summary>,
     summaries: Vec<Summary>,
-    searched: Vec<SourceId>
+    searched: Vec<SourceId>,
+    shell: &'a mut MultiShell
 }
 
-impl PackageRegistry {
-    pub fn new(source_ids: Vec<SourceId>,
-               override_ids: Vec<SourceId>) -> CargoResult<PackageRegistry> {
-        let mut reg = PackageRegistry::empty();
+impl<'a> PackageRegistry<'a> {
+    pub fn new<'a>(source_ids: Vec<SourceId>,
+               override_ids: Vec<SourceId>,
+               shell: &'a mut MultiShell) -> CargoResult<PackageRegistry<'a>> {
+
+        let mut reg = PackageRegistry::empty(shell);
 
         for id in source_ids.iter() {
             try!(reg.load(id, false));
@@ -38,12 +41,13 @@ impl PackageRegistry {
         Ok(reg)
     }
 
-    fn empty() -> PackageRegistry {
+    fn empty<'a>(shell: &'a mut MultiShell) -> PackageRegistry<'a> {
         PackageRegistry {
             sources: vec!(),
             overrides: vec!(),
             summaries: vec!(),
-            searched: vec!()
+            searched: vec!(),
+            shell: shell
         }
     }
 
@@ -75,11 +79,10 @@ impl PackageRegistry {
         Ok(())
     }
 
-    fn load(&mut self, namespace: &SourceId,
-            override: bool) -> CargoResult<()> {
+    fn load(&mut self, namespace: &SourceId, override: bool) -> CargoResult<()> {
 
         (|| {
-            let mut source = namespace.load(&try!(Config::new()));
+            let mut source = namespace.load(&mut try!(Config::new(self.shell)));
             let dst = if override {&mut self.overrides} else {&mut self.summaries};
 
             // Ensure the source has fetched all necessary remote data.
@@ -103,7 +106,7 @@ impl PackageRegistry {
     }
 }
 
-impl Registry for PackageRegistry {
+impl<'a> Registry for PackageRegistry<'a> {
     fn query(&mut self, dep: &Dependency) -> CargoResult<Vec<Summary>> {
         let overrides = try!(self.overrides.query(dep)); // this can never fail in practice
 
index 32d0f8ed0fce2ab5c8991184a88803800ddd3297..8eaeb033214b8f421db6d74957c720f8a75485ab 100644 (file)
@@ -1,8 +1,9 @@
 use term;
 use term::{Terminal,color};
-use term::color::{Color, BLACK};
-use term::attr::Attr;
+use term::color::{Color, BLACK, RED, GREEN};
+use term::attr::{Attr, Bold};
 use std::io::{IoResult, stderr};
+use std::fmt::Show;
 
 pub struct ShellConfig {
     pub color: bool,
@@ -20,6 +21,39 @@ pub struct Shell {
     config: ShellConfig
 }
 
+pub struct MultiShell {
+    out: Shell,
+    err: Shell
+}
+
+impl MultiShell {
+    pub fn new(out: Shell, err: Shell) -> MultiShell {
+        MultiShell { out: out, err: err }
+    }
+
+    pub fn out<'a>(&'a mut self) -> &'a mut Shell {
+        &mut self.out
+    }
+
+    pub fn err<'a>(&'a mut self) -> &'a mut Shell {
+        &mut self.err
+    }
+
+    pub fn say<T: ToStr>(&mut self, message: T, color: Color) -> IoResult<()> {
+        self.out().say(message, color)
+    }
+
+    pub fn status<T: Show, U: Show>(&mut self, status: T, message: U) -> IoResult<()> {
+        self.out().say_status(status, message, GREEN)
+    }
+
+    pub fn error<T: ToStr>(&mut self, message: T) -> IoResult<()> {
+        self.err().say(message, RED)
+    }
+}
+
+
+
 impl Shell {
     pub fn create(out: Box<Writer>, config: ShellConfig) -> Shell {
         if config.tty && config.color {
@@ -52,6 +86,17 @@ impl Shell {
         try!(self.flush());
         Ok(())
     }
+
+    pub fn say_status<T: Show, U: Show>(&mut self, status: T, message: U, color: Color) -> IoResult<()> {
+        try!(self.reset());
+        if color != BLACK { try!(self.fg(color)); }
+        if self.supports_attr(Bold) { try!(self.attr(Bold)); }
+        try!(self.write_str(format!("{:>12}", status).as_slice()));
+        try!(self.reset());
+        try!(self.write_line(format!(" {}", message).as_slice()));
+        try!(self.flush());
+        Ok(())
+    }
 }
 
 impl Terminal<Box<Writer>> for Shell {
index ef209186c07876c0674bb2749ff0b9ddd9258fba..31b380473655f2eebf0c4acb609005c1b91d3477 100644 (file)
@@ -115,7 +115,7 @@ impl SourceId {
         }
     }
 
-    pub fn load(&self, config: &Config) -> Box<Source> {
+    pub fn load(&self, config: &mut Config) -> Box<Source> {
         match self.kind {
             GitKind(..) => {
                 box GitSource::new(self, config) as Box<Source>
index 6945438083a5cce66e2fed6284e2f76d60212fe3..8879bd70f58a3d713d37b8614faa44b4b1fa8faf 100644 (file)
@@ -21,12 +21,12 @@ extern crate hamcrest;
 
 use serialize::{Decoder, Encoder, Decodable, Encodable, json};
 use std::io;
-use std::io::stderr;
-use std::io::stdio::stderr_raw;
+use std::io::{stdout, stderr};
+use std::io::stdio::{stdout_raw, stderr_raw};
 use hammer::{FlagDecoder, FlagConfig, UsageDecoder, HammerError};
 
-use core::{Shell, ShellConfig};
-use term::color::{RED, BLACK};
+use core::{Shell, MultiShell, ShellConfig};
+use term::color::{BLACK};
 
 pub use util::{CargoError, CliError, CliResult, human};
 
@@ -99,47 +99,55 @@ pub fn execute_main<'a,
                     T: RepresentsFlags,
                     U: RepresentsJSON,
                     V: Encodable<json::Encoder<'a>, io::IoError>>(
-                        exec: fn(T, U) -> CliResult<Option<V>>)
+                        exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>)
 {
     fn call<'a,
             T: RepresentsFlags,
             U: RepresentsJSON,
             V: Encodable<json::Encoder<'a>, io::IoError>>(
-                exec: fn(T, U) -> CliResult<Option<V>>,
+                exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
+                shell: &mut MultiShell,
                 args: &[String])
         -> CliResult<Option<V>>
     {
         let flags = try!(flags_from_args::<T>(args));
         let json = try!(json_from_stdin::<U>());
 
-        exec(flags, json)
+        exec(flags, json, shell)
     }
 
-    match global_flags() {
-        Err(e) => handle_error(e, true),
-        Ok(val) => process_executed(call(exec, val.rest.as_slice()), val)
-    }
+    process::<T, V>(|rest, shell| call(exec, shell, rest));
 }
 
 pub fn execute_main_without_stdin<'a,
                                   T: RepresentsFlags,
                                   V: Encodable<json::Encoder<'a>, io::IoError>>(
-                                      exec: fn(T) -> CliResult<Option<V>>)
+                                      exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>)
 {
     fn call<'a,
             T: RepresentsFlags,
             V: Encodable<json::Encoder<'a>, io::IoError>>(
-                exec: fn(T) -> CliResult<Option<V>>,
+                exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
+                shell: &mut MultiShell,
                 args: &[String])
         -> CliResult<Option<V>>
     {
         let flags = try!(flags_from_args::<T>(args));
-
-        exec(flags)
+        exec(flags, shell)
     }
 
+    process::<T, V>(|rest, shell| call(exec, shell, rest));
+}
+
+fn process<'a,
+           T: RepresentsFlags,
+           V: Encodable<json::Encoder<'a>, io::IoError>>(
+               callback: |&[String], &mut MultiShell| -> CliResult<Option<V>>) {
+
+    let mut shell = shell();
+
     match global_flags() {
-        Err(e) => handle_error(e, true),
+        Err(e) => handle_error(e, &mut shell, true),
         Ok(val) => {
             if val.help {
                 let (desc, options) = hammer::usage::<T>(true);
@@ -153,7 +161,7 @@ pub fn execute_main_without_stdin<'a,
                 let (_, options) = hammer::usage::<GlobalFlags>(false);
                 print!("{}", options);
             } else {
-                process_executed(call(exec, val.rest.as_slice()), val)
+                process_executed(callback(val.rest.as_slice(), &mut shell), val, &mut shell)
             }
         }
     }
@@ -162,10 +170,10 @@ pub fn execute_main_without_stdin<'a,
 pub fn process_executed<'a,
                         T: Encodable<json::Encoder<'a>, io::IoError>>(
                             result: CliResult<Option<T>>,
-                            flags: GlobalFlags)
+                            flags: GlobalFlags, shell: &mut MultiShell)
 {
     match result {
-        Err(e) => handle_error(e, flags.verbose),
+        Err(e) => handle_error(e, shell, flags.verbose),
         Ok(encodable) => {
             encodable.map(|encodable| {
                 let encoded = json::Encoder::str_encode(&encodable);
@@ -175,38 +183,47 @@ pub fn process_executed<'a,
     }
 }
 
-pub fn handle_error(err: CliError, verbose: bool) {
-    log!(4, "handle_error; err={}", err);
-
-
-    let CliError { error, exit_code, unknown, .. } = err;
-
+pub fn shell() -> MultiShell {
     let tty = stderr_raw().isatty();
     let stderr = box stderr() as Box<Writer>;
 
     let config = ShellConfig { color: true, verbose: false, tty: tty };
-    let mut shell = Shell::create(stderr, config);
+    let err = Shell::create(stderr, config);
+
+    let tty = stdout_raw().isatty();
+    let stdout = box stdout() as Box<Writer>;
+
+    let config = ShellConfig { color: true, verbose: false, tty: tty };
+    let out = Shell::create(stdout, config);
+
+    MultiShell::new(out, err)
+}
+
+pub fn handle_error(err: CliError, shell: &mut MultiShell, verbose: bool) {
+    log!(4, "handle_error; err={}", err);
+
+    let CliError { error, exit_code, unknown, .. } = err;
 
     if unknown {
-        let _ = shell.say("An unknown error occurred", RED);
+        let _ = shell.error("An unknown error occurred");
     } else {
-        let _ = shell.say(error.to_str(), RED);
+        let _ = shell.error(error.to_str());
     }
 
     if unknown && !verbose {
-        let _ = shell.say("\nTo learn more, run the command again with --verbose.", BLACK);
+        let _ = shell.err().say("\nTo learn more, run the command again with --verbose.", BLACK);
     }
 
     if verbose {
-        handle_cause(error, &mut shell);
+        handle_cause(error, shell);
     }
 
     std::os::set_exit_status(exit_code as int);
 }
 
-fn handle_cause(err: &CargoError, shell: &mut Shell) {
-    let _ = shell.say("\nCaused by:", BLACK);
-    let _ = shell.say(format!("  {}", err.description()), BLACK);
+fn handle_cause(err: &CargoError, shell: &mut MultiShell) {
+    let _ = shell.err().say("\nCaused by:", BLACK);
+    let _ = shell.err().say(format!("  {}", err.description()), BLACK);
 
     err.cause().map(|e| handle_cause(e, shell));
 }
index 35b1392f00a0d666a389b1ee5dbf03b4166a6497..416961bfe07013263b01c3ece6aded2faec6ef9a 100644 (file)
 
 use std::os;
 use util::config::{ConfigValue};
-use core::{Source,SourceId,PackageSet,resolver};
+use core::{MultiShell, Source, SourceId, PackageSet, resolver};
 use core::registry::PackageRegistry;
 use ops;
 use sources::{PathSource};
 use util::{CargoResult, Wrap, config, internal, human};
 
-pub fn compile(manifest_path: &Path) -> CargoResult<()> {
+pub fn compile(manifest_path: &Path, shell: &mut MultiShell) -> CargoResult<()> {
     log!(4, "compile; manifest-path={}", manifest_path.display());
 
     let id = SourceId::for_path(&manifest_path.dir_path());
@@ -45,19 +45,21 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> {
     let override_ids = try!(source_ids_from_config());
     let source_ids = package.get_source_ids();
 
-    let mut registry = try!(PackageRegistry::new(source_ids, override_ids));
-    let resolved = try!(resolver::resolve(package.get_dependencies(),
-                                          &mut registry).wrap({
-        human("unable to resolve dependencies")
-    }));
+    let packages = {
+        let mut registry = try!(PackageRegistry::new(source_ids, override_ids, shell));
+        let resolved = try!(resolver::resolve(package.get_dependencies(),
+                                              &mut registry).wrap({
+            human("unable to resolve dependencies")
+        }));
 
-    let packages = try!(registry.get(resolved.as_slice()).wrap({
-        human("unable to get packages from source")
-    }));
+        try!(registry.get(resolved.as_slice()).wrap({
+            human("unable to get packages from source")
+        }))
+    };
 
     debug!("packages={}", packages);
 
-    try!(ops::compile_packages(&package, &PackageSet::new(packages.as_slice())));
+    try!(ops::compile_packages(&package, &PackageSet::new(packages.as_slice()), shell));
 
     Ok(())
 }
index 334467c3afa8d15eda19295cff818409ae488fe6..804c21e8caa1dc1a1d71056004aef34f1a3fcc79 100644 (file)
@@ -3,7 +3,7 @@ use std::io;
 use std::io::{File, IoError};
 use std::str;
 
-use core::{Package, PackageSet, Target};
+use core::{MultiShell, Package, PackageSet, Target};
 use util;
 use util::{CargoResult, ChainError, ProcessBuilder, internal, human, CargoError};
 use util::{Config};
@@ -16,13 +16,13 @@ struct Context<'a> {
     primary: bool,
     rustc_version: &'a str,
     compiled_anything: bool,
-    config: &'a Config,
+    config: &'a mut Config<'a>
 }
 
-pub fn compile_packages(pkg: &Package, deps: &PackageSet) -> CargoResult<()> {
+pub fn compile_packages(pkg: &Package, deps: &PackageSet, shell: &mut MultiShell) -> CargoResult<()> {
     debug!("compile_packages; pkg={}; deps={}", pkg, deps);
 
-    let config = try!(Config::new());
+    let mut config = try!(Config::new(shell));
     let target_dir = pkg.get_absolute_target_dir();
     let deps_target_dir = target_dir.join("deps");
 
@@ -46,7 +46,7 @@ pub fn compile_packages(pkg: &Package, deps: &PackageSet) -> CargoResult<()> {
         primary: false,
         rustc_version: rustc_version.as_slice(),
         compiled_anything: false,
-        config: &config,
+        config: &mut config
     };
 
     // Traverse the dependencies in topological order
@@ -78,14 +78,14 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> {
                                                pkg.get_name()));
     let (is_fresh, fingerprint) = try!(is_fresh(pkg, &fingerprint_loc, cx));
     if !cx.compiled_anything && is_fresh {
-        println!("Skipping fresh {}", pkg);
+        try!(cx.config.shell().status("Fresh", pkg));
         return Ok(())
     }
 
     // Alright, so this package is not fresh and we need to compile it. Start
     // off by printing a nice helpful message and then run the custom build
     // command if one is present.
-    println!("Compiling {}", pkg);
+    try!(cx.config.shell().status("Compiling", pkg));
 
     match pkg.get_manifest().get_build() {
         Some(cmd) => try!(compile_custom(pkg, cmd, cx)),
@@ -110,7 +110,7 @@ fn compile_pkg(pkg: &Package, cx: &mut Context) -> CargoResult<()> {
 }
 
 fn is_fresh(dep: &Package, loc: &Path,
-            cx: &Context) -> CargoResult<(bool, String)> {
+            cx: &mut Context) -> CargoResult<(bool, String)> {
     let new_fingerprint = format!("{}{}", cx.rustc_version,
                                   try!(dep.get_fingerprint(cx.config)));
     let mut file = match File::open(loc) {
index e7949eceb837aebe08abf13ea7ca11f8f243ae1e..724be4f416338fe50779d3705a8d0a0068ee13fb 100644 (file)
@@ -15,16 +15,17 @@ use sources::git::utils::{GitReference,GitRemote,Master,Other};
 
 /* TODO: Refactor GitSource to delegate to a PathSource
  */
-pub struct GitSource {
+pub struct GitSource<'a, 'b> {
     id: SourceId,
     remote: GitRemote,
     reference: GitReference,
     db_path: Path,
-    checkout_path: Path
+    checkout_path: Path,
+    config: &'a mut Config<'b>
 }
 
-impl GitSource {
-    pub fn new(source_id: &SourceId, config: &Config) -> GitSource {
+impl<'a, 'b> GitSource<'a, 'b> {
+    pub fn new<'a, 'b>(source_id: &SourceId, config: &'a mut Config<'b>) -> GitSource<'a, 'b> {
         assert!(source_id.is_git(), "id is not git, id={}", source_id);
 
         let reference = match source_id.kind {
@@ -46,7 +47,8 @@ impl GitSource {
             remote: remote,
             reference: GitReference::for_str(reference.as_slice()),
             db_path: db_path,
-            checkout_path: checkout_path
+            checkout_path: checkout_path,
+            config: config
         }
     }
 
@@ -79,7 +81,7 @@ fn to_hex(num: u64) -> String {
     writer.get_ref().to_hex()
 }
 
-impl Show for GitSource {
+impl<'a, 'b> Show for GitSource<'a, 'b> {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         try!(write!(f, "git repo at {}", self.remote.get_url()));
 
@@ -90,9 +92,11 @@ impl Show for GitSource {
     }
 }
 
-impl Source for GitSource {
+impl<'a, 'b> Source for GitSource<'a, 'b> {
     fn update(&mut self) -> CargoResult<()> {
-        println!("Updating git repository `{}`", self.remote.get_url());
+        try!(self.config.shell().status("Updating",
+            format!("git repository `{}`", self.remote.get_url())));
+
         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));
index 4604ec9c55aeffb153a0f8dea70f24fe5c7210fc..24fb603e65521bbd49c72b4060344200d467a7f1 100644 (file)
@@ -2,19 +2,22 @@ use std::{io,fmt,os};
 use std::collections::HashMap;
 use serialize::{Encodable,Encoder};
 use toml;
+use core::MultiShell;
 use util::{CargoResult, CargoError, ChainError, Require, internal, human};
 
-pub struct Config {
-    home_path: Path
+pub struct Config<'a> {
+    home_path: Path,
+    shell: &'a mut MultiShell
 }
 
-impl Config {
-    pub fn new() -> CargoResult<Config> {
+impl<'a> Config<'a> {
+    pub fn new<'a>(shell: &'a mut MultiShell) -> CargoResult<Config<'a>> {
         Ok(Config {
             home_path: try!(os::homedir().require(|| {
                 human("Cargo couldn't find your home directory. \
                       This probably means that $HOME was not set.")
-            }))
+            })),
+            shell: shell
         })
     }
 
@@ -25,6 +28,10 @@ impl Config {
     pub fn git_checkout_path(&self) -> Path {
         self.home_path.join(".cargo").join("git").join("checkouts")
     }
+
+    pub fn shell<'a>(&'a mut self) -> &'a mut MultiShell {
+        &mut *self.shell
+    }
 }
 
 #[deriving(Eq,PartialEq,Clone,Encodable,Decodable)]
index b1bc4c0ba34cfeae32f903ba26cc1cb9be70a56f..8cac9db37cf19ebbf56458b5d34593faa8d07716 100644 (file)
@@ -9,7 +9,6 @@ use std::str;
 use std::vec::Vec;
 use std::fmt::Show;
 use ham = hamcrest;
-use cargo::core::shell;
 use cargo::util::{process,ProcessBuilder};
 use cargo::util::ProcessError;
 
@@ -305,8 +304,6 @@ impl<'a> ham::Matcher<&'a [u8]> for ShellWrites {
     fn matches(&self, actual: &[u8])
         -> ham::MatchResult
     {
-        use term::Terminal;
-
         println!("{}", actual);
         let actual = std::str::from_utf8_lossy(actual);
         let actual = actual.to_str();
index f3a03a3c8abc3a1bdec0e1bcb4388fe21bf4a708..89a0c400c623b481ab66604d49552b1b0d61f274 100644 (file)
@@ -9,6 +9,8 @@ use cargo::util::{process,realpath};
 fn setup() {
 }
 
+static COMPILING: &'static str = "   Compiling";
+
 fn basic_bin_manifest(name: &str) -> String {
     format!(r#"
         [project]
@@ -143,9 +145,10 @@ test!(cargo_compile_with_warnings_in_a_dep_package {
 
     assert_that(p.cargo_process("cargo-compile"),
         execs()
-        .with_stdout(format!("Compiling bar v0.5.0 (file:{})\n\
-                              Compiling foo v0.5.0 (file:{})\n",
-                             bar.display(), main.display()))
+        .with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                              {} foo v0.5.0 (file:{})\n",
+                             COMPILING, bar.display(),
+                             COMPILING, main.display()))
         .with_stderr(""));
 
     assert_that(&p.root().join("target/foo"), existing_file());
@@ -343,7 +346,7 @@ test!(custom_build {
         "#);
     assert_that(p.cargo_process("cargo-compile"),
                 execs().with_status(0)
-                       .with_stdout(format!("Compiling foo v0.5.0 (file:{})\n",
+                       .with_stdout(format!("   Compiling foo v0.5.0 (file:{})\n",
                                             p.root().display()))
                        .with_stderr(""));
 })
index 68c10537352d8950d5075227a4f120dc26afb112..48907e5f88a81718b7ae98ed5263aef1ea34092a 100644 (file)
@@ -5,6 +5,10 @@ use hamcrest::{assert_that,existing_file};
 use cargo;
 use cargo::util::{ProcessError, process};
 
+static COMPILING: &'static str = "   Compiling";
+static FRESH:     &'static str = "       Fresh";
+static UPDATING:  &'static str = "    Updating";
+
 fn setup() {
 }
 
@@ -83,11 +87,12 @@ test!(cargo_compile_simple_git_dep {
 
     assert_that(project.cargo_process("cargo-compile"),
         execs()
-        .with_stdout(format!("Updating git repository `file:{}`\n\
-                              Compiling dep1 v0.5.0 (file:{})\n\
-                              Compiling foo v0.5.0 (file:{})\n",
-                             git_root.display(), git_root.display(),
-                             root.display()))
+        .with_stdout(format!("{} git repository `file:{}`\n\
+                              {} dep1 v0.5.0 (file:{})\n\
+                              {} foo v0.5.0 (file:{})\n",
+                             UPDATING, git_root.display(),
+                             COMPILING, git_root.display(),
+                             COMPILING, root.display()))
         .with_stderr(""));
 
     assert_that(&project.root().join("target/foo"), existing_file());
@@ -211,31 +216,31 @@ test!(recompilation {
 
     // First time around we should compile both foo and bar
     assert_that(p.cargo_process("cargo-compile"),
-                execs().with_stdout(format!("Updating git repository `file:{}`\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            git_project.root().display(),
-                                            git_project.root().display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} git repository `file:{}`\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            UPDATING, git_project.root().display(),
+                                            COMPILING, git_project.root().display(),
+                                            COMPILING, p.root().display())));
     // Don't recompile the second time
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Updating git repository `file:{}`\n\
-                                             Skipping fresh bar v0.5.0 (file:{})\n\
-                                             Skipping fresh foo v0.5.0 (file:{})\n",
-                                            git_project.root().display(),
-                                            git_project.root().display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} git repository `file:{}`\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            UPDATING, git_project.root().display(),
+                                            FRESH, git_project.root().display(),
+                                            FRESH, p.root().display())));
     // Modify a file manually, shouldn't trigger a recompile
     File::create(&git_project.root().join("src/bar.rs")).write_str(r#"
         pub fn bar() { println!("hello!"); }
     "#).assert();
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Updating git repository `file:{}`\n\
-                                             Skipping fresh bar v0.5.0 (file:{})\n\
-                                             Skipping fresh foo v0.5.0 (file:{})\n",
-                                            git_project.root().display(),
-                                            git_project.root().display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} git repository `file:{}`\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            UPDATING, git_project.root().display(),
+                                            FRESH, git_project.root().display(),
+                                            FRESH, p.root().display())));
     // Commit the changes and make sure we trigger a recompile
     File::create(&git_project.root().join("src/bar.rs")).write_str(r#"
         pub fn bar() { println!("hello!"); }
@@ -244,10 +249,10 @@ test!(recompilation {
     git_project.process("git").args(["commit", "-m", "test"]).exec_with_output()
                .assert();
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Updating git repository `file:{}`\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            git_project.root().display(),
-                                            git_project.root().display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} git repository `file:{}`\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            UPDATING, git_project.root().display(),
+                                            COMPILING, git_project.root().display(),
+                                            COMPILING, p.root().display())));
 })
index eabf8276e0d1b0e7a63816d6a06fc014e2f8eb6a..c8072a261c57d8d1495b7952ce9ec9bfacc83313 100644 (file)
@@ -9,6 +9,9 @@ use cargo::util::{process};
 fn setup() {
 }
 
+static COMPILING: &'static str = "   Compiling";
+static FRESH:     &'static str = "       Fresh";
+
 test!(cargo_compile_with_nested_deps_shorthand {
     let p = project("foo")
         .file("Cargo.toml", r#"
@@ -115,23 +118,23 @@ test!(no_rebuild_dependency {
         "#);
     // First time around we should compile both foo and bar
     assert_that(p.cargo_process("cargo-compile"),
-                execs().with_stdout(format!("Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
     // This time we shouldn't compile bar
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Skipping fresh bar v0.5.0 (file:{})\n\
-                                             Skipping fresh foo v0.5.0 (file:{})\n",
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            FRESH, bar.display(),
+                                            FRESH, p.root().display())));
 
     p.build(); // rebuild the files (rewriting them in the process)
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
 })
 
 test!(deep_dependencies_trigger_rebuild {
@@ -183,19 +186,19 @@ test!(deep_dependencies_trigger_rebuild {
             pub fn baz() {}
         "#);
     assert_that(p.cargo_process("cargo-compile"),
-                execs().with_stdout(format!("Compiling baz v0.5.0 (file:{})\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            COMPILING, baz.display(),
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Skipping fresh baz v0.5.0 (file:{})\n\
-                                             Skipping fresh bar v0.5.0 (file:{})\n\
-                                             Skipping fresh foo v0.5.0 (file:{})\n",
-                                            baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            FRESH, baz.display(),
+                                            FRESH, bar.display(),
+                                            FRESH, p.root().display())));
 
     // Make sure an update to baz triggers a rebuild of bar
     //
@@ -206,12 +209,12 @@ test!(deep_dependencies_trigger_rebuild {
         pub fn baz() { println!("hello!"); }
     "#).assert();
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Compiling baz v0.5.0 (file:{})\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            COMPILING, baz.display(),
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
 
     // Make sure an update to bar doesn't trigger baz
     File::create(&p.root().join("bar/src/bar.rs")).write_str(r#"
@@ -219,12 +222,13 @@ test!(deep_dependencies_trigger_rebuild {
         pub fn bar() { println!("hello!"); baz::baz(); }
     "#).assert();
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Skipping fresh baz v0.5.0 (file:{})\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            FRESH,
                                             baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
 })
 
 test!(no_rebuild_two_deps {
@@ -276,17 +280,17 @@ test!(no_rebuild_two_deps {
             pub fn baz() {}
         "#);
     assert_that(p.cargo_process("cargo-compile"),
-                execs().with_stdout(format!("Compiling baz v0.5.0 (file:{})\n\
-                                             Compiling bar v0.5.0 (file:{})\n\
-                                             Compiling foo v0.5.0 (file:{})\n",
-                                            baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            COMPILING, baz.display(),
+                                            COMPILING, bar.display(),
+                                            COMPILING, p.root().display())));
     assert_that(p.process("cargo-compile"),
-                execs().with_stdout(format!("Skipping fresh baz v0.5.0 (file:{})\n\
-                                             Skipping fresh bar v0.5.0 (file:{})\n\
-                                             Skipping fresh foo v0.5.0 (file:{})\n",
-                                            baz.display(),
-                                            bar.display(),
-                                            p.root().display())));
+                execs().with_stdout(format!("{} baz v0.5.0 (file:{})\n\
+                                             {} bar v0.5.0 (file:{})\n\
+                                             {} foo v0.5.0 (file:{})\n",
+                                            FRESH, baz.display(),
+                                            FRESH, bar.display(),
+                                            FRESH, p.root().display())));
 })