Skip to content

Commit 8cf0f43

Browse files
authored
fix: optimize directory metadata generation (#8404)
1 parent 97a0585 commit 8cf0f43

File tree

3 files changed

+67
-82
lines changed

3 files changed

+67
-82
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
"eslint-plugin-next": "^0.0.0",
5757
"eslint-plugin-prettier": "^5.0.1",
5858
"fs-extra": "^9.0.1",
59-
"git-jiggy": "1.1.1",
6059
"husky": "^8.0.1",
6160
"jest": "^29.7.0",
6261
"jest-cli": "^29.7.0",

src/directory/generateDirectory.mjs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,80 @@ import { promises as fs } from 'fs';
22
import { fileURLToPath } from 'url';
33
import { cwd } from 'node:process';
44
import path from 'path';
5+
import { execFile } from 'child_process';
6+
import { promisify } from 'util';
57
import JSON5 from 'json5';
68
import { directory } from './directory.mjs';
79
import { writeFile } from 'fs/promises';
8-
import { getLastModifiedDate } from 'git-jiggy';
910
import { API_CATEGORIES, API_SUB_CATEGORIES } from '../data/api-categories.mjs';
1011

12+
const execFileAsync = promisify(execFile);
13+
1114
// Set up the root path so that we can get the correct path from the current working directory
1215
const rootPath = path.resolve(cwd(), 'src/pages');
1316

17+
let gitDatesCache;
18+
19+
/**
20+
* Initializes and caches Git last-modified dates for files under `rootPath`.
21+
* Executes:
22+
* git log --follow --name-only --pretty=format:%ct -- .
23+
* The output is a sequence of lines like:
24+
* 1625030400
25+
* src/pages/index.js
26+
* src/pages/about.js
27+
*
28+
* Parses lines of Unix timestamps and file paths, mapping each file to the ISO date
29+
* of its most recent commit. Caches the result to avoid repeated Git invocations.
30+
*/
31+
async function initializeGitCache() {
32+
if (gitDatesCache) return gitDatesCache;
33+
34+
try {
35+
const { stdout } = await execFileAsync(
36+
'git',
37+
['log', '--follow', '--name-only', '--pretty=format:%ct', '--', '.'],
38+
{ cwd: rootPath, maxBuffer: 50 * 1024 * 1024, timeout: 30000 }
39+
);
40+
41+
const cache = new Map();
42+
let currentDate;
43+
44+
for (const line of stdout.trim().split('\n')) {
45+
if (/^\d+$/.test(line)) {
46+
currentDate = new Date(Number(line) * 1000).toISOString();
47+
} else if (line && !cache.has(line)) {
48+
cache.set(line, currentDate);
49+
}
50+
}
51+
52+
gitDatesCache = cache;
53+
} catch (err) {
54+
console.warn(`Git operation failed: ${err.message}`);
55+
gitDatesCache = new Map();
56+
}
57+
58+
return gitDatesCache;
59+
}
60+
61+
/**
62+
* Retrieves the last modified date for a given file by looking it up
63+
* in the cached Git dates map. Initializes the cache on first invocation.
64+
*
65+
* @param {string} filePath - Absolute path to the target file.
66+
* @returns {Promise<string>} ISO 8601 date string of the last Git commit touching that file.
67+
* @throws {Error} If no Git date is found for the given file.
68+
*/
69+
async function getLastModifiedDate(filePath) {
70+
const cache = await initializeGitCache();
71+
72+
if (!cache.has(filePath)) {
73+
throw new Error(`Git date not found for: ${filePath}`);
74+
}
75+
76+
return cache.get(filePath);
77+
}
78+
1479
/**
1580
* Helper function to use RegEx to grab the "meta" object
1681
* @param {string} filePath

yarn.lock

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,13 +3598,6 @@ __metadata:
35983598
languageName: node
35993599
linkType: hard
36003600

3601-
"@sindresorhus/is@npm:0.15.0":
3602-
version: 0.15.0
3603-
resolution: "@sindresorhus/is@npm:0.15.0"
3604-
checksum: 10c0/1d7dba430c13dd2e1a977d9191e0137a131dd83e7166fb1b69378e6627b5baef267d09ed11e5753b24c8e852ad5cdbcab9573b1c9a4bdc2992a1b06aa872517e
3605-
languageName: node
3606-
linkType: hard
3607-
36083601
"@sinonjs/commons@npm:^3.0.0":
36093602
version: 3.0.1
36103603
resolution: "@sinonjs/commons@npm:3.0.1"
@@ -6890,7 +6883,6 @@ __metadata:
68906883
eslint-plugin-next: "npm:^0.0.0"
68916884
eslint-plugin-prettier: "npm:^5.0.1"
68926885
fs-extra: "npm:^9.0.1"
6893-
git-jiggy: "npm:1.1.1"
68946886
husky: "npm:^8.0.1"
68956887
jest: "npm:^29.7.0"
68966888
jest-cli: "npm:^29.7.0"
@@ -7808,21 +7800,6 @@ __metadata:
78087800
languageName: node
78097801
linkType: hard
78107802

7811-
"execa@npm:1.0.0":
7812-
version: 1.0.0
7813-
resolution: "execa@npm:1.0.0"
7814-
dependencies:
7815-
cross-spawn: "npm:^6.0.0"
7816-
get-stream: "npm:^4.0.0"
7817-
is-stream: "npm:^1.1.0"
7818-
npm-run-path: "npm:^2.0.0"
7819-
p-finally: "npm:^1.0.0"
7820-
signal-exit: "npm:^3.0.0"
7821-
strip-eof: "npm:^1.0.0"
7822-
checksum: 10c0/cc71707c9aa4a2552346893ee63198bf70a04b5a1bc4f8a0ef40f1d03c319eae80932c59191f037990d7d102193e83a38ec72115fff814ec2fb3099f3661a590
7823-
languageName: node
7824-
linkType: hard
7825-
78267803
"execa@npm:^5.0.0, execa@npm:^5.1.1":
78277804
version: 5.1.1
78287805
resolution: "execa@npm:5.1.1"
@@ -8447,15 +8424,6 @@ __metadata:
84478424
languageName: node
84488425
linkType: hard
84498426

8450-
"get-stream@npm:^4.0.0":
8451-
version: 4.1.0
8452-
resolution: "get-stream@npm:4.1.0"
8453-
dependencies:
8454-
pump: "npm:^3.0.0"
8455-
checksum: 10c0/294d876f667694a5ca23f0ca2156de67da950433b6fb53024833733975d32582896dbc7f257842d331809979efccf04d5e0b6b75ad4d45744c45f193fd497539
8456-
languageName: node
8457-
linkType: hard
8458-
84598427
"get-stream@npm:^5.1.0":
84608428
version: 5.2.0
84618429
resolution: "get-stream@npm:5.2.0"
@@ -8511,16 +8479,6 @@ __metadata:
85118479
languageName: node
85128480
linkType: hard
85138481

8514-
"git-jiggy@npm:1.1.1":
8515-
version: 1.1.1
8516-
resolution: "git-jiggy@npm:1.1.1"
8517-
dependencies:
8518-
"@sindresorhus/is": "npm:0.15.0"
8519-
execa: "npm:1.0.0"
8520-
checksum: 10c0/1b5e963555967548bc73c0c9bdfb0d204a7ce926865eca69b69115a28a2b0a1a959b1ea21eb32519ee79c7e71c71ab1edd4dfb70322068882cecbfd2cac9d6f7
8521-
languageName: node
8522-
linkType: hard
8523-
85248482
"github-slugger@npm:^2.0.0":
85258483
version: 2.0.0
85268484
resolution: "github-slugger@npm:2.0.0"
@@ -9590,13 +9548,6 @@ __metadata:
95909548
languageName: node
95919549
linkType: hard
95929550

9593-
"is-stream@npm:^1.1.0":
9594-
version: 1.1.0
9595-
resolution: "is-stream@npm:1.1.0"
9596-
checksum: 10c0/b8ae7971e78d2e8488d15f804229c6eed7ed36a28f8807a1815938771f4adff0e705218b7dab968270433f67103e4fef98062a0beea55d64835f705ee72c7002
9597-
languageName: node
9598-
linkType: hard
9599-
96009551
"is-stream@npm:^2.0.0":
96019552
version: 2.0.1
96029553
resolution: "is-stream@npm:2.0.1"
@@ -12300,15 +12251,6 @@ __metadata:
1230012251
languageName: node
1230112252
linkType: hard
1230212253

12303-
"npm-run-path@npm:^2.0.0":
12304-
version: 2.0.2
12305-
resolution: "npm-run-path@npm:2.0.2"
12306-
dependencies:
12307-
path-key: "npm:^2.0.0"
12308-
checksum: 10c0/95549a477886f48346568c97b08c4fda9cdbf7ce8a4fbc2213f36896d0d19249e32d68d7451bdcbca8041b5fba04a6b2c4a618beaf19849505c05b700740f1de
12309-
languageName: node
12310-
linkType: hard
12311-
1231212254
"npm-run-path@npm:^4.0.1":
1231312255
version: 4.0.1
1231412256
resolution: "npm-run-path@npm:4.0.1"
@@ -12549,13 +12491,6 @@ __metadata:
1254912491
languageName: node
1255012492
linkType: hard
1255112493

12552-
"p-finally@npm:^1.0.0":
12553-
version: 1.0.0
12554-
resolution: "p-finally@npm:1.0.0"
12555-
checksum: 10c0/6b8552339a71fe7bd424d01d8451eea92d379a711fc62f6b2fe64cad8a472c7259a236c9a22b4733abca0b5666ad503cb497792a0478c5af31ded793d00937e7
12556-
languageName: node
12557-
linkType: hard
12558-
1255912494
"p-limit@npm:^2.2.0":
1256012495
version: 2.3.0
1256112496
resolution: "p-limit@npm:2.3.0"
@@ -12758,13 +12693,6 @@ __metadata:
1275812693
languageName: node
1275912694
linkType: hard
1276012695

12761-
"path-key@npm:^2.0.0":
12762-
version: 2.0.1
12763-
resolution: "path-key@npm:2.0.1"
12764-
checksum: 10c0/dd2044f029a8e58ac31d2bf34c34b93c3095c1481942960e84dd2faa95bbb71b9b762a106aead0646695330936414b31ca0bd862bf488a937ad17c8c5d73b32b
12765-
languageName: node
12766-
linkType: hard
12767-
1276812696
"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
1276912697
version: 3.1.1
1277012698
resolution: "path-key@npm:3.1.1"
@@ -13989,7 +13917,7 @@ __metadata:
1398913917
languageName: node
1399013918
linkType: hard
1399113919

13992-
"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
13920+
"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
1399313921
version: 3.0.7
1399413922
resolution: "signal-exit@npm:3.0.7"
1399513923
checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912
@@ -14441,13 +14369,6 @@ __metadata:
1444114369
languageName: node
1444214370
linkType: hard
1444314371

14444-
"strip-eof@npm:^1.0.0":
14445-
version: 1.0.0
14446-
resolution: "strip-eof@npm:1.0.0"
14447-
checksum: 10c0/f336beed8622f7c1dd02f2cbd8422da9208fae81daf184f73656332899978919d5c0ca84dc6cfc49ad1fc4dd7badcde5412a063cf4e0d7f8ed95a13a63f68f45
14448-
languageName: node
14449-
linkType: hard
14450-
1445114372
"strip-final-newline@npm:^2.0.0":
1445214373
version: 2.0.0
1445314374
resolution: "strip-final-newline@npm:2.0.0"

0 commit comments

Comments
 (0)