mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-02 08:19:07 +02:00
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:
parent
68aa3c876b
commit
264774a550
10 changed files with 160 additions and 21 deletions
|
@ -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(
|
||||
'',
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue