use difflore_core::export::ExportRule;
pub(crate) static OPEN_CODE_REVIEW: super::Emitter = super::Emitter {
format: "open-code-review",
file_name: ".opencodereview/rule.json",
engine: None,
kind: super::EmitterKind::OwnedJson,
};
pub(crate) fn render_ocr_rules(rules: &[ExportRule]) -> String {
let mut entries = Vec::new();
for rule in rules {
let fallback_globs;
let globs = if rule.file_patterns.is_empty() {
fallback_globs = vec!["**/*".to_owned()];
&fallback_globs
} else {
&rule.file_patterns
};
let text = format!("{}: {}", rule.name, rule.description);
for glob in globs {
entries.push(serde_json::json!({
"path": glob,
"rule": text,
"merge_system_rule": true,
}));
}
}
let value = serde_json::json!({
"_difflore": {
"generator": "difflore",
"version": env!("CARGO_PKG_VERSION"),
"note": "generated by `difflore export --format open-code-review`; manual edits will be overwritten",
},
"rules": entries,
});
serde_json::to_string_pretty(&value).unwrap_or_else(|_| "{}".to_owned())
}
#[cfg(test)]
mod tests {
use super::*;
fn rule(patterns: &[&str], name: &str, description: &str) -> ExportRule {
ExportRule {
id: "rule-id".into(),
name: name.into(),
description: description.into(),
r#type: "pattern".into(),
confidence: 0.9,
origin: "test".into(),
source_kind: "review".into(),
source: "local".into(),
repo_scope: None,
check_prompt: None,
file_patterns: patterns.iter().map(ToString::to_string).collect(),
examples: Vec::new(),
}
}
#[test]
fn renders_ocr_rule_json_with_ownership_marker() {
let json = render_ocr_rules(&[rule(
&["src/**/*.ts", "lib/**/*.ts"],
"No double retries",
"This package handles retries; don't add a second loop.",
)]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["_difflore"]["generator"], "difflore");
let rules = v["rules"].as_array().unwrap();
assert_eq!(rules.len(), 2);
assert_eq!(rules[0]["path"], "src/**/*.ts");
assert_eq!(rules[0]["merge_system_rule"], true);
assert!(
rules[0]["rule"]
.as_str()
.unwrap()
.contains("No double retries")
);
}
#[test]
fn rule_without_patterns_matches_everything() {
let json = render_ocr_rules(&[rule(&[], "t", "c")]);
let v: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(v["rules"][0]["path"], "**/*");
}
}