blob: 46b01a74c073f2869b06468ce91f88458d1e5704 [file] [log] [blame]
// Copyright 2020 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.
use {
crate::{
config::{self, OutputFormat, ProgramStateHolder},
Options,
},
anyhow::{Context as _, Error},
triage::{analyze, ActionResults, ActionResultFormatter},
};
/// The entry point for the CLI app.
pub struct App {
options: Options,
}
impl App {
/// Creates a new App with the given options.
pub fn new(options: Options) -> App {
App { options }
}
/// Runs the App.
///
/// This method consumes self and returns a [RunResult] which can be used
/// to examine results. If an error occurs during the running of the app
/// it will be returned as an Error.
pub fn run(self) -> Result<RunResult, Error> {
// TODO(fxb/50449): Use 'argh' crate.
let ProgramStateHolder { parse_result, diagnostic_data, output_format } =
config::initialize(self.options)?;
let action_results = analyze(&diagnostic_data, &parse_result)?;
Ok(RunResult::new(output_format, action_results))
}
}
/// The result of calling App::run.
pub struct RunResult {
output_format: OutputFormat,
action_results: Vec<ActionResults>,
}
impl RunResult {
/// Creates a new RunResult struct. This method is intended to be used by the
/// App:run method.
fn new(output_format: OutputFormat, action_results: Vec<ActionResults>) -> RunResult {
RunResult { output_format, action_results }
}
/// Writes the contents of the run to the provided writer.
///
/// This method can be used to output the results to a file or stdout.
pub fn write_report(&self, dest: &mut dyn std::io::Write) -> Result<(), Error> {
let results_formatter = ActionResultFormatter::new(self.action_results.iter().collect());
let output = match self.output_format {
OutputFormat::Text => results_formatter.to_warnings(),
};
dest.write_fmt(format_args!("{}\n", output)).context("failed to write to destination")?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use {super::*, triage::ActionResults};
macro_rules! make_action_result {
($source:expr, $($action:expr => $r:literal),+) => {
{
let mut result = ActionResults::new($source);
$(
result.set_result($action, $r);
)*
result
}
};
}
#[test]
fn test_output_text_no_warnings() -> Result<(), Error> {
let action_results = vec![make_action_result!("foo", "a" => true)];
let run_result = RunResult::new(OutputFormat::Text, action_results);
let mut dest = vec![];
run_result.write_report(&mut dest)?;
let output = String::from_utf8(dest)?;
assert_eq!("Warnings for foo\n\n", output);
Ok(())
}
#[test]
fn test_output_text_with_warnings() -> Result<(), Error> {
let mut action_result = make_action_result!("foo", "a" => true);
action_result.add_warning("fail".to_string());
let action_results = vec![action_result];
let run_result = RunResult::new(OutputFormat::Text, action_results);
let mut dest = vec![];
run_result.write_report(&mut dest)?;
let output = String::from_utf8(dest)?;
assert_eq!("Warnings for foo\nfail\n\n", output);
Ok(())
}
}