eleventy-plugin-git-commit-date
Version:
Eleventy plugin to get Git commit time of a file, or a Eleventy collection.
81 lines (68 loc) • 2.1 kB
JavaScript
import { exec as nodeExec } from "node:child_process";
import { promisify } from "node:util";
const exec = promisify(nodeExec);
/**
* Convert Unix Timestamp String to Date object
*
* @param {string} ts Unix Timestamp String
* @returns {Date | undefined}
*/
function timestampToDate(ts) {
const tsInMilliseconds = parseInt(ts, 10) * 1000;
// Paths not commited to Git returns empty timestamps, resulting in NaN.
// So, convert only valid timestamps.
if (!isNaN(tsInMilliseconds)) {
return new Date(tsInMilliseconds);
}
}
/**
* @param {string} str Git log text
* @param {string} [timeStampMarker="TS:"] The time stamp marker. Default is
* `"TS:"`
* @returns {Map<string, date>} Map with file path and date.
*/
function parseGitOutput(str, timeStampMarker = "TS:") {
if (str === undefined) {
return new Map();
}
let currentDate = null;
const lines = str
.split("\n")
// Remove empty lines
.filter(Boolean);
const map = new Map();
for (const line of lines) {
if (line.startsWith(timeStampMarker)) {
currentDate = timestampToDate(line.slice(timeStampMarker.length).trim());
} else if (currentDate) {
// Eleventy inputPath starts with "./"
const filePath = "./" + line;
// Only store first occurence, as first occurence is the latest.
if (!map.has(filePath)) {
map.set(filePath, currentDate);
}
}
}
return map;
}
/**
* Returns a Map of all files in Git repo. The key is file path and value latest
* commit date.
*
* The code is based on Jens' blog post 'Eleventy: How to Work Around the “git
* Last Modified” Performance Bottleneck,'
* https://meiert.com/blog/eleventy-git-last-modified/
*
* @returns {Promise<Map<string, date>>} Map of file paths and date.
*/
export async function getRepoGitCommitDateMap() {
let output;
try {
const { stdout } = await exec("git log --format=TS:%at --name-only");
output = stdout.toString();
} catch (e) {
console.log(e);
throw new Error("Failed to run 'git log'");
}
return parseGitOutput(output);
}