Add --nocapture and plumb it through to the runner

The --nocapture option of the Rust test runner is just about
the only one folks are likely to use so it is easier to expose
it in fargo and plub it through.

Change-Id: I80ef5513bd6a31fc6867460acb24f5956643e65c
Testing: fargo test with both options, also fargo autotest, also cargo test.
diff --git a/README.md b/README.md
index c988b6a..7bd5028 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,6 @@
         fargo [FLAGS] [OPTIONS] [SUBCOMMAND]
 
     FLAGS:
-            --debug-os             Use debug user.bootfs and ssh keys
             --disable-cross-env    Disable the setting of CC, AR and such environmental variables.
         -h, --help                 Prints help information
         -V, --version              Prints version information
@@ -15,18 +14,16 @@
 
     OPTIONS:
         -N, --device-name <device-name>
-                Name of device to target, needed if there are multiple devices visible on the
-                network
-        -T, --target-cpu <target-cpu>
-                Architecture of target device [default: x64]  [values: x64, arm64]
+                Name of device to target, needed if there are multiple devices visible on the network
 
+            --manifest-path <manifest-path>    Path to Cargo.toml
 
     SUBCOMMANDS:
         autotest             Auto build and test in Fuchsia device or emulator
         build                Build binary targeting Fuchsia device or emulator
         build-tests          Build tests for Fuchsia device or emulator
-        cargo                Run a cargo command for Fuchsia. Use -- to indicate that all
-                             following arguments should be passed to cargo.
+        cargo                Run a cargo command for Fuchsia. Use -- to indicate that all following
+                             arguments should be passed to cargo.
         check                Check binary targeting Fuchsia device or emulator
         configure            Run a configure script for the cross compilation environment
         doc                  Build a package's documentation
@@ -41,31 +38,26 @@
         start                Start a Fuchsia emulator
         stop                 Stop all Fuchsia emulators
         test                 Run unit tests on Fuchsia device or emulator
-        write-config         Write a .cargo/config file to allow cargo to operate correctly
-                             for Fuchsia
+        write-config         Write a .cargo/config file to allow cargo to operate correctly for Fuchsia
 
 The `fargo-test` directory contains something one can use to test-drive.
 
 ## Getting started
 
 Since at the moment fargo requires the FUCHSIA\_DIR environmental variable be
-set to the path to a Fuchsia source tree containing a **release** build,
+set to the path to a Fuchsia source tree containing a Fuchsia build,
 the first step is to build Fuchsia.
 
 The [Fuchsia Getting
 Started](https://fuchsia.googlesource.com/docs/+/HEAD/getting_started.md)
-instruction are what you need. Since a release build is what fargo expects to
-find you'll want to pass --args "is_debug=false" to fx/set. You'll also need to
-specify `out/release-x64` or `out/debug-x64` as the out directory when using
-`fx set`. The Rust components that fargo needs to cross compile are part of garnet,
-so you must be using the garnet layer or higher.
+instruction are what you need.
 
 The author most often uses the following steps to update and build Fuchsia in
 preparation for using fargo
 
-    ./scripts/fx set-layer garnet
+    ./scripts/fx set-petal garnet
     .jiri_root/bin/jiri update
-    ./scripts/fx set x64 out/release-x64 --args "is_debug=false"
+    ./scripts/fx set x64 out/release-x64 --release
     ./scripts/fx build-zircon
     ./scripts/fx build
 
@@ -74,7 +66,10 @@
 
     git clone https://fuchsia.googlesource.com/fargo
     cd fargo
-    cargo +nightly install --force
+    cargo install --force --path .
+
+Fargo uses the $FUCHSIA\_DIR/.config file written by ./scripts/fx set to know what
+build directory to use.
 
 Fargo uses ssh to communicate between your host computer and either Qemu or a
 real device to copy build results and execute them. For Qemu there is a bit of
diff --git a/fargo-test/test/bork_bork.rs b/fargo-test/test/bork_bork.rs
index 985c594..e1bef33 100644
--- a/fargo-test/test/bork_bork.rs
+++ b/fargo-test/test/bork_bork.rs
@@ -4,6 +4,7 @@
 
 #[test]
 fn test_dogs() {
+    println!("#### bork bork bork");
     let dogs = "good";
     assert_eq!(dogs, "good");
 }
diff --git a/src/lib.rs b/src/lib.rs
index 6f1200f..be8e868 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,8 +53,9 @@
 }
 
 fn run_program_on_target(
-    filename: &str, verbose: bool, config: &FuchsiaConfig, target_options: &TargetOptions<'_, '_>,
-    run_mode: RunMode, params: &[&str], test_args: Option<&str>,
+    filename: &str, verbose: bool, nocapture: bool, config: &FuchsiaConfig,
+    target_options: &TargetOptions<'_, '_>, run_mode: RunMode, params: &[&str],
+    test_args: Option<&str>,
 ) -> Result<(), Error> {
     let source_path = PathBuf::from(&filename);
     let stripped_source_path = strip_binary(&source_path)?;
@@ -67,6 +68,12 @@
     })
     .to_string();
     command_string.push_str(&destination_path);
