Make a fargo library and expose run_cargo

Change-Id: Ia0a2f14660ab556c88648a318644b87e96f03ac2
diff --git a/Cargo.toml b/Cargo.toml
index 6a9123b..d85901c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,4 +11,8 @@
 serde_json = "1.0.2"
 toml = "0.4.2"
 uname = "0.1.1"
-notify = "4.0.0"
\ No newline at end of file
+notify = "4.0.0"
+
+[[bin]]
+name = "fargo"
+doc = false
diff --git a/src/bin/fargo.rs b/src/bin/fargo.rs
new file mode 100644
index 0000000..e255f75
--- /dev/null
+++ b/src/bin/fargo.rs
@@ -0,0 +1,27 @@
+#![recursion_limit = "1024"]
+
+#[macro_use]
+extern crate error_chain;
+extern crate fargo;
+
+use fargo::run;
+
+error_chain!{}
+
+fn main() {
+    if let Err(ref e) = run() {
+        println!("error: {}", e);
+
+        for e in e.iter().skip(1) {
+            println!("caused by: {}", e);
+        }
+
+        // The backtrace is not always generated. Try to run this example
+        // with `RUST_BACKTRACE=1`.
+        if let Some(backtrace) = e.backtrace() {
+            println!("backtrace: {:?}", backtrace);
+        }
+
+        ::std::process::exit(1);
+    }
+}
diff --git a/src/main.rs b/src/lib.rs
similarity index 92%
rename from src/main.rs
rename to src/lib.rs
index 31b48e1..977d730 100644
--- a/src/main.rs
+++ b/src/lib.rs
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+//! While fargo is mainly intended to be a command line tool, this library
+//! exposes one function, `run_cargo`, that could be integrated directly into
+//! Rust programs that want to cross compile cargo crates on Fuchsia.
+
 #![recursion_limit = "1024"]
 
 extern crate clap;
@@ -40,7 +44,8 @@
 
 use clap::{App, AppSettings, Arg, SubCommand};
 use device::{netaddr, scp_to_device, ssh, start_emulator, stop_emulator};
-use sdk::{rust_c_path, rust_linker_path, TargetOptions};
+use sdk::{rust_c_path, rust_linker_path};
+pub use sdk::TargetOptions;
 use cross::{pkg_config_path, run_configure, run_pkg_config};
 use std::path::PathBuf;
 use std::process::Command;
@@ -167,7 +172,7 @@
         args.push(param);
     }
 
-    run_cargo(verbose, release, false,&args, &target_options)?;
+    run_cargo(verbose, release, false, &args, &target_options)?;
     Ok(())
 }
 
@@ -202,7 +207,18 @@
     return Ok(());
 }
 
-fn run_cargo(
+/// Runs the cargo tool configured to target Fuchsia.
+///
+/// # Examples
+///
+/// ```
+/// use fargo::{run_cargo, TargetOptions};
+///
+/// let target_options = TargetOptions::new(true);
+/// run_cargo(false, true, false, &["--help"], &target_options);
+///
+/// ```
+pub fn run_cargo(
     verbose: bool,
     release: bool,
     launch: bool,
@@ -269,7 +285,8 @@
 }
 
 
-fn run() -> Result<()> {
+#[doc(hidden)]
+pub fn run() -> Result<()> {
     let matches = App::new("fargo")
         .version("v0.1.0")
         .setting(AppSettings::GlobalVersion)
@@ -320,13 +337,15 @@
                 .arg(Arg::with_name("release").long("release").help(
                     "Build release",
                 ))
-                .arg(Arg::with_name("example")
-                    .long("example")
-                    .takes_value(true)
-                    .help("Build a specific example from the examples/ dir.")
+                .arg(
+                    Arg::with_name("example")
+                        .long("example")
+                        .takes_value(true)
+                        .help("Build a specific example from the examples/ dir."),
                 )
                 .arg(Arg::with_name("examples").long("examples").help(
-                    "Build all examples in the examples/ dir.")),
+                    "Build all examples in the examples/ dir.",
+                )),
         )
         .subcommand(
             SubCommand::with_name("run")
@@ -337,10 +356,11 @@
                 .arg(Arg::with_name("launch").long("launch").help(
                     "Use launch to run binary.",
                 ))
-                .arg(Arg::with_name("example")
-                    .long("example")
-                    .value_name("example")
-                    .help("Run a specific example from the examples/ dir.")
+                .arg(
+                    Arg::with_name("example")
+                        .long("example")
+                        .value_name("example")
+                        .help("Run a specific example from the examples/ dir."),
                 ),
         )
         .subcommand(
@@ -458,7 +478,7 @@
             verbose,
             build_matches.is_present("release"),
             &target_options,
-            &params
+            &params,
         ).chain_err(|| "building binary failed")?;
         return Ok(());
     }
@@ -475,7 +495,7 @@
             run_matches.is_present("release"),
             run_matches.is_present("launch"),
             &target_options,
-            &params
+            &params,
         ).chain_err(|| "running binary failed");
     }
 
@@ -571,21 +591,3 @@
 
     Ok(())
 }
-
-fn main() {
-    if let Err(ref e) = run() {
-        println!("error: {}", e);
-
-        for e in e.iter().skip(1) {
-            println!("caused by: {}", e);
-        }
-
-        // The backtrace is not always generated. Try to run this example
-        // with `RUST_BACKTRACE=1`.
-        if let Some(backtrace) = e.backtrace() {
-            println!("backtrace: {:?}", backtrace);
-        }
-
-        ::std::process::exit(1);
-    }
-}
diff --git a/src/sdk.rs b/src/sdk.rs
index 25c1484..d72c520 100644
--- a/src/sdk.rs
+++ b/src/sdk.rs
@@ -8,6 +8,10 @@
 
 error_chain!{}
 
+/// The `TargetOptions` struct bundles together a number of parameters specific to
+/// the Fuchsia target that need to be passed through various internal functions. For
+/// the moment there is no way to set anything but the release_os field, but this
+/// will change when fargo starts supporting ARM targets.
 pub struct TargetOptions {
     pub release_os: bool,
     pub target_cpu: &'static str,
@@ -15,6 +19,15 @@
 }
 
 impl TargetOptions {
+    /// Constructs a new `TargetOptions`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use fargo::TargetOptions;
+    ///
+    /// let target_options = TargetOptions::new(true);
+    /// ```
     pub fn new(release_os: bool) -> TargetOptions {
         TargetOptions {
             release_os: release_os,