// Copyright 2017 The Fuchsia Authors. All rights reserved.
// 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"]

mod build_rustc;
mod cross;
mod device;
mod package;
pub mod run2;
mod sdk;
mod utils;

pub use crate::sdk::{FuchsiaConfig, TargetOptions};

use crate::build_rustc::build_rustc;
use crate::cross::{pkg_config_path, run_configure, run_pkg_config};
use crate::device::{
    enable_networking, netaddr, netls, scp_to_device, ssh, start_emulator, stop_emulator,
    StartEmulatorOptions,
};
use crate::package::make_package;
use crate::{
    sdk::{
        cargo_out_dir, cargo_path, clang_archiver_path, clang_c_compiler_path,
        clang_cpp_compiler_path, clang_ranlib_path, clang_resource_dir, rustc_path, rustdoc_path,
        shared_libraries_path, sysroot_path, zircon_build_path,
    },
    utils::strip_binary,
};

use clap::{App, AppSettings, Arg, SubCommand};
use failure::{bail, err_msg, format_err, Error, ResultExt};
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::time::SystemTime;

fn copy_to_target(
    source_path: &PathBuf,
    verbose: bool,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
) -> Result<String, Error> {
    let netaddr = netaddr(verbose, target_options)?;
    if verbose {
        println!("netaddr {}", netaddr);
    }
    let destination_path = format!(
        "/tmp/{}",
        source_path
            .file_name()
            .ok_or(format_err!("file_name failed on {:#?}", source_path))?
            .to_string_lossy()
    );
    println!("copying {} to {}", source_path.to_string_lossy(), destination_path);
    scp_to_device(verbose, config, &netaddr, &source_path, &destination_path)?;
    Ok(destination_path)
}

fn run_program_on_target(
    filename: &str,
    verbose: bool,
    nocapture: bool,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
    run_mode: RunMode,
    cmx_path: &Option<PathBuf>,
    story_name: &str,
    mod_name: &str,
    app_name: &str,
    params: &[&str],
    test_args: Option<&str>,
) -> Result<(), Error> {
    let source_path = PathBuf::from(&filename);
    let target_string = match run_mode {
        RunMode::Normal => {
            let stripped_source_path = strip_binary(&source_path)?;
            copy_to_target(&stripped_source_path, verbose, config, target_options)?
        }
        _ => {
            if cmx_path.is_none() {
                bail!("Run modes other than normal require a path to a cmx file");
            }
            make_package(
                verbose,
                target_options,
                &source_path,
                cmx_path.as_ref().unwrap(),
                app_name,
            )?
        }
    };

    let mut command_string = match run_mode {
        RunMode::Tiles => "tiles_ctl add ".to_string(),
        RunMode::Ermine => {
            format!("sessionctl --story_name={} --mod_name={} --mod_url=", story_name, mod_name)
        }
        RunMode::Run => "run ".to_string(),
        RunMode::Normal => "".to_string(),
    };
    command_string.push_str(&target_string);

    match run_mode {
        RunMode::Ermine => {
            command_string.push_str(" add_mod");
        }
        _ => (),
    }

    if nocapture {
        command_string.push_str(" --");
        command_string.push_str(NOCAPTURE);
    }

    for param in params {
        command_string.push(' ');
        command_string.push_str(param);
    }

    if let Some(test_args_str) = test_args {
        command_string.push_str(" -- ");
        command_string.push_str(test_args_str);
    }

    if verbose {
        println!("running {}", command_string);
    }

    ssh(verbose, config, target_options, &command_string).context("ssh failed")?;
    Ok(())
}

extern crate notify;

use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;
use std::time::Duration;

fn autotest(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let (tx, rx) = channel();
    let mut watcher: RecommendedWatcher =
        Watcher::new(tx, Duration::from_secs(1)).context("autotest: watcher creation failed")?;

    let cwd = std::fs::canonicalize(std::env::current_dir()?)
        .context("autotest: canonicalize working directory")?;
    let tgt = cwd.join("target");
    let git = cwd.join(".git");

    watcher.watch(&cwd, RecursiveMode::Recursive).context("autotest: watch failed")?;

    println!("autotest: started");
    loop {
        let event = rx.recv().context("autotest: watch recv failed")?;
        match event {
            notify::DebouncedEvent::Create(path)
            | notify::DebouncedEvent::Write(path)
            | notify::DebouncedEvent::Chmod(path)
            | notify::DebouncedEvent::Remove(path)
            | notify::DebouncedEvent::Rename(path, _) => {
                // TODO(raggi): provide a fuller ignore flag/pattern match solution here.
                if !path.starts_with(&tgt) && !path.starts_with(&git) {
                    println!("autotest: running tests because {:?}", path);
                    run_tests(run_cargo_options, false, target_options, &[], None).ok();
                }
            }
            _ => {}
        }
    }
}

fn run_tests(
    run_cargo_options: &RunCargoOptions,
    no_run: bool,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
    target_params: Option<&str>,
) -> Result<(), Error> {
    let mut args = vec![];

    if no_run {
        args.push("--no-run");
    }

    for param in params {
        args.push(param);
    }

    if let Some(target_params) = target_params {
        let formatted_target_params = format!("--args={}", target_params);
        run_cargo(
            &run_cargo_options,
            "test",
            &args,
            target_options,
            None,
            Some(&formatted_target_params),
        )?;
    } else {
        run_cargo(&run_cargo_options, "test", &args, target_options, None, None)?;
    }

    Ok(())
}

fn build_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, "build", params, target_options, None, None)
}

fn check_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, "check", params, target_options, None, None)
}

fn run_binary(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    params: &[&str],
) -> Result<(), Error> {
    run_cargo(run_cargo_options, RUN, params, target_options, None, None)?;
    Ok(())
}

fn build_doc(
    run_cargo_options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
    no_deps: bool,
    open: bool,
) -> Result<(), Error> {
    let mut args = vec![];
    if no_deps {
        args.push("--no-deps");
    }
    if open {
        args.push("--open");
    }
    run_cargo(run_cargo_options, DOC, &args, &target_options, None, None)
}

fn load_driver(
    run_cargo_options: &RunCargoOptions,
    config: &FuchsiaConfig,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let args = vec![];
    run_cargo(run_cargo_options, "build", &args, target_options, None, None)?;
    let cwd = std::env::current_dir()?;
    let package = cwd
        .file_name()
        .ok_or(err_msg("No current directory"))?
        .to_str()
        .ok_or(err_msg("Invalid current directory"))?;
    let filename = cargo_out_dir(target_options)?.join(format!("lib{}.so", package));
    let destination_path =
        copy_to_target(&filename, run_cargo_options.verbose, config, target_options)?;
    let command_string = format!("dm add-driver:{}", destination_path);
    if run_cargo_options.verbose {
        println!("running {}", command_string);
    }
    ssh(run_cargo_options.verbose, config, target_options, &command_string)?;
    Ok(())
}

#[derive(Clone, Copy, Debug)]
pub enum RunMode {
    Normal,
    Run,
    Tiles,
    Ermine,
}

impl Default for RunMode {
    fn default() -> Self {
        RunMode::Normal
    }
}
fn run_switches_to_mode(tiles: bool, run: bool, ermine: bool) -> RunMode {
    if tiles {
        RunMode::Tiles
    } else if run {
        RunMode::Run
    } else if ermine {
        RunMode::Ermine
    } else {
        RunMode::Normal
    }
}

fn random_story_name() -> String {
    let secs = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
        Ok(n) => n.as_secs(),
        Err(_) => panic!("SystemTime before UNIX EPOCH!"),
    };
    format!("fargo-story-{}", secs)
}

#[derive(Debug, Clone, Default)]
pub struct RunCargoOptions {
    pub verbose: bool,
    pub release: bool,
    pub run_mode: RunMode,
    pub story_name: Option<String>,
    pub mod_name: Option<String>,
    pub disable_cross: bool,
    pub nocapture: bool,
    pub manifest_path: Option<PathBuf>,
    pub cmx_path: Option<PathBuf>,
    pub app_name: Option<String>,
}

impl RunCargoOptions {
    pub fn new(verbose: bool, release: bool) -> RunCargoOptions {
        Self { verbose, release, ..Self::default() }
    }

    pub fn disable_cross(&self, disable_cross: bool) -> RunCargoOptions {
        Self { disable_cross, ..self.clone() }
    }

    pub fn release(&self, release: bool) -> RunCargoOptions {
        Self { release, ..self.clone() }
    }

    pub fn nocapture(&self, nocapture: bool) -> RunCargoOptions {
        Self { nocapture, ..self.clone() }
    }

    pub fn run_mode(&self, run_mode: RunMode) -> RunCargoOptions {
        Self { run_mode, ..self.clone() }
    }

    pub fn story_name(&self, story_name: &Option<&str>) -> RunCargoOptions {
        Self { story_name: story_name.map(|name| name.to_string()), ..self.clone() }
    }

    pub fn mod_name(&self, mod_name: &Option<&str>) -> RunCargoOptions {
        Self { mod_name: mod_name.map(|name| name.to_string()), ..self.clone() }
    }

    pub fn manifest_path(&self, manifest_path: Option<PathBuf>) -> RunCargoOptions {
        Self { manifest_path, ..self.clone() }
    }

    pub fn cmx_path(&self, cmx_path: Option<PathBuf>) -> RunCargoOptions {
        Self { cmx_path, ..self.clone() }
    }

    pub fn app_name(&self, app_name: &Option<&str>) -> RunCargoOptions {
        Self { app_name: app_name.map(|name| name.to_string()), ..self.clone() }
    }

    pub fn get_story_name(&self) -> String {
        if let Some(ref name) = self.story_name {
            name.clone()
        } else {
            random_story_name()
        }
    }

    pub fn get_mod_name(&self) -> String {
        if let Some(ref name) = self.mod_name {
            name.clone()
        } else {
            DEFAULT_MOD_NAME.to_string()
        }
    }
}

pub fn get_triple_cpu(target_options: &TargetOptions<'_, '_>) -> String {
    if (target_options.config.fuchsia_arch) == X64 { "x86_64" } else { "aarch64" }.to_string()
}

pub fn get_target_triple(target_options: &TargetOptions<'_, '_>) -> String {
    let triple_cpu = get_triple_cpu(target_options);

    format!("{}-fuchsia", triple_cpu)
}

fn get_rustflags(
    target_options: &TargetOptions<'_, '_>,
    sysroot_as_path: &PathBuf,
) -> Result<String, Error> {
    let target_triple = get_target_triple(target_options);
    let sysroot_lib_pathbuf = sysroot_as_path.join("lib");
    let sysroot_lib = sysroot_lib_pathbuf.to_string_lossy();
    let shared_lib_path = shared_libraries_path(target_options)?;
    let clang_resource_lib = clang_resource_dir(&target_triple)?.join(&target_triple).join("lib");

    let mut rust_flags = vec![
        "-L".to_string(),
        sysroot_lib.to_string(),
        "-Clink-arg=--pack-dyn-relocs=relr".to_string(),
        "-Clink-arg=--threads".to_string(),
        format!("-Clink-arg=-L{}", sysroot_lib),
        format!("-Clink-arg=-L{}/gen/zircon/public/lib/fdio", shared_lib_path.to_string_lossy(),),
        format!("-Clink-arg=-L{}/gen/zircon/public/lib/syslog", shared_lib_path.to_string_lossy(),),
        format!("-Clink-arg=-L{}", clang_resource_lib.to_string_lossy()),
        format!("-Clink-arg=--sysroot={}", sysroot_as_path.to_string_lossy()),
        format!("-Lnative={}", shared_libraries_path(target_options)?.to_string_lossy()),
    ];

    if get_triple_cpu(target_options) == "aarch64" {
        rust_flags.push("-Clink-arg=--fix-cortex-a53-843419".to_string());
    }

    Ok(rust_flags.join(" "))
}

fn make_fargo_command(
    runner: Option<PathBuf>,
    options: &RunCargoOptions,
    nocapture: bool,
    target_options: &TargetOptions<'_, '_>,
    additional_target_args: Option<&str>,
) -> Result<String, Error> {
    let cmx_path;
    let tiles_arg = format!("--{}", RUN_WITH_TILES);
    let ermine_arg = format!(
        "--{} --story-name={} --mod-name={}",
        RUN_WITH_SESSIONCTL,
        options.get_story_name(),
        options.get_mod_name()
    );
    let cmx_arg = format!("--{}", CMX_PATH);
    let app_name_arg = format!("--{}", APP_NAME);
    let run_arg = format!("--{}", RUN_WITH_RUN);
    let nocapture_arg = format!("--{}", NOCAPTURE);

    let fargo_path = if let Some(runner) = runner {
        runner
    } else {
        fs::canonicalize(std::env::current_exe()?)?
    };

    let mut runner_args = vec![fargo_path
        .to_str()
        .ok_or_else(|| err_msg("unable to convert path to utf8 encoding"))?];

    if options.verbose {
        runner_args.push("-v");
    }

    if let Some(device_name) = target_options.device_name {
        runner_args.push("--device-name");
        runner_args.push(device_name);
    }

    runner_args.push(RUN_ON_TARGET);

    if let Some(ref passed_path) = options.cmx_path {
        cmx_path = passed_path.to_string_lossy().to_string();
        runner_args.push(&cmx_arg);
        runner_args.push(&cmx_path);
    } else {
        match options.run_mode {
            RunMode::Normal => (),
            _ => {
                bail!("Run modes other than normal require a path to a cmx file");
            }
        }
    }

    if nocapture {
        runner_args.push(&nocapture_arg);
    }

    match options.run_mode {
        RunMode::Normal => (),
        RunMode::Tiles => runner_args.push(&tiles_arg),
        RunMode::Ermine => runner_args.push(&ermine_arg),
        RunMode::Run => runner_args.push(&run_arg),
    }

    if let Some(args_for_target) = additional_target_args {
        runner_args.push(&args_for_target);
    }

    if let Some(app_name) = options.app_name.as_ref() {
        runner_args.push(&app_name_arg);
        runner_args.push(&app_name);
    }

    Ok(runner_args.join(" "))
}

fn convert_manifest_path(possible_path: &Option<&str>) -> Option<PathBuf> {
    if let Some(path) = possible_path {
        Some(PathBuf::from(path))
    } else {
        None
    }
}

fn format_project(manifest_path: Option<PathBuf>) -> Result<(), Error> {
    let mut cmd = Command::new(cargo_path()?);
    if let Some(ref manifest_path) = manifest_path {
        let parent =
            manifest_path.parent().expect(&format!("Can't get parent of {:#?}", manifest_path));
        cmd.current_dir(parent);
    }
    cmd.arg(FORMAT);
    let cargo_status = cmd.status()?;
    if !cargo_status.success() {
        bail!("cargo exited with status {:?}", cargo_status,);
    }
    Ok(())
}

/// Runs the cargo tool configured to target Fuchsia. When used as a library,
/// the runner options must contain the path to fargo or some other program
/// that implements the `run-on-target` subcommand in a way compatible with
/// fargo.
///
/// # Examples
///
/// ```
/// use fargo::{run_cargo, FuchsiaConfig, RunCargoOptions, RunMode, TargetOptions};
///
/// let config = FuchsiaConfig::default();
/// let target_options = TargetOptions::new(&config, None);
/// run_cargo(
///     &RunCargoOptions {
///         verbose: false,
///         release: true,
///         nocapture: false,
///         run_mode: RunMode::Normal,
///         story_name: None,
///         mod_name: None,
///         disable_cross: false,
///         manifest_path: None,
///         cmx_path: None,
///         app_name: None,
///     },
///     "help",
///     &[],
///     &target_options,
///     None,
///     None,
/// );
/// ```
pub fn run_cargo(
    options: &RunCargoOptions,
    subcommand: &str,
    args: &[&str],
    target_options: &TargetOptions<'_, '_>,
    runner: Option<PathBuf>,
    additional_target_args: Option<&str>,
) -> Result<(), Error> {
    if options.verbose {
        println!("target_options = {:?}", target_options);
    }

    let triple_cpu = get_triple_cpu(target_options);
    let target_triple = get_target_triple(target_options);
    let mut target_args = vec!["--target", &target_triple];

    if options.release {
        target_args.push("--release");
    }

    if options.verbose {
        println!("target_options.target_cpu = {:?}", target_options.config.fuchsia_arch);
        println!("triple_cpu = {:?}", triple_cpu);
        println!("target_triple = {:?}", target_triple);
        println!("target_args = {:?}", target_args);
        println!("options = {:?}", options);
    }

    let target_triple_uc = format!("{}_fuchsia", triple_cpu).to_uppercase();

    let fargo_command = make_fargo_command(
        runner,
        &options,
        options.nocapture,
        target_options,
        additional_target_args,
    )?;

    if options.verbose {
        println!("fargo_command: {:?}", fargo_command);
    }

    let pkg_path = pkg_config_path(target_options)?;
    let mut cmd = Command::new(cargo_path()?);
    let sysroot_as_path = sysroot_path(target_options)?;
    let sysroot_as_str = sysroot_as_path.to_string_lossy();

    let args: Vec<&str> = args.iter().map(|a| if *a == "++" { "--" } else { *a }).collect();

    let runner_env_name = format!("CARGO_TARGET_{}_RUNNER", target_triple_uc);
    let rustflags_env_name = format!("CARGO_TARGET_{}_RUSTFLAGS", target_triple_uc);

    if options.verbose {
        println!("runner_env_name: {:?}", runner_env_name);
        println!("rustflags_env_name: {:?}", rustflags_env_name);
        println!("rustc_path: {:?}", rustc_path()?.to_string_lossy());
        println!("cargo_path: {:?}", cargo_path()?.to_string_lossy());
    }

    cmd.env(runner_env_name, fargo_command)
        .env(rustflags_env_name, get_rustflags(target_options, &sysroot_as_path)?)
        .env("RUSTC", rustc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOC", rustdoc_path()?.to_string_lossy().as_ref())
        .env("RUSTDOCFLAGS", "--cap-lints allow -Z unstable-options")
        .env("FUCHSIA_SHARED_ROOT", shared_libraries_path(target_options)?)
        .env("ZIRCON_BUILD_ROOT", zircon_build_path(&target_options.config)?)
        .arg(subcommand)
        .args(target_args)
        .args(args);

    if let Some(ref manifest_path) = options.manifest_path {
        let manifest_args: Vec<&str> = vec![
            "--manifest-path",
            manifest_path.to_str().expect("path to string failed for manifest_path"),
        ];
        cmd.args(manifest_args);
    }

    if !options.disable_cross {
        let cc_env_name = format!("CC_{}", target_triple_uc);
        let cxx_env_name = format!("CXX_{}", target_triple_uc);
        let cflags_env_name = format!("CFLAGS_{}", target_triple_uc);
        let ar_env_name = format!("AR_{}", target_triple_uc);
        cmd.env(cc_env_name, clang_c_compiler_path()?.to_string_lossy().as_ref())
            .env(cxx_env_name, clang_cpp_compiler_path()?.to_string_lossy().as_ref())
            .env(cflags_env_name, format!("--sysroot={}", sysroot_as_str))
            .env(ar_env_name, clang_archiver_path()?.to_string_lossy().as_ref())
            .env("RANLIB", clang_ranlib_path()?.to_string_lossy().as_ref())
            .env("PKG_CONFIG_ALL_STATIC", "1")
            .env("PKG_CONFIG_ALLOW_CROSS", "1")
            .env("PKG_CONFIG_PATH", "")
            .env("PKG_CONFIG_LIBDIR", pkg_path);
    }

    if options.verbose {
        println!("cargo cmd: {:?}", cmd);
    }

    let cargo_status = cmd.status()?;
    if !cargo_status.success() {
        bail!("cargo exited with status {:?}", cargo_status,);
    }

    Ok(())
}

fn write_config(
    options: &RunCargoOptions,
    target_options: &TargetOptions<'_, '_>,
) -> Result<(), Error> {
    let cargo_dir_path = Path::new(".cargo");
    if cargo_dir_path.exists() {
        if !cargo_dir_path.is_dir() {
            bail!(
                "fargo wants to create a directory {:#?}, but there is an existing file in the way",
                cargo_dir_path
            );
        }
    } else {
        fs::create_dir(cargo_dir_path)?;
    }

    let mut config = File::create(".cargo/config")?;

    let sysroot_as_path = sysroot_path(target_options)?;
    writeln!(config, "[target.{}]", get_target_triple(target_options))?;
    writeln!(config, "rustflags = \"{}\"", get_rustflags(target_options, &sysroot_as_path)?)?;
    writeln!(
        config,
        "runner = \"{}\"",
        make_fargo_command(None, options, true, target_options, None)?
    )?;
    writeln!(config, "")?;
    writeln!(config, "[build]")?;
    writeln!(config, "rustc = \"{}\"", rustc_path()?.to_string_lossy())?;
    writeln!(config, "rustdoc = \"{}\"", rustdoc_path()?.to_string_lossy())?;
    writeln!(config, "target = \"{}\"", get_target_triple(target_options))?;
    Ok(())
}

static RUN: &str = "run";
static RUN_WITH_TILES: &str = "run-with-tiles";
static RUN_WITH_RUN: &str = "run-with-run";
static RUN_WITH_SESSIONCTL: &str = "run-with-sessionctl";
static STORY_NAME: &str = "story-name";
static MOD_NAME: &str = "mod-name";
static DEFAULT_MOD_NAME: &str = "fargo";
static APP_NAME: &str = "app-name";
static DEFAULT_APP_NAME: &str = "app";

static CHECK: &str = "check";
static RELEASE: &str = "release";
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";

static X64: &str = "x64";

static SUBCOMMAND: &str = "subcommand";

static DISABLE_CROSS_ENV: &str = "disable-cross-env";

static NO_NET: &str = "no-net";
static FX_RUN_PARAMS: &str = "fx-run-params";
static MANIFEST_PATH: &str = "manifest-path";
static CMX_PATH: &str = "cmx-path";

static RELEASE_HELP: &str = "Build artifacts in release mode, with optimizations";

static START: &str = "start";
static RESTART: &str = "restart";
static GRAPHICS: &str = "graphics";
static KVM: &str = "kvm";
static DISABLE_VIRTCON: &str = "disable-virtcon";

static WRITE_CONFIG: &str = "write-config";

static BUILD_RUSTC: &str = "build-rustc";
static RUST_ROOT: &str = "rust-root";

static RUN_ON_TARGET: &str = "run-on-target";

static MAKE_PACKAGE: &str = "make-package";
static BINARY_PATH: &str = "binary-path";

static FORMAT: &str = "fmt";

/// Arguments which configure the startup of an emulator.
///
/// Used when `start`ing or `restart`ing.
fn emulator_args() -> Vec<Arg<'static, 'static>> {
    vec![
        Arg::with_name(GRAPHICS).short("g").help("Start a simulator with graphics enabled"),
        Arg::with_name(KVM).short("k").help("Start a simulator with KVM (Linux only)"),
        Arg::with_name(DISABLE_VIRTCON)
            .long(DISABLE_VIRTCON)
            .help("Do not launch the virtual console service if this option is present"),
        Arg::with_name(NO_NET).long(NO_NET).help("Don't set up networking."),
        Arg::with_name(FX_RUN_PARAMS).index(1).multiple(true),
    ]
}

#[doc(hidden)]
pub fn run() -> Result<(), Error> {
    let emulator_args = emulator_args();

    let global_matches = App::new("fargo")
        .version("v0.2.0")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::ArgRequiredElseHelp)
        .about("Fargo is a prototype Fuchsia-specific wrapper around Cargo")
        .arg(
            Arg::with_name("verbose")
                .long("verbose")
                .short("v")
                .help("Print verbose output while performing commands"),
        )
        .arg(
            Arg::with_name(DISABLE_CROSS_ENV)
                .long(DISABLE_CROSS_ENV)
                .help("Disable the setting of CC, AR and such environmental variables."),
        )
        .arg(
            Arg::with_name("device-name")
                .long("device-name")
                .short("N")
                .value_name("device-name")
                .help(
                    "Name of device to target, needed if there are multiple devices visible \
                     on the network",
                ),
        )
        .arg(
            Arg::with_name(MANIFEST_PATH)
                .long(MANIFEST_PATH)
                .value_name(MANIFEST_PATH)
                .global(true)
                .help("Path to Cargo.toml"),
        )
        .subcommand(
            SubCommand::with_name("autotest")
                .about("Auto build and test in Fuchsia device or emulator")
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .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(TEST)
                .about("Run unit tests on Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    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(
                    Arg::with_name(EXAMPLE)
                        .long(EXAMPLE)
                        .takes_value(true)
                        .help("Test a specific example from the examples/ dir."),
                )
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to run tests for"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .value_name("bin")
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test_args")
                        .long("args")
                        .value_name("args")
                        .help("arguments to pass to the test runner"),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run tests."))
                .arg(Arg::with_name("test_params").index(1).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name("build")
                .about("Build binary targeting Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .takes_value(true)
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test")
                        .long("test")
                        .takes_value(true)
                        .help("Build only the specified test target"),
                )
                .arg(Arg::with_name("tests").long("tests").help("Build all the tests"))
                .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."),
                ),
        )
        .subcommand(
            SubCommand::with_name(CHECK)
                .about("Check binary targeting Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .takes_value(true)
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .takes_value(true)
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name("test")
                        .long("test")
                        .takes_value(true)
                        .help("Build only the specified test target"),
                )
                .arg(Arg::with_name("tests").long("tests").help("Build all the tests"))
                .arg(
                    Arg::with_name(EXAMPLE)
                        .long(EXAMPLE)
                        .takes_value(true)
                        .help("Check a specific example from the examples/ dir."),
                )
                .arg(
                    Arg::with_name(EXAMPLES)
                        .long(EXAMPLES)
                        .help("Check all examples in the examples/ dir."),
                ),
        )
        .subcommand(
            SubCommand::with_name(DOC)
                .about("Build a package's documentation")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name(DOC_NO_DEPS)
                        .long(DOC_NO_DEPS)
                        .help("Don't build documentation for dependencies"),
                )
                .arg(
                    Arg::with_name(DOC_OPEN)
                        .long(DOC_OPEN)
                        .help("Opens the docs in a browser after the operation"),
                ),
        )
        .subcommand(
            SubCommand::with_name(RUN)
                .about("Run binary on Fuchsia device or emulator")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help(RELEASE_HELP))
                .arg(
                    Arg::with_name(STORY_NAME)
                        .long(STORY_NAME)
                        .short("n")
                        .value_name(STORY_NAME)
                        .help("Name of story to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(MOD_NAME)
                        .long(MOD_NAME)
                        .short("m")
                        .value_name(MOD_NAME)
                        .help("Name of mod to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app as it appears in the manifest file."),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(
                    Arg::with_name(RUN_WITH_TILES)
                        .long(RUN_WITH_TILES)
                        .help("Use tiles_ctl add to run binary."),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run binary."))
                .arg(
                    Arg::with_name(RUN_WITH_SESSIONCTL)
                        .long(RUN_WITH_SESSIONCTL)
                        .help("Use sessionctl to run binary."),
                )
                .arg(
                    Arg::with_name("package")
                        .short("p")
                        .long("package")
                        .value_name("package")
                        .help("Package to build"),
                )
                .arg(
                    Arg::with_name("bin")
                        .long("bin")
                        .value_name("bin")
                        .help("Name of the bin target to run"),
                )
                .arg(
                    Arg::with_name(EXAMPLE)
                        .long(EXAMPLE)
                        .value_name(EXAMPLE)
                        .help("Run a specific example from the examples/ dir."),
                ),
        )
        .subcommand(
            SubCommand::with_name("load-driver")
                .about("Build driver and load it on Fuchsia device or emulator.")
                .arg(Arg::with_name(RELEASE).long(RELEASE).help("Build release")),
        )
        .subcommand(SubCommand::with_name("list-devices").about("List visible Fuchsia devices"))
        .subcommand(
            SubCommand::with_name(START).about("Start a Fuchsia emulator").args(&emulator_args),
        )
        .subcommand(SubCommand::with_name("stop").about("Stop all Fuchsia emulators"))
        .subcommand(
            SubCommand::with_name("enable-networking")
                .about("Enable networking for a running emulator"),
        )
        .subcommand(
            SubCommand::with_name(RESTART)
                .about("Stop all Fuchsia emulators and start a new one")
                .args(&emulator_args),
        )
        .subcommand(
            SubCommand::with_name("ssh").about("Open a shell on Fuchsia device or emulator"),
        )
        .subcommand(
            SubCommand::with_name("cargo")
                .about(
                    "Run a cargo command for Fuchsia. Use -- to indicate that all following \
                     arguments should be passed to cargo.",
                )
                .arg(Arg::with_name(SUBCOMMAND).required(true))
                .arg(Arg::with_name("cargo_params").index(2).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name(RUN_ON_TARGET)
                .about("Act as a test runner for cargo")
                .arg(
                    Arg::with_name("test_args")
                        .long("args")
                        .value_name("args")
                        .help("arguments to pass to the test runner"),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(
                    Arg::with_name(NOCAPTURE)
                        .long(NOCAPTURE)
                        .help("Display all output when running tests."),
                )
                .arg(
                    Arg::with_name(RUN_WITH_TILES)
                        .long(RUN_WITH_TILES)
                        .help("Use tiles to run binary."),
                )
                .arg(Arg::with_name(RUN_WITH_RUN).long(RUN_WITH_RUN).help("Use run to run binary."))
                .arg(
                    Arg::with_name(RUN_WITH_SESSIONCTL)
                        .long(RUN_WITH_SESSIONCTL)
                        .help("Use sessionctl to run binary."),
                )
                .arg(
                    Arg::with_name(STORY_NAME)
                        .long(STORY_NAME)
                        .short("n")
                        .value_name(STORY_NAME)
                        .help("Name of story to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(MOD_NAME)
                        .long(MOD_NAME)
                        .short("m")
                        .value_name(MOD_NAME)
                        .help("Name of mod to pass to sessionctl"),
                )
                .arg(
                    Arg::with_name(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app"),
                )
                .arg(Arg::with_name("run_on_target_params").index(1).multiple(true))
                .setting(AppSettings::Hidden),
        )
        .subcommand(
            SubCommand::with_name("pkg-config")
                .about("Run pkg-config for the cross compilation environment")
                .arg(Arg::with_name("pkgconfig_param").index(1).multiple(true)),
        )
        .subcommand(
            SubCommand::with_name("configure")
                .about("Run a configure script for the cross compilation environment")
                .arg(Arg::with_name("configure_param").index(1).multiple(true))
                .arg(
                    Arg::with_name("no-host")
                        .long("no-host")
                        .help("Don't pass --host to configure"),
                ),
        )
        .subcommand(
            SubCommand::with_name(WRITE_CONFIG).about(
                "Write a .cargo/config file to allow cargo to operate correctly for Fuchsia",
            ),
        )
        .subcommand(
            SubCommand::with_name(BUILD_RUSTC)
                .arg(
                    Arg::with_name(RUST_ROOT)
                        .long(RUST_ROOT)
                        .value_name(RUST_ROOT)
                        .required(true)
                        .help("Path to rust checkout"),
                )
                .about("Build rustc targeting Fuchsia"),
        )
        .subcommand(
            SubCommand::with_name(MAKE_PACKAGE)
                .arg(
                    Arg::with_name(BINARY_PATH)
                        .long(BINARY_PATH)
                        .value_name(BINARY_PATH)
                        .required(true)
                        .help("Path to the binary to package"),
                )
                .arg(
                    Arg::with_name(CMX_PATH)
                        .long(CMX_PATH)
                        .value_name(CMX_PATH)
                        .help("Path to sandbox file to use when running"),
                )
                .arg(
                    Arg::with_name(APP_NAME)
                        .long(APP_NAME)
                        .value_name(APP_NAME)
                        .default_value(DEFAULT_APP_NAME)
                        .help("Name of app"),
                )
                .about("Make a Fuchsia package from an unstripped binary"),
        )
        .subcommand(
            SubCommand::with_name(FORMAT).about("Run cargo fmt using the Fuchsia toolchain"),
        )
        .get_matches();

    let verbose = global_matches.is_present("verbose");
    let disable_cross = global_matches.is_present(DISABLE_CROSS_ENV);

    let fuchsia_config = FuchsiaConfig::new_from_fx_exec()?;
    if verbose {
        println!("fuchsia_config = {:#?}", fuchsia_config);
    }

    let target_options =
        TargetOptions::new(&fuchsia_config, global_matches.value_of("device-name"));

    let run_cargo_options = RunCargoOptions { verbose, ..RunCargoOptions::default() };

    if verbose {
        println!("target_options = {:#?}", target_options);
    }

    if let Some(autotest_matches) = global_matches.subcommand_matches("autotest") {
        let manifest_path = convert_manifest_path(&autotest_matches.value_of(MANIFEST_PATH));
        return autotest(
            &run_cargo_options
                .release(autotest_matches.is_present(RELEASE))
                .manifest_path(manifest_path)
                .cmx_path(autotest_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)))
                .nocapture(autotest_matches.is_present(NOCAPTURE)),
            &target_options,
        );
    }

    if let Some(test_matches) = global_matches.subcommand_matches(TEST) {
        let mut params = vec![];
        if let Some(package) = test_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = test_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(example) = test_matches.value_of(EXAMPLE) {
            params.push("--example");
            params.push(example);
        }
        if let Some(test_params) = test_matches.values_of("test_params") {
            params.extend(test_params.collect::<Vec<_>>());
        }
        if let Some(test) = test_matches.value_of(TEST_TARGET_NAME) {
            params.push("--test");
            params.push(test);
        }

        let test_args = test_matches.value_of("test_args");
        let manifest_path = convert_manifest_path(&test_matches.value_of(MANIFEST_PATH));
        let run_mode = run_switches_to_mode(
            test_matches.is_present(RUN_WITH_TILES),
            test_matches.is_present(RUN_WITH_RUN),
            test_matches.is_present(RUN_WITH_SESSIONCTL),
        );
        return run_tests(
            &run_cargo_options
                .cmx_path(test_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)))
                .run_mode(run_mode)
                .release(test_matches.is_present(RELEASE))
                .manifest_path(manifest_path)
                .nocapture(test_matches.is_present(NOCAPTURE)),
            false,
            &target_options,
            &params,
            test_args,
        );
    }

    if let Some(build_matches) = global_matches.subcommand_matches("build") {
        let mut params = vec![];
        if let Some(package) = build_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = build_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(test) = build_matches.value_of("test") {
            params.push("--test");
            params.push(test);
        }
        if build_matches.is_present("tests") {
            params.push("--tests");
        }
        if let Some(example) = build_matches.value_of(EXAMPLE) {
            params.push("--example");
            params.push(example);
        }
        if build_matches.is_present("examples") {
            params.push("--examples");
        }

        let manifest_path = convert_manifest_path(&build_matches.value_of(MANIFEST_PATH));
        build_binary(
            &run_cargo_options
                .release(build_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            &params,
        )?;
        return Ok(());
    }

    if let Some(check_matches) = global_matches.subcommand_matches(CHECK) {
        let mut params = vec![];
        if let Some(example) = check_matches.value_of(EXAMPLE) {
            params.push("--example");
            params.push(example);
        }
        if let Some(package) = check_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = check_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(test) = check_matches.value_of("test") {
            params.push("--test");
            params.push(test);
        }
        if check_matches.is_present("tests") {
            params.push("--tests");
        }
        if check_matches.is_present(EXAMPLES) {
            params.push("--examples");
        }

        let manifest_path = convert_manifest_path(&check_matches.value_of(MANIFEST_PATH));
        check_binary(
            &run_cargo_options
                .release(check_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            &params,
        )?;
        return Ok(());
    }

    if let Some(run_matches) = global_matches.subcommand_matches(RUN) {
        let mut params = vec![];
        if let Some(package) = run_matches.value_of("package") {
            params.push("--package");
            params.push(package);
        }
        if let Some(bin) = run_matches.value_of("bin") {
            params.push("--bin");
            params.push(bin);
        }
        if let Some(example) = run_matches.value_of(EXAMPLE) {
            params.push("--example");
            params.push(example);
        }

        let manifest_path = convert_manifest_path(&run_matches.value_of(MANIFEST_PATH));
        let run_mode = run_switches_to_mode(
            run_matches.is_present(RUN_WITH_TILES),
            run_matches.is_present(RUN_WITH_RUN),
            run_matches.is_present(RUN_WITH_SESSIONCTL),
        );
        return run_binary(
            &run_cargo_options
                .release(run_matches.is_present(RELEASE))
                .run_mode(run_mode)
                .story_name(&run_matches.value_of(STORY_NAME))
                .mod_name(&run_matches.value_of(MOD_NAME))
                .app_name(&run_matches.value_of(APP_NAME))
                .manifest_path(manifest_path)
                .cmx_path(run_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s))),
            &target_options,
            &params,
        );
    }

    if let Some(load_driver_matches) = global_matches.subcommand_matches("load-driver") {
        return load_driver(
            &run_cargo_options.release(load_driver_matches.is_present(RELEASE)),
            &fuchsia_config,
            &target_options,
        );
    }

    if let Some(doc_matches) = global_matches.subcommand_matches(DOC) {
        let manifest_path = convert_manifest_path(&doc_matches.value_of(MANIFEST_PATH));
        return build_doc(
            &run_cargo_options
                .release(doc_matches.is_present(RELEASE))
                .manifest_path(manifest_path),
            &target_options,
            doc_matches.is_present(DOC_NO_DEPS),
            doc_matches.is_present(DOC_OPEN),
        );
    }

    if global_matches.subcommand_matches("list-devices").is_some() {
        return netls(verbose, &target_options);
    }

    if let Some(start_matches) = global_matches.subcommand_matches(START) {
        let fx_run_params =
            start_matches.values_of(FX_RUN_PARAMS).map(|x| x.collect()).unwrap_or_else(|| vec![]);

        return start_emulator(
            &StartEmulatorOptions {
                verbose: verbose,
                with_graphics: start_matches.is_present(GRAPHICS),
                with_kvm: start_matches.is_present(KVM),
                with_networking: !start_matches.is_present(NO_NET),
                disable_virtcon: start_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

    if global_matches.subcommand_matches("stop").is_some() {
        return stop_emulator();
    }

    if global_matches.subcommand_matches("enable-networking").is_some() {
        return enable_networking();
    }

    if let Some(restart_matches) = global_matches.subcommand_matches(RESTART) {
        stop_emulator()?;

        let fx_run_params =
            restart_matches.values_of(FX_RUN_PARAMS).map(|x| x.collect()).unwrap_or_else(|| vec![]);

        return start_emulator(
            &StartEmulatorOptions {
                verbose: verbose,
                with_graphics: restart_matches.is_present(GRAPHICS),
                with_kvm: restart_matches.is_present(KVM),
                with_networking: !restart_matches.is_present(NO_NET),
                disable_virtcon: restart_matches.is_present(DISABLE_VIRTCON),
            },
            &fx_run_params,
        );
    }

    if global_matches.subcommand_matches("ssh").is_some() {
        return ssh(verbose, &fuchsia_config, &target_options, "");
    }

    if let Some(cargo_matches) = global_matches.subcommand_matches("cargo") {
        let subcommand =
            cargo_matches.value_of(SUBCOMMAND).expect("The cargo command requires a subcommand");
        let cargo_params =
            cargo_matches.values_of("cargo_params").map(|x| x.collect()).unwrap_or_else(|| vec![]);
        return run_cargo(
            &RunCargoOptions {
                verbose,
                release: false,
                nocapture: false,
                run_mode: RunMode::Normal,
                story_name: None,
                mod_name: None,
                disable_cross: disable_cross,
                manifest_path: None,
                cmx_path: None,
                app_name: None,
            },
            subcommand,
            &cargo_params,
            &target_options,
            None,
            None,
        );
    }

    if let Some(run_on_target_matches) = global_matches.subcommand_matches(RUN_ON_TARGET) {
        let run_cargo_options = run_cargo_options
            .cmx_path(run_on_target_matches.value_of(CMX_PATH).map(|s| PathBuf::from(s)));

        let run_params = run_on_target_matches
            .values_of("run_on_target_params")
            .map(|x| x.collect())
            .unwrap_or_else(|| vec![]);
        let test_args = run_on_target_matches.value_of("test_args");
        let (program, args) =
            run_params.split_first().expect("run on target expects at least one parameter");
        let run_mode = run_switches_to_mode(
            run_on_target_matches.is_present(RUN_WITH_TILES),
            run_on_target_matches.is_present(RUN_WITH_RUN),
            run_on_target_matches.is_present(RUN_WITH_SESSIONCTL),
        );

        return run_program_on_target(
            program,
            verbose,
            run_on_target_matches.is_present(NOCAPTURE),
            &fuchsia_config,
            &target_options,
            run_mode,
            &run_cargo_options.cmx_path,
            run_on_target_matches.value_of(STORY_NAME).unwrap_or(&random_story_name()),
            run_on_target_matches.value_of(MOD_NAME).unwrap_or(DEFAULT_MOD_NAME),
            run_on_target_matches.value_of(APP_NAME).unwrap_or(DEFAULT_APP_NAME),
            args,
            test_args,
        );
    }

    if let Some(pkg_matches) = global_matches.subcommand_matches("pkg-config") {
        let pkg_params =
            pkg_matches.values_of("pkgconfig_param").map(|x| x.collect()).unwrap_or_else(|| vec![]);
        let exit_code = run_pkg_config(verbose, &pkg_params, &target_options)?;
        if exit_code != 0 {
            ::std::process::exit(exit_code);
        }
        return Ok(());
    }

    if let Some(configure_matches) = global_matches.subcommand_matches("configure") {
        let configure_params = configure_matches
            .values_of("configure_param")
            .map(|x| x.collect())
            .unwrap_or_else(|| vec![]);
        run_configure(
            verbose,
            !configure_matches.is_present("no-host"),
            &configure_params,
            &target_options,
        )?;
        return Ok(());
    }

    if let Some(_write_config_matches) = global_matches.subcommand_matches(WRITE_CONFIG) {
        return write_config(&run_cargo_options, &target_options);
    }

    if let Some(build_rustc_matches) = global_matches.subcommand_matches(BUILD_RUSTC) {
        let rust_root = PathBuf::from(
            build_rustc_matches
                .value_of(RUST_ROOT)
                .expect("rust_root is a required parameter of build-rustc"),
        );
        return build_rustc(&rust_root, &target_options);
    }

    if let Some(make_package_matches) = global_matches.subcommand_matches(MAKE_PACKAGE) {
        let binary_path = PathBuf::from(
            make_package_matches
                .value_of(BINARY_PATH)
                .expect(&format!("{} is a required parameter of {}", BINARY_PATH, MAKE_PACKAGE)),
        );
        let cmx_path = PathBuf::from(
            make_package_matches
                .value_of(CMX_PATH)
                .expect(&format!("{} is a required parameter of {}", CMX_PATH, MAKE_PACKAGE)),
        );
        println!(
            "make package {}",
            make_package(verbose, &target_options, &binary_path, &cmx_path, "app")?
        );
        return Ok(());
    }

    if let Some(fmt_matches) = global_matches.subcommand_matches(FORMAT) {
        let manifest_path = convert_manifest_path(&fmt_matches.value_of(MANIFEST_PATH));
        format_project(manifest_path)?;
        return Ok(());
    }

    Ok(())
}
