From 0af094770c4ebabc56ff761a8bd215bc397c0f7e Mon Sep 17 00:00:00 2001 From: João Augusto Costa Branco Marado Torres Date: Tue, 5 Aug 2025 18:50:37 +0100 Subject: refactor: reading page review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: João Augusto Costa Branco Marado Torres --- src/lib/git/log.ts | 162 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 99 insertions(+), 63 deletions(-) (limited to 'src/lib/git') diff --git a/src/lib/git/log.ts b/src/lib/git/log.ts index bcf6888..4545f17 100644 --- a/src/lib/git/log.ts +++ b/src/lib/git/log.ts @@ -1,4 +1,4 @@ -import { defined } from "../../utils/anonymous.ts"; +import { defined, get } from "../../utils/anonymous.ts"; import { type MaybeIterable, surelyIterable } from "../../utils/iterator.ts"; import { gitDir } from "./index.ts"; import type { Commit, CommitFile } from "./types.ts"; @@ -23,72 +23,86 @@ export async function getLastCommitForOneOfFiles( sources: MaybeIterable, ): Promise { const files = surelyIterable(sources); - const gitLog = new Deno.Command("git", { - args: [ - "log", - "-1", - `--pretty=format:${format.map((x) => `%${x}`).join("%n")}`, - "--", - // deno-lint-ignore no-undef - ...Iterator.from(files).map((x) => x.pathname), - ], - }); + const gitLogs = (await Promise.all( + Iterator.from(files).map(async ({ pathname }) => { + const gitLog = new Deno.Command("git", { + args: [ + "log", + "--follow", + "-1", + `--pretty=format:${format.map((x) => `%${x}`).join("%n")}`, + "--", + pathname, + ], + }); + const { stdout } = await gitLog.output(); + const result = new TextDecoder().decode(stdout).trim(); - const { stdout } = await gitLog.output(); - const result = new TextDecoder().decode(stdout).trim(); + if (result.length <= 0) { + return undefined; + } - if (result.length <= 0) { - return undefined; - } + const [ + hash, + abbrHash, + authorDate, + authorName, + authorEmail, + committerDate, + committerName, + committerEmail, + // signatureValidation, + signer, + key, + keyFingerPrint, + ...rawLines + ] = result.split("\n"); - const [ - hash, - abbrHash, - authorDate, - authorName, - authorEmail, - committerDate, - committerName, - committerEmail, - // signatureValidation, - signer, - key, - keyFingerPrint, - ...rawLines - ] = result.split("\n"); - - const raw = rawLines.join("\n").trim(); - - const commit: Commit = { - // deno-lint-ignore no-undef - files: await fileStatusFromCommit(hash, Iterator.from(files)), - hash: { long: hash, short: abbrHash }, - author: { - date: new Date(authorDate), - name: authorName, - email: authorEmail, - }, - committer: { - date: new Date(committerDate), - name: committerName, - email: committerEmail, - }, - }; - - if (raw.length > 0) { - commit.signature = { - type: raw.startsWith("gpgsm:") - ? "x509" - : raw.startsWith("gpg:") - ? "gpg" - : "ssh", - signer, - key: { long: keyFingerPrint, short: key }, - rawMessage: raw, - }; - } + const raw = rawLines.join("\n").trim(); + + const commit: Commit = { + // deno-lint-ignore no-undef + files: await fileStatusFromCommit(hash, Iterator.from(files)), + hash: { long: hash, short: abbrHash }, + author: { + date: new Date(authorDate), + name: authorName, + email: authorEmail, + }, + committer: { + date: new Date(committerDate), + name: committerName, + email: committerEmail, + }, + }; + + if (raw.length > 0) { + commit.signature = { + type: raw.startsWith("gpgsm:") + ? "x509" + : raw.startsWith("gpg:") + ? "gpg" + : "ssh", + signer, + key: { long: keyFingerPrint, short: key }, + rawMessage: raw, + }; + } + + return commit; + }), + )).filter(defined); + + const last = gitLogs.sort(({ committer: a }, { committer: b }) => + b.date.getTime() - a.date.getTime() + )?.[0]; + + if (last === undefined) return undefined; - return commit; + const final = gitLogs.filter(({ hash }) => hash.long === last.hash.long); + + last.files = final.flatMap(get("files")); + return last; } async function fileStatusFromCommit( @@ -132,3 +146,25 @@ async function fileStatusFromCommit( return undefined; }).filter(defined); } + +export async function fileCreationCommitDate( + file: URL, +): Promise { + const gitDiffTree = new Deno.Command("git", { + args: [ + "log", + "--follow", + "--diff-filter=A", + "--format=%cI", + "--", + file.pathname, + ], + }); + + const { stdout } = await gitDiffTree.output(); + try { + return new Date(new TextDecoder().decode(stdout).trim()); + } catch { + return undefined; + } +} -- cgit v1.2.3