use crate::{cli_args::CliArgs, coverage::Coverage, coveralls::CoverallsManager, config::Config, env::Env};
use simple_error::SimpleError;
use log::{debug, info, warn};
use clap::Parser;
use std::{
io::{Result, ErrorKind, Error, copy, stdin},
fs::File,
};
pub fn work() -> Result<()> {
let args = CliArgs::parse();
let env = Env::new();
run(args, env)
}
fn run(args: CliArgs, env: Env) -> Result<()> {
let do_send = !args.no_send;
debug!(
"Arguments parsed (send: {do_send}, force git fetch: {})",
args.force_fetch_git_infos
);
let config = {
let config = match Config::load_from_command(&args, &env)? {
Some(v) => Some(v),
None => Config::load_from_environment(&env)?,
};
match config {
Some(v) => v.init_parameters(&args),
None => {
return Err(Error::new(ErrorKind::Other, SimpleError::new("No service name found")));
}
}
};
info!("Using service `{}`", config.service.get_name());
let manager = CoverallsManager::new();
let mut coverage = if let Some(input) = &args.input {
info!("Reading coverage report from file `{}`", input.display());
Coverage::from_reader(File::open(input)?)?
} else {
info!("Reading coverage report from standard input");
Coverage::from_reader(stdin())?
};
manager.apply_config(&config, &mut coverage, args.force_fetch_git_infos)?;
config.show(coverage.git());
if let Some(output) = &args.output {
info!("Writing coverage payload to file `{}`", output.display());
let mut reader = coverage.new_reader()?;
let mut file = File::create(output)?;
copy(&mut reader, &mut file)?;
}
if do_send {
manager.send(&coverage)?;
} else {
warn!("Sending is disabled (--no-send): coverage will not be uploaded to Coveralls");
}
debug!("Coverage processing finished");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use std::{fs, process};
#[test]
fn run_dry_run_writes_payload_without_sending() {
let dir = std::env::temp_dir().join(format!("coveralls-work-test-{}", process::id()));
fs::create_dir_all(&dir).expect("create the temporary directory");
let input = dir.join("coverage.json");
let output = dir.join("payload.json");
fs::write(&input, r#"{"source_files":[]}"#).expect("write the coverage fixture");
let token = "secret-token-1234567890";
let args = CliArgs::try_parse_from([
"coveralls",
"--no-send",
"--output",
output.to_str().unwrap(),
input.to_str().unwrap(),
"circleci",
"--repo-token",
token,
])
.expect("parse the command line arguments");
let result = run(args, Env::new());
let payload = fs::read_to_string(&output);
fs::remove_dir_all(&dir).ok();
result.expect("the dry-run workflow should succeed");
let json: serde_json::Value =
serde_json::from_str(&payload.expect("the payload should have been written")).expect("a valid JSON payload");
assert_eq!(json["service_name"], "circleci");
assert_eq!(json["repo_token"], token);
}
}