+
+    if nocapture {
+        command_string.push_str(" --");
+        command_string.push_str(NOCAPTURE);
+    }
+
     for param in params {
         command_string.push(' ');
         command_string.push_str(param);
@@ -171,7 +178,14 @@
             Some(&formatted_target_params),
         )?;
     } else {
-        run_cargo(run_cargo_options, "test", &args, target_options, None, None)?;
+        run_cargo(
+            &run_cargo_options,
+            "test",
+            &args,
+            target_options,
+            None,
+            None,
+        )?;
     }
 
     Ok(())
@@ -285,6 +299,7 @@
     pub release: bool,
     pub run_mode: RunMode,
     pub disable_cross: bool,
+    pub nocapture: bool,
     pub manifest_path: Option<PathBuf>,
 }
 
@@ -293,6 +308,7 @@
         RunCargoOptions {
             verbose,
             release,
+            nocapture: false,
             run_mode: RunMode::Normal,
             disable_cross: false,
             manifest_path: None,
@@ -303,6 +319,7 @@
         RunCargoOptions {
             verbose: self.verbose,
             release: self.release,
+            nocapture: self.nocapture,
             run_mode: self.run_mode,
             disable_cross,
             manifest_path: self.manifest_path.clone(),
@@ -313,6 +330,18 @@
         RunCargoOptions {
             verbose: self.verbose,
             release: release,
+            nocapture: self.nocapture,
+            run_mode: self.run_mode,
+            disable_cross: self.disable_cross,
+            manifest_path: self.manifest_path.clone(),
+        }
+    }
+
+    pub fn nocapture(&self, nocapture: bool) -> RunCargoOptions {
+        RunCargoOptions {
+            verbose: self.verbose,
+            release: self.release,
+            nocapture: nocapture,
             run_mode: self.run_mode,
             disable_cross: self.disable_cross,
             manifest_path: self.manifest_path.clone(),
@@ -323,6 +352,7 @@
         RunCargoOptions {
             verbose: self.verbose,
             release: self.release,
+            nocapture: self.nocapture,
             run_mode: run_mode,
             disable_cross: self.disable_cross,
             manifest_path: self.manifest_path.clone(),
@@ -333,6 +363,7 @@
         RunCargoOptions {
             verbose: self.verbose,
             release: self.release,
+            nocapture: self.nocapture,
             run_mode: self.run_mode,
             disable_cross: self.disable_cross,
             manifest_path: manifest_path,
@@ -380,12 +411,13 @@
 }
 
 fn make_fargo_command(
-    runner: Option<PathBuf>, options: &RunCargoOptions, target_options: &TargetOptions<'_, '_>,
-    additional_target_args: Option<&str>,
+    runner: Option<PathBuf>, options: &RunCargoOptions, nocapture: bool,
+    target_options: &TargetOptions<'_, '_>, additional_target_args: Option<&str>,
 ) -> Result<String, Error> {
     let tiles_arg = format!("--{}", TILES);
     let ermine_arg = format!("--{}", ERMINE);
     let run_arg = format!("--{}", RUN);
+    let nocapture_arg = format!("--{}", NOCAPTURE);
 
     let fargo_path = if runner.is_some() {
         runner.unwrap()
@@ -410,6 +442,10 @@
 
     runner_args.push(RUN_ON_TARGET);
 
+    if nocapture {
+        runner_args.push(&nocapture_arg);
+    }
+
     match options.run_mode {
         RunMode::Normal => (),
         RunMode::Tiles => runner_args.push(&tiles_arg),
@@ -448,6 +484,7 @@
 ///     &RunCargoOptions {
 ///         verbose: false,
 ///         release: true,
+///         nocapture: false,
 ///         run_mode: RunMode::Normal,
 ///         disable_cross: false,
 ///         manifest_path: None,
@@ -489,8 +526,13 @@
 
     let target_triple_uc = format!("{}_fuchsia", triple_cpu).to_uppercase();
 
-    let fargo_command =
-        make_fargo_command(runner, &options, target_options, additional_target_args)?;
+    let fargo_command = make_fargo_command(
+        runner,
+        &options,
+        options.nocapture,
+        target_options,
+        additional_target_args,
+    )?;
 
     if options.verbose {
         println!("fargo_command: {:?}", fargo_command);
@@ -601,7 +643,7 @@
     writeln!(
         config,
         "runner = \"{}\"",
-        make_fargo_command(None, options, target_options, None)?
+        make_fargo_command(None, options, true, target_options, None)?
     )?;
     writeln!(config, "")?;
     writeln!(config, "[build]")?;
@@ -624,6 +666,10 @@
 static EXAMPLE: &str = "example";
 static EXAMPLES: &str = "examples";
 
+static TEST: &str = "test";
+static TEST_TARGET_NAME: &str = "test";
+static NOCAPTURE: &str = "nocapture";
+
 static DOC: &str = "doc";
 static DOC_OPEN: &str = "open";
 static DOC_NO_DEPS: &str = "no-deps";
@@ -687,27 +733,37 @@
             .subcommand(
                 SubCommand::with_name("autotest")
                     .about("Auto build and test in Fuchsia device or emulator")
-                    .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release")),
+                    .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release"))
+                    .arg(
+                        Arg::with_name(NOCAPTURE)
+                            .long(NOCAPTURE)
+                            .help("Display all output when running tests."),
+                    ),
             )
             .subcommand(
                 SubCommand::with_name("build-tests")
                     .about("Build tests for Fuchsia device or emulator")
                     .arg(
-                        Arg::with_name("test")
-                            .long("test")
-                            .value_name("test")
+                        Arg::with_name(TEST_TARGET_NAME)
+                            .long(TEST_TARGET_NAME)
+                            .value_name(TEST_TARGET_NAME)
                             .help("Test only the specified test target"),
                     )
                     .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release")),
             )
             .subcommand(
-                SubCommand::with_name("test")
+                SubCommand::with_name(TEST)
                     .about("Run unit tests on Fuchsia device or emulator")
                     .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                     .arg(
-                        Arg::with_name("test")
-                            .long("test")
-                            .value_name("test")
+                        Arg::with_name(NOCAPTURE)
+                            .long(NOCAPTURE)
+                            .help("Display all output when running tests."),
+                    )
+                    .arg(
+                        Arg::with_name(TEST_TARGET_NAME)
+                            .long(TEST_TARGET_NAME)
+                            .value_name(TEST_TARGET_NAME)
                             .help("Test only the specified test target"),
                     )
                     .arg(
@@ -856,6 +912,11 @@
                             .help("arguments to pass to the test runner"),
                     )
                     .arg(
+                        Arg::with_name(NOCAPTURE)
+                            .long(NOCAPTURE)
+                            .help("Display all output when running tests."),
+                    )
+                    .arg(
                         Arg::with_name(TILES)
                             .long(TILES)
                             .help("Use tiles to run binary."),
@@ -906,6 +967,7 @@
     let run_cargo_options = RunCargoOptions {
         verbose,
         release: false,
+        nocapture: false,
         run_mode: RunMode::Normal,
         disable_cross,
         manifest_path: None,
@@ -920,23 +982,25 @@
         return autotest(
             &run_cargo_options
                 .release(autotest_matches.is_present(RELEASE))
-                .manifest_path(manifest_path),
+                .manifest_path(manifest_path)
+                .nocapture(autotest_matches.is_present(NOCAPTURE)),
             &target_options,
         );
     }
 
-    if let Some(test_matches) = matches.subcommand_matches("test") {
+    if let Some(test_matches) = matches.subcommand_matches(TEST) {
         let test_params = test_matches
             .values_of("test_params")
             .map(|x| x.collect())
             .unwrap_or_else(|| vec![]);
-        let test_target = test_matches.value_of("test").unwrap_or("");
+        let test_target = test_matches.value_of(TEST_TARGET_NAME).unwrap_or("");
         let test_args = test_matches.value_of("test_args");
         let manifest_path = convert_manifest_path(&test_matches.value_of(MANIFEST_PATH));
         return run_tests(
             &run_cargo_options
                 .release(test_matches.is_present(RELEASE))
-                .manifest_path(manifest_path),
+                .manifest_path(manifest_path)
+                .nocapture(test_matches.is_present(NOCAPTURE)),
             false,
             &target_options,
             test_target,
@@ -1021,7 +1085,7 @@
     }
 
     if let Some(build_test_matches) = matches.subcommand_matches("build-tests") {
-        let test_target = build_test_matches.value_of("test").unwrap_or("");
+        let test_target = build_test_matches.value_of(TEST_TARGET_NAME).unwrap_or("");
         let manifest_path = convert_manifest_path(&build_test_matches.value_of(MANIFEST_PATH));
         build_tests(
             &run_cargo_options
@@ -1107,6 +1171,7 @@
             &RunCargoOptions {
                 verbose,
                 release: false,
+                nocapture: false,
                 run_mode: RunMode::Normal,
                 disable_cross: disable_cross,
                 manifest_path: None,
@@ -1134,6 +1199,7 @@
         return run_program_on_target(
             program,
             verbose,
+            run_on_target_matches.is_present(NOCAPTURE),
             &fuchsia_config,
             &target_options,
             run_mode,