use super::{
ExecutionContext, NinjaContent, NinjaToolSpec, generate_ninja, graph, handle_build,
handle_ninja_tool, help, materialize_dyndep_bundle, process, prune_dyndep_bundle,
resolve_output_path,
};
use crate::cli::{BuildArgs, Cli, Commands, HelpArgs, HelpTopic};
use crate::localization::keys;
use crate::result_json;
use anyhow::{Context, Result};
pub(super) fn execute(cli: &Cli, command: Commands, context: &ExecutionContext<'_>) -> Result<()> {
match command {
Commands::Build(args) => execute_build(cli, &args, context),
Commands::Generate { output } => execute_generate(cli, output.as_ref(), context),
Commands::Clean => execute_clean(cli, context),
Commands::Graph(args) => graph::handle_graph(cli, &args, context.reporter),
Commands::Help(args) => execute_help(cli, &args, context.reporter),
}
}
pub(super) fn execute_help(
cli: &Cli,
args: &HelpArgs,
reporter: &dyn crate::status::StatusReporter,
) -> Result<()> {
match args.topic.as_ref() {
None => help::render_root_help(),
Some(HelpTopic::Targets) => help::handle_help_targets(cli, reporter),
Some(HelpTopic::Build) => help::render_subcommand_help("build"),
Some(HelpTopic::Clean) => help::render_subcommand_help("clean"),
Some(HelpTopic::Graph) => help::render_subcommand_help("graph"),
Some(HelpTopic::Generate) => help::render_subcommand_help("generate"),
}
}
fn execute_build(cli: &Cli, args: &BuildArgs, context: &ExecutionContext<'_>) -> Result<()> {
handle_build(cli, args, context)?;
write_json_result(cli, "build", None)
}
fn execute_generate(
cli: &Cli,
output: Option<&std::path::PathBuf>,
context: &ExecutionContext<'_>,
) -> Result<()> {
let bundle = generate_ninja(cli, context.reporter, None)?;
let publication = materialize_dyndep_bundle(cli, &bundle)?;
prune_dyndep_bundle(cli, bundle.dyndep_files(), &publication)?;
let ninja = NinjaContent::new(bundle.into_parts().0);
if let Some(file) = output {
let output_path = resolve_output_path(cli, file.as_path());
process::write_ninja_file(output_path.as_ref(), &ninja)?;
} else if cli.json {
write_json_result(cli, "generate", Some(ninja.as_str()))?;
} else {
process::write_ninja_stdout(&ninja)?;
}
context
.reporter
.report_complete(keys::STATUS_TOOL_GENERATE.into());
let json_result = if output.is_some() {
write_json_result(cli, "generate", None)?;
Ok(())
} else {
Ok(())
};
drop(publication);
json_result
}
fn execute_clean(cli: &Cli, context: &ExecutionContext<'_>) -> Result<()> {
handle_ninja_tool(
cli,
NinjaToolSpec {
name: "clean",
key: keys::STATUS_TOOL_CLEAN.into(),
prune_after_success: true,
},
context,
)?;
write_json_result(cli, "clean", None)
}
fn write_json_result(cli: &Cli, command: &str, content: Option<&str>) -> Result<()> {
if !cli.json {
return Ok(());
}
let rendered = result_json::render_result_json(command, content)
.context("serialize successful command result")?;
process::write_text_stdout(&rendered)
}