Skip to content

Commit 9645164

Browse files
committed
[gobby-cli-#1009] fix: normalize codewiki markdown strictly
1 parent 298dc99 commit 9645164

11 files changed

Lines changed: 887 additions & 54 deletions

File tree

.markdownlint.strict.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"default": true}

crates/gcode/src/commands/codewiki/io.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ impl<'a> DocSink<'a> {
186186
let target = safe_doc_path(self.out_dir, &doc.path)?;
187187
let write_outcome = ai_outcome.for_doc(doc.degraded);
188188
let content = apply_ai_outcome_to_markdown(&doc.content, write_outcome);
189+
let content = if doc.path.ends_with(".md") {
190+
strict_markdown::normalize_codewiki_markdown(&content)
191+
} else {
192+
content
193+
};
189194
let previous_meta = self.previous_docs.get(&doc.path);
190195
if let (Some(since), Some(meta)) = (self.since.as_ref(), previous_meta)
191196
&& doc.invalidation_key.is_none()
@@ -204,10 +209,14 @@ impl<'a> DocSink<'a> {
204209
.chain(meta.neighbor_hashes.keys())
205210
.all(|file| !since.contains(file))
206211
{
212+
let refreshed = refresh_doc_if_needed(self.out_dir, &doc.path, &content)?;
213+
if refreshed {
214+
self.generated_docs.push(doc.path.clone());
215+
}
207216
self.next_docs.insert(doc.path.clone(), meta.clone());
208217
self.seen.insert(doc.path.clone());
209218
self.flush()?;
210-
return Ok(false);
219+
return Ok(refreshed);
211220
}
212221

213222
let source_hashes = source_hashes_for_doc(self.project_root, &content)?;
@@ -280,7 +289,15 @@ impl<'a> DocSink<'a> {
280289
});
281290
let unchanged = unchanged || since_unchanged;
282291

292+
let refreshed = if unchanged {
293+
refresh_doc_if_needed(self.out_dir, &doc.path, &content)?
294+
} else {
295+
false
296+
};
283297
let entry = if unchanged {
298+
if refreshed {
299+
self.generated_docs.push(doc.path.clone());
300+
}
284301
// A skip keeps the previous healthy content on disk, so the meta
285302
// entry keeps the previous summary and stays healthy even when
286303
// this run's generation failed — degraded fallback never displaces
@@ -321,7 +338,7 @@ impl<'a> DocSink<'a> {
321338
self.next_docs.insert(doc.path.clone(), entry);
322339
self.seen.insert(doc.path.clone());
323340
self.flush()?;
324-
Ok(!unchanged)
341+
Ok(!unchanged || refreshed)
325342
}
326343

327344
/// Pages written with a degraded structural fallback this run (#900), in
@@ -627,14 +644,37 @@ pub(crate) fn write_doc(out_dir: &Path, relative_path: &str, content: &str) -> a
627644
.and_then(|extension| extension.to_str())
628645
== Some("md")
629646
{
630-
gobby_core::markdown::normalize_markdown(content)
647+
strict_markdown::normalize_codewiki_markdown(content)
631648
} else {
632649
content.to_string()
633650
};
634651
std::fs::write(target, content)?;
635652
Ok(())
636653
}
637654

655+
fn refresh_doc_if_needed(
656+
out_dir: &Path,
657+
relative_path: &str,
658+
content: &str,
659+
) -> anyhow::Result<bool> {
660+
let target = safe_doc_path(out_dir, relative_path)?;
661+
let existing = match std::fs::read_to_string(&target) {
662+
Ok(existing) => existing,
663+
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(false),
664+
Err(error) => return Err(error.into()),
665+
};
666+
if existing == content {
667+
return Ok(false);
668+
}
669+
if !relative_path.ends_with(".md")
670+
|| strict_markdown::normalize_codewiki_markdown(&existing) != content
671+
{
672+
return Ok(false);
673+
}
674+
write_doc(out_dir, relative_path, content)?;
675+
Ok(true)
676+
}
677+
638678
pub(crate) fn reject_symlinked_doc_path(out_dir: &Path, target: &Path) -> anyhow::Result<()> {
639679
let relative = target.strip_prefix(out_dir)?;
640680
let mut current = out_dir.to_path_buf();

crates/gcode/src/commands/codewiki/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ mod render;
133133
mod repair;
134134
mod reuse;
135135
mod run;
136+
mod strict_markdown;
136137
mod system_model;
137138
mod text;
138139
mod tool_executor;

0 commit comments

Comments
 (0)