chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
A squash message keeps fold tags in code fenced with tildes
crates/knotless/src/forge.rs+18−5
| @@ -3475,14 +3475,22 @@ pub(crate) async fn squash_commit( | ||
/// A pull's body as its squashed commit says it: without the `<details>` | ||
/// and `<summary>` tags that fold a part of it away on its page, each | ||
/// summary's words kept as a line of their own, and with no more than one | ||
/// blank line in a row where a tag was. Fenced code is left as it is. | ||
/// blank line in a row. Code fenced with backticks or tildes is left as | ||
/// it is. | ||
fn unfolded(body: &str) -> String { | ||
let mut lines: Vec<&str> = Vec::new(); | ||
let mut fenced = false; | ||
// The fence while in fenced code: one of the other kind is code there | ||
// too. | ||
let mut fenced: Option<&str> = None; | ||
for line in body.lines() { | ||
let fence = line.trim_start().starts_with("```"); | ||
let code = fenced || fence; | ||
fenced ^= fence; | ||
let start = line.trim_start(); | ||
let mark = ["```", "~~~"].into_iter().find(|f| start.starts_with(f)); | ||
let code = fenced.is_some() || mark.is_some(); | ||
match (fenced, mark) { | ||
(None, Some(mark)) => fenced = Some(mark), | ||
(Some(open), Some(mark)) if open == mark => fenced = None, | ||
_ => {} | ||
} | ||
let kept = match code { | ||
true => Some(line), | ||
false => fold_line(line.trim()).unwrap_or(Some(line)), | ||
| @@ -3834,6 +3842,11 @@ mod tests { | ||
) | ||
); | ||
assert_eq!(unfolded("<details>\n\n</details>\n"), ""); | ||
// A fence closes only with its own kind. | ||
assert_eq!( | ||
unfolded("~~~\n<details>\n```\n</details>\n~~~\n<details>"), | ||
"~~~\n<details>\n```\n</details>\n~~~" | ||
); | ||
} | ||
| ||
#[test] | ||