in ingester/src/main.rs [128:186]
fn main() -> anyhow::Result<()> {
env_logger::builder()
.filter_level(log::LevelFilter::Warn)
.parse_default_env()
.init();
let mut args = Args::parse();
if args.config_file.is_none() && std::fs::exists(DEFAULT_CONFIG_FILE).unwrap_or_log(false) {
args.config_file = Some(DEFAULT_CONFIG_FILE.into());
}
let toml_config: toml::Table = if let Some(file) = args.config_file {
std::fs::read_to_string(&file)
.map_err(|e| anyhow::Error::from(e))
.and_then(|s| Ok(toml::from_str(&s)?))
.with_context(|| format!("while reading {}", file.display()))?
} else {
Default::default()
};
let mut toml_config: toml::Value = toml_config.into();
let cli_config: toml::Table =
toml::from_str(&args.config.join("\n")).context("while parsing CLI TOML arguments")?;
// Merge configs
toml_merge(&mut toml_config, cli_config.into());
let config: Config = toml_config.try_into()?;
let input = args
.input_file
.map(|path| {
std::fs::File::open(path).map(|f| Box::new(BufReader::new(f)) as Box<dyn BufRead>)
})
.unwrap_or_else(|| Ok(Box::new(std::io::stdin().lock())))?;
let mut output = args
.output_file
.map(|path| std::fs::File::create(path).map(|f| Box::new(f) as Box<dyn Write>))
.unwrap_or_else(|| Ok(Box::new(std::io::stdout())))?;
let ingest = CrashPingIngest::new(config, JsonlReader::new(input), move |ping_info| {
serde_json::to_writer(&mut output, &ping_info)?;
writeln!(&mut output)?;
Ok(())
});
let cancellation_status = ingest.status.clone();
ctrlc::set_handler(move || cancellation_status.cancel())
.expect("failed to set interrupt handler");
let _progress = if args.no_progress {
None
} else {
Progress::new(ingest.status.clone())
};
ingest.run()
}