blob: 132f7e592d3ae075598fd018e139f5e0c2e9e80b [file] [log] [blame]
use crate::{
random_story_name, run_binary, run_program_on_target, run_switches_to_mode, FuchsiaConfig,
RunCargoOptions, TargetOptions, DEFAULT_MOD_NAME,
};
use failure::Error;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
enum FargoCommand {
/// Auto build and test in Fuchsia device or emulator
Autotest,
/// Build binary targeting Fuchsia device or emulator
Build,
/// Build rustc targeting Fuchsia
BuildRustc,
/// Run a cargo command for Fuchsia. Use -- to indicate that all following arguments should be
/// passed to cargo.
Cargo,
/// Check binary targeting Fuchsia device or emulator
Check,
/// Run a configure script for the cross compilation environment
Configure,
/// Build a package's documentation
Doc,
/// Enable networking for a running emulator
EnableNetworking,
/// Run cargo fmt using the Fuchsia toolchain
Fmt,
/// List visible Fuchsia devices
ListDevices,
/// Make a Fuchsia package from an unstripped binary
MakePackage,
/// Run pkg-config for the cross compilation environment
PkgConfig,
/// Stop all Fuchsia emulators and start a new one
Restart,
/// Act as as custom runner for Cargo targeting a Fuchsia device
RunOnTarget(RunOnTarget),
/// Run binary on Fuchsia device or emulator
Run(Run),
/// Open a shell on Fuchsia device or emulator
Ssh,
/// Start a Fuchsia emulator
Start,
/// Stop all Fuchsia emulators
Stop,
/// Run unit tests on Fuchsia device or emulator
Test,
/// Write a .cargo/config file to allow cargo to operate correctly for Fuchsia
WriteConfig,
}
#[derive(Debug, StructOpt)]
struct Run {
/// Build artifacts in release mode, with optimizations.
#[structopt(long)]
release: bool,
/// Use run to run the binary.
#[structopt(long)]
run_with_run: bool,
/// Use tiles_ctl add to run the binary.
#[structopt(long)]
run_with_tiles: bool,
/// Use Use sessionctl to run the binary.
#[structopt(long)]
run_with_sessionctl: bool,
/// Name of app as it appears in the manifest file.
#[structopt(long, default_value = "app")]
app_name: String,
/// Name of story to pass to sessionctl.
#[structopt(short = "n", long)]
story_name: Option<String>,
/// Name of mod to pass to sessionctl.
#[structopt(short, long)]
mod_name: Option<String>,
/// Path to sandbox file to use when running.
#[structopt(long)]
cmx_path: Option<PathBuf>,
/// Package to build.
#[structopt(short, long)]
package: Option<String>,
/// Name of the bin target to run.
#[structopt(long)]
bin: Option<String>,
/// Run a specific example from the examples/ dir.
#[structopt(long)]
example: Option<String>,
}
#[derive(Debug, StructOpt)]
struct RunOnTarget {
/// Path to the binary to run.
binary_to_run: String,
/// Use run to run the binary.
#[structopt(long)]
run_with_run: bool,
/// Use tiles_ctl add to run the binary.
#[structopt(long)]
run_with_tiles: bool,
/// Use Use sessionctl to run the binary.
#[structopt(long)]
run_with_sessionctl: bool,
/// Name of app as it appears in the manifest file.
#[structopt(long, default_value = "app")]
app_name: String,
/// Name of story to pass to sessionctl.
#[structopt(short = "n", long)]
story_name: Option<String>,
/// Name of mod to pass to sessionctl.
#[structopt(short, long)]
mod_name: Option<String>,
/// Path to sandbox file to use when running.
#[structopt(long)]
cmx_path: Option<PathBuf>,
/// Additional arguments for the binary.
runner_args: Vec<String>,
#[structopt(long)]
no_capture: bool,
}
#[derive(Debug, StructOpt)]
#[structopt(name = "fargo", about = "Fargo is a prototype Fuchsia-specific wrapper around Cargo.")]
struct FargoOption {
/// Print verbose output while performing commands
#[structopt(short, long)]
verbose: bool,
/// Disable the setting of CC, AR and such environmental variables
#[structopt(long)]
disable_cross_env: bool,
/// Name of device to target, needed if there are multiple devices visible on the network
#[structopt(short = "N", long)]
device_name: Option<String>,
/// Path to Cargo.toml
#[structopt(long, global = true)]
manifest_path: Option<PathBuf>,
#[structopt(subcommand)]
command: FargoCommand,
}
fn to_opt_str(value: &Option<String>) -> Option<&str> {
value.as_ref().map(String::as_str)
}
#[doc(hidden)]
pub fn run2() -> Result<(), Error> {
let opt = FargoOption::from_args();
println!("{:?}", opt);
let verbose = opt.verbose;
let fuchsia_config = FuchsiaConfig::new_from_fx_exec()?;
if verbose {
println!("fuchsia_config = {:#?}", fuchsia_config);
}
let target_options =
TargetOptions::new(&fuchsia_config, opt.device_name.as_ref().map(String::as_str));
let run_cargo_options = RunCargoOptions { verbose, ..RunCargoOptions::default() };
match opt.command {
FargoCommand::Run(run) => {
println!("Want to run {:#?}", run);
let mut params = vec![];
if let Some(package) = run.package.as_ref() {
params.push("--package");
params.push(package);
}
if let Some(bin) = run.bin.as_ref() {
params.push("--bin");
params.push(bin);
}
if let Some(example) = run.example.as_ref() {
params.push("--example");
params.push(example);
}
let run_mode =
run_switches_to_mode(run.run_with_tiles, run.run_with_run, run.run_with_sessionctl);
return run_binary(
&run_cargo_options
.release(run.release)
.run_mode(run_mode)
.story_name(&to_opt_str(&run.story_name))
.mod_name(&to_opt_str(&run.mod_name))
.app_name(&Some(&run.app_name))
.manifest_path(opt.manifest_path)
.cmx_path(run.cmx_path),
&target_options,
&params,
);
}
FargoCommand::RunOnTarget(run_on_target) => {
let run_cargo_options = run_cargo_options.cmx_path(run_on_target.cmx_path);
let run_params = run_on_target.runner_args;
let run_mode = run_switches_to_mode(
run_on_target.run_with_tiles,
run_on_target.run_with_run,
run_on_target.run_with_sessionctl,
);
return run_program_on_target(
&run_on_target.binary_to_run,
verbose,
run_on_target.no_capture,
&fuchsia_config,
&target_options,
run_mode,
&run_cargo_options.cmx_path,
&run_on_target.story_name.unwrap_or(random_story_name()),
&run_on_target.mod_name.unwrap_or(DEFAULT_MOD_NAME.to_string()),
&run_on_target.app_name,
&[],
None,
);
}
_ => println!("command {:#?} not yet implemented", opt.command),
}
Ok(())
}