From: Lady Date: Fri, 28 Jul 2023 04:42:33 +0000 (-0700) Subject: Support ranking recent changes by recency X-Git-Tag: 0.1.1~3 X-Git-Url: https://git.ladys.computer/GitWikiWeb/commitdiff_plain/fea8cf6564baf418f6e6035758383154d2813b36?ds=inline;hp=74fb42b4f38c2e7e87495cf999e5382f113476d4 Support ranking recent changes by recency This walks back the latest 5 commits to get the changes there before skipping back a week to get any remaining changes, then formats them all into a proper list. --- diff --git a/build.js b/build.js index da0f783..4f996a3 100644 --- a/build.js +++ b/build.js @@ -143,7 +143,7 @@ const getReferenceFromPath = (path) => /Sources\/([A-Z][0-9A-Za-z]*\/[A-Z][0-9A-Za-z]*)\.djot$/u.exec(path) ?.[1]?.replace?.("/", ":"); -const listOfInternalLinks = (references) => ({ +const listOfInternalLinks = (references, wrapper = ($) => $) => ({ tag: "bullet_list", tight: true, style: "*", @@ -155,7 +155,7 @@ const listOfInternalLinks = (references) => ({ tag: "list_item", children: [{ tag: "para", - children: [{ + children: [wrapper({ tag: "link", attributes: { "data-realm": "internal", @@ -164,13 +164,34 @@ const listOfInternalLinks = (references) => ({ }, reference, children: [], - }], + })], }], }; }, ), }); +const diffReferences = async (hash) => { + const diff = new Deno.Command("git", { + args: [ + "diff-tree", + "-r", + "-z", + "--name-only", + "--no-renames", + "--diff-filter=AM", + hash, + ], + stdout: "piped", + stderr: "piped", + }).spawn(); + const [diffNames] = await Promise.allSettled([ + new Response(diff.stdout).text(), + new Response(diff.stderr).text(), + ]).then(logErrorsAndCollectResults); + return references(diffNames.split("\0")); // returns an iterable +}; + function* references(paths) { for (const path of paths) { const reference = getReferenceFromPath(path); @@ -592,23 +613,42 @@ class GitWikiWebPage { } else { /* do nothing */ } - const diff = new Deno.Command("git", { - args: [ - "diff", - "-z", - "--name-only", - "--no-renames", - "--diff-filter=AM", - commit, - ], - stdout: "piped", - stderr: "piped", - }).spawn(); - const [diffNames] = await Promise.allSettled([ - new Response(diff.stdout).text(), - new Response(diff.stderr).text(), - ]).then(logErrorsAndCollectResults); - return [...references(diffNames.split("\0"))]; + const results = new Array(6); + const seen = new Set(); + let recency = 5; + let current; + do { + const show = new Deno.Command("git", { + args: [ + "show", + "-s", + "--format=%H%x00%cI%x00%cD", + recency ? `HEAD~${5 - recency}` : commit, + ], + stdout: "piped", + stderr: "piped", + }).spawn(); + const [ + [hash, dateTime, humanReadable], + ] = await Promise.allSettled([ + new Response(show.stdout).text().then((rev) => + rev.trim().split("\0") + ), + new Response(show.stderr).text(), + ]).then(logErrorsAndCollectResults); + const refs = []; + current = hash; + for (const ref of (await diffReferences(current))) { + if (seen.has(ref)) { + /* do nothing */ + } else { + refs.push(ref); + seen.add(ref); + } + } + results[recency] = { dateTime, humanReadable, refs }; + } while (recency-- > 0 && current && current != commit); + return results; })(), ...Array.from( pages.keys(), @@ -650,9 +690,39 @@ class GitWikiWebPage { const { content, navigation } = (() => { const navigation = []; if (pageRef == "Special:RecentlyChanged") { - navigation.push( - listOfInternalLinks(recentlyChanged), - ); + navigation.push({ + tag: "bullet_list", + attributes: { class: "recent-changes" }, + tight: true, + style: "*", + children: Array.from(function* () { + for ( + const [index, result] of recentlyChanged + .entries() + ) { + if (result != null) { + const { + dateTime, + humanReadable, + refs, + } = result; + yield* listOfInternalLinks(refs, (link) => ({ + tag: index ? "strong" : "span", + attributes: { "data-recency": `${index}` }, + children: [ + link, + str` `, + rawInline`()`, + ], + })).children; + } else { + /* do nothing */ + } + } + }()).reverse(), + }); } else { isNavigationPage = false; return { content: e.children, navigation }; @@ -668,7 +738,7 @@ class GitWikiWebPage { level: 1, children: [str`${title}`], }, - rawBlock`
`, + rawBlock``, @@ -726,7 +796,8 @@ class GitWikiWebPage { if (attributes["data-realm"] == "internal") { delete e.reference; if (redLinks.has(reference)) { - e.destination = `/Special:NotFound?path=/${reference}`; + e.destination = + `/Special:NotFound?path=/${reference}`; attributes["data-notfound"] = ""; } else { e.destination = `/${reference}`; diff --git a/style.css b/style.css index 1d81fd9..e66d38f 100644 --- a/style.css +++ b/style.css @@ -8,3 +8,9 @@ header.main{ Margin-Block: 0 1REM; Border-Block-End: Thin Solid; Padding-Block: header.main h1{ Margin-Block: 0; Font-Size: XX-Large; Font-Style: Italic } details:Has(>summary:Last-Child){ Display: None } span.sig{ Font-Style: Italic; Font-Weight: Bold } +strong[data-recency="5"]{ Font-Weight: 900 } +strong[data-recency="4"]{ Font-Weight: 800 } +strong[data-recency="3"]{ Font-Weight: 700 } +strong[data-recency="2"]{ Font-Weight: 600 } +strong[data-recency="1"]{ Font-Weight: 500 } +strong[data-recency] time{ Font-Style: Italic }