multiversx_sc_meta/cmd/code_report/
generate_report.rsuse std::{
fs::{read_dir, File},
io::{BufReader, Write},
path::{Path, PathBuf},
};
use crate::{
cli::{CompareArgs, CompileArgs, ConvertArgs},
folder_structure::RelevantDirectories,
};
use multiversx_sc_meta_lib::{
self, code_report_json::CodeReportJson, mxsc_file_json::MxscFileJson,
};
use super::render_code_report::CodeReportRender;
const JSON: &str = ".json";
const MD: &str = ".md";
pub fn compare_report(compare_args: &CompareArgs) {
if !is_path_ends_with(&compare_args.output, MD) {
panic!("Compare output is only available for Markdown file extension.");
}
if !is_path_ends_with(&compare_args.baseline, JSON)
&& !is_path_ends_with(&compare_args.new, JSON)
{
panic!("Compare baseline and new are only available for JSON file extension.");
}
let mut output_file = create_file(&compare_args.output);
let baseline_reports: Vec<CodeReportJson> = match File::open(&compare_args.baseline) {
Ok(_) => extract_reports_from_json(&compare_args.baseline),
Err(_) => vec![],
};
let new_reports: Vec<CodeReportJson> = extract_reports_from_json(&compare_args.new);
let mut render_code_report =
CodeReportRender::new(&mut output_file, &baseline_reports, &new_reports);
render_code_report.compare_reports();
}
pub fn convert_report(convert_args: &ConvertArgs) {
if !is_path_ends_with(&convert_args.output, MD) {
panic!("Conversion output is only available for Markdown file extension");
}
if !is_path_ends_with(&convert_args.input, JSON) {
panic!("Conversion only available from JSON file extension");
}
let mut output_file = create_file(&convert_args.output);
let reports: Vec<CodeReportJson> = extract_reports_from_json(&convert_args.input);
let mut convert_code_report = CodeReportRender::new_without_compare(&mut output_file, &reports);
convert_code_report.render_report();
}
pub fn create_report(compile_args: &CompileArgs) {
if !is_path_ends_with(&compile_args.output, JSON)
&& !is_path_ends_with(&compile_args.output, MD)
{
panic!("Create report is only available for Markdown or JSON output file.")
}
let reports = generate_new_report(&compile_args.path);
let mut file = create_file(&compile_args.output);
if is_path_ends_with(&compile_args.output, MD) {
let mut render_code_report = CodeReportRender::new_without_compare(&mut file, &reports);
render_code_report.render_report();
} else {
let json_output = serde_json::to_string(&reports).unwrap();
file.write_all(json_output.as_bytes()).unwrap();
}
}
fn generate_new_report(path: &PathBuf) -> Vec<CodeReportJson> {
let directors = RelevantDirectories::find_all(path, &["".to_owned()]);
assemble_report_vec(directors)
}
fn assemble_report_vec(directors: RelevantDirectories) -> Vec<CodeReportJson> {
let mut reports: Vec<CodeReportJson> = Vec::new();
for director in directors.iter() {
let output_path: PathBuf = director.path.join("output");
collect_reports(&output_path, &mut reports);
sanitize_output_path_from_report(&mut reports);
}
reports
}
fn find_mxsc_files(path: &PathBuf) -> Vec<PathBuf> {
if !path.is_dir() {
return vec![];
}
let mut mxsc_files = Vec::new();
for entry in read_dir(path).unwrap() {
let file_path = entry.unwrap().path();
if file_path.to_str().unwrap().ends_with("-dbg.mxsc.json") {
continue;
}
if file_path.to_str().unwrap().ends_with(".mxsc.json") {
mxsc_files.push(file_path);
}
}
mxsc_files
}
fn collect_reports(path: &PathBuf, reports: &mut Vec<CodeReportJson>) {
for mxsc_path in find_mxsc_files(path) {
let mxsc_file = match File::open(mxsc_path) {
Ok(file) => file,
Err(_) => continue,
};
let data: MxscFileJson = serde_json::from_reader(mxsc_file).unwrap();
reports.push(data.report.code_report);
}
}
fn create_file(file_path: &PathBuf) -> File {
File::create(file_path).expect("could not write report file")
}
fn sanitize_output_path_from_report(reports: &mut [CodeReportJson]) {
reports.iter_mut().for_each(|report| {
report.path = report
.path
.split('/')
.last()
.unwrap_or(&report.path)
.to_string();
})
}
fn is_path_ends_with(path: &Path, extension: &str) -> bool {
path.to_path_buf()
.into_os_string()
.into_string()
.unwrap()
.ends_with(extension)
}
fn extract_reports_from_json(path: &PathBuf) -> Vec<CodeReportJson> {
let file =
File::open(path).unwrap_or_else(|_| panic!("file with path {} not found", path.display()));
let reader = BufReader::new(file);
serde_json::from_reader(reader).unwrap_or_else(|_| vec![])
}