///|
fn diff_file_report(
old_path : String,
new_path : String,
) -> Result[@moonguard.ApiReport, String] {
let old_text = read_file_raw(old_path)
if old_text.has_prefix(read_error_prefix) {
let message = old_text[read_error_prefix.length():].to_owned()
return Err(
"error: cannot read old interface file '\{old_path}': \{message}",
)
}
let new_text = read_file_raw(new_path)
if new_text.has_prefix(read_error_prefix) {
let message = new_text[read_error_prefix.length():].to_owned()
return Err(
"error: cannot read new interface file '\{new_path}': \{message}",
)
}
Ok(@moonguard.diff_interfaces(old_text, new_text))
}
///|
fn diff_dir_package_report(
old_dir : String,
new_dir : String,
) -> Result[PackageReportResult, String] {
let old_files = list_interface_files_raw(old_dir)
if old_files.has_prefix(read_error_prefix) {
let message = old_files[read_error_prefix.length():].to_owned()
return Err(
"error: cannot list old interface directory '\{old_dir}': \{message}",
)
}
let new_files = list_interface_files_raw(new_dir)
if new_files.has_prefix(read_error_prefix) {
let message = new_files[read_error_prefix.length():].to_owned()
return Err(
"error: cannot list new interface directory '\{new_dir}': \{message}",
)
}
let old_snapshot = match
read_dir_snapshot(old_dir, parse_file_list(old_files[:]), "old") {
Ok(snapshot) => snapshot
Err(message) => return Err(message)
}
let new_snapshot = match
read_dir_snapshot(new_dir, parse_file_list(new_files[:]), "new") {
Ok(snapshot) => snapshot
Err(message) => return Err(message)
}
let comparison = @moonguard.compare_api_snapshots(old_snapshot, new_snapshot)
Ok({ report: comparison.report, diagnostics: comparison.diagnostics })
}
///|
fn apply_ignore_file(
report : @moonguard.ApiReport,
ignore_file : String,
) -> Result[@moonguard.ApiReport, String] {
if ignore_file.length() == 0 {
return Ok(report)
}
let rules_text = read_file_raw(ignore_file)
if rules_text.has_prefix(read_error_prefix) {
let message = rules_text[read_error_prefix.length():].to_owned()
return Err("error: cannot read ignore file '\{ignore_file}': \{message}")
}
let parsed = @moonguard.parse_ignore_rules(rules_text)
if !parsed.errors.is_empty() {
return Err(render_ignore_errors(ignore_file, parsed.errors))
}
Ok(@moonguard.filter_report_with_rules(report, parsed.rules))
}
///|
fn apply_policy_file(
report : @moonguard.ApiReport,
policy_file : String,
target_version : String,
) -> Result[@moonguard.ApiPolicyEvaluation, String] {
let rules_text = read_file_raw(policy_file)
if rules_text.has_prefix(read_error_prefix) {
let message = rules_text[read_error_prefix.length():].to_owned()
return Err("error: cannot read policy file '\{policy_file}': \{message}")
}
Ok(@moonguard.evaluate_policy_text(report, rules_text, target_version))
}
///|
fn read_dir_snapshot(
root : String,
files : Array[String],
label : String,
) -> Result[@moonguard.ApiSnapshot, String] {
if files.is_empty() {
return Err(
"error: no .mbti files found in \{label} interface directory '\{root}'",
)
}
let api_files : Array[@moonguard.ApiFile] = []
for rel in files {
let path = join_path(root, rel)
let text = read_file_raw(path)
if text.has_prefix(read_error_prefix) {
let message = text[read_error_prefix.length():].to_owned()
return Err(
"error: cannot read \{label} interface file '\{rel}': \{message}",
)
}
api_files.push(@moonguard.api_file(rel, text))
}
Ok(@moonguard.build_api_snapshot(api_files))
}
///|
fn parse_file_list(raw : StringView) -> Array[String] {
let files : Array[String] = []
for line in split_lines(raw) {
let file = line.trim()
if file.length() > 0 {
files.push(file.to_owned())
}
}
files
}
///|
fn join_path(root : String, relative_path : String) -> String {
"\{root}/\{relative_path}"
}