perf: avoid duplicated git log calls in loadContent() and postBuild() for untracked Git files (#11211)

Co-authored-by: slorber <749374+slorber@users.noreply.github.com>
This commit is contained in:
Sébastien Lorber 2025-05-28 14:03:10 +02:00 committed by GitHub
parent 68aa3c876b
commit 264774a550
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 160 additions and 21 deletions

View file

@ -14,8 +14,10 @@ import execa from 'execa';
import {
getGitLastUpdate,
LAST_UPDATE_FALLBACK,
LAST_UPDATE_UNTRACKED_GIT_FILEPATH,
readLastUpdateData,
} from '../lastUpdateUtils';
import type {FrontMatterLastUpdate} from '../lastUpdateUtils';
describe('getGitLastUpdate', () => {
const {repoDir} = createTempRepo();
@ -109,6 +111,34 @@ describe('readLastUpdateData', () => {
const testTimestamp = new Date(testDate).getTime();
const testAuthor = 'ozaki';
describe('on untracked Git file', () => {
function test(lastUpdateFrontMatter: FrontMatterLastUpdate | undefined) {
return readLastUpdateData(
LAST_UPDATE_UNTRACKED_GIT_FILEPATH,
{showLastUpdateAuthor: true, showLastUpdateTime: true},
lastUpdateFrontMatter,
);
}
it('reads null at/by from Git', async () => {
const {lastUpdatedAt, lastUpdatedBy} = await test({});
expect(lastUpdatedAt).toBeNull();
expect(lastUpdatedBy).toBeNull();
});
it('reads null at from Git and author from front matter', async () => {
const {lastUpdatedAt, lastUpdatedBy} = await test({author: testAuthor});
expect(lastUpdatedAt).toBeNull();
expect(lastUpdatedBy).toEqual(testAuthor);
});
it('reads null by from Git and date from front matter', async () => {
const {lastUpdatedAt, lastUpdatedBy} = await test({date: testDate});
expect(lastUpdatedBy).toBeNull();
expect(lastUpdatedAt).toEqual(testTimestamp);
});
});
it('read last time show author time', async () => {
const {lastUpdatedAt, lastUpdatedBy} = await readLastUpdateData(
'',

View file

@ -154,12 +154,12 @@ export async function getFileCommitDate(
file,
)}"`;
const result = (await GitCommandQueue.add(() =>
execa(command, {
const result = (await GitCommandQueue.add(() => {
return execa(command, {
cwd: path.dirname(file),
shell: true,
}),
))!;
});
}))!;
if (result.exitCode !== 0) {
throw new Error(

View file

@ -15,10 +15,18 @@ import {
import type {PluginOptions} from '@docusaurus/types';
export type LastUpdateData = {
/** A timestamp in **milliseconds**, usually read from `git log` */
lastUpdatedAt?: number;
/** The author's name, usually coming from `git log` */
lastUpdatedBy?: string;
/**
* A timestamp in **milliseconds**, usually read from `git log`
* `undefined`: not read
* `null`: no value to read (usual for untracked files)
*/
lastUpdatedAt: number | undefined | null;
/**
* The author's name, usually coming from `git log`
* `undefined`: not read
* `null`: no value to read (usual for untracked files)
*/
lastUpdatedBy: string | undefined | null;
};
let showedGitRequirementError = false;
@ -68,9 +76,15 @@ export const LAST_UPDATE_FALLBACK: LastUpdateData = {
lastUpdatedBy: 'Author',
};
// Not proud of this, but convenient for tests :/
export const LAST_UPDATE_UNTRACKED_GIT_FILEPATH = `file/path/${Math.random()}.mdx`;
export async function getLastUpdate(
filePath: string,
): Promise<LastUpdateData | null> {
if (filePath === LAST_UPDATE_UNTRACKED_GIT_FILEPATH) {
return null;
}
if (
process.env.NODE_ENV !== 'production' ||
process.env.DOCUSAURUS_DISABLE_LAST_UPDATE === 'true'
@ -103,7 +117,7 @@ export async function readLastUpdateData(
const {showLastUpdateAuthor, showLastUpdateTime} = options;
if (!showLastUpdateAuthor && !showLastUpdateTime) {
return {};
return {lastUpdatedBy: undefined, lastUpdatedAt: undefined};
}
const frontMatterAuthor = lastUpdateFrontMatter?.author;
@ -116,9 +130,21 @@ export async function readLastUpdateData(
// If all the data is provided as front matter, we do not call it
const getLastUpdateMemoized = _.memoize(() => getLastUpdate(filePath));
const getLastUpdateBy = () =>
getLastUpdateMemoized().then((update) => update?.lastUpdatedBy);
getLastUpdateMemoized().then((update) => {
// Important, see https://github.com/facebook/docusaurus/pull/11211
if (update === null) {
return null;
}
return update?.lastUpdatedBy;
});
const getLastUpdateAt = () =>
getLastUpdateMemoized().then((update) => update?.lastUpdatedAt);
getLastUpdateMemoized().then((update) => {
// Important, see https://github.com/facebook/docusaurus/pull/11211
if (update === null) {
return null;
}
return update?.lastUpdatedAt;
});
const lastUpdatedBy = showLastUpdateAuthor
? frontMatterAuthor ?? (await getLastUpdateBy())