mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 15:47:23 +02:00
perf: optimize getFileCommitDate, make it async (#9890)
This commit is contained in:
parent
0279c329ad
commit
f159bb2472
5 changed files with 54 additions and 34 deletions
|
@ -437,7 +437,7 @@ describe('blog plugin', () => {
|
||||||
const noDateSource = path.posix.join('@site', PluginPath, 'no date.md');
|
const noDateSource = path.posix.join('@site', PluginPath, 'no date.md');
|
||||||
const noDateSourceFile = path.posix.join(siteDir, PluginPath, 'no date.md');
|
const noDateSourceFile = path.posix.join(siteDir, PluginPath, 'no date.md');
|
||||||
// We know the file exists and we know we have git
|
// We know the file exists and we know we have git
|
||||||
const result = getFileCommitDate(noDateSourceFile, {age: 'oldest'});
|
const result = await getFileCommitDate(noDateSourceFile, {age: 'oldest'});
|
||||||
const noDateSourceTime = result.date;
|
const noDateSourceTime = result.date;
|
||||||
|
|
||||||
expect({
|
expect({
|
||||||
|
|
|
@ -258,10 +258,11 @@ async function processBlogSourceFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = getFileCommitDate(blogSourceAbsolute, {
|
const result = await getFileCommitDate(blogSourceAbsolute, {
|
||||||
age: 'oldest',
|
age: 'oldest',
|
||||||
includeAuthor: false,
|
includeAuthor: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.date;
|
return result.date;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn(err);
|
logger.warn(err);
|
||||||
|
|
|
@ -25,10 +25,11 @@ export async function getFileLastUpdate(
|
||||||
// Wrap in try/catch in case the shell commands fail
|
// Wrap in try/catch in case the shell commands fail
|
||||||
// (e.g. project doesn't use Git, etc).
|
// (e.g. project doesn't use Git, etc).
|
||||||
try {
|
try {
|
||||||
const result = getFileCommitDate(filePath, {
|
const result = await getFileCommitDate(filePath, {
|
||||||
age: 'newest',
|
age: 'newest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {timestamp: result.timestamp, author: result.author};
|
return {timestamp: result.timestamp, author: result.author};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof GitNotFoundError) {
|
if (err instanceof GitNotFoundError) {
|
||||||
|
|
|
@ -47,88 +47,92 @@ function initializeTempRepo() {
|
||||||
describe('getFileCommitDate', () => {
|
describe('getFileCommitDate', () => {
|
||||||
const repoDir = initializeTempRepo();
|
const repoDir = initializeTempRepo();
|
||||||
it('returns earliest commit date', async () => {
|
it('returns earliest commit date', async () => {
|
||||||
expect(getFileCommitDate(path.join(repoDir, 'test.txt'), {})).toEqual({
|
await expect(
|
||||||
|
getFileCommitDate(path.join(repoDir, 'test.txt'), {}),
|
||||||
|
).resolves.toEqual({
|
||||||
date: new Date('2020-06-19'),
|
date: new Date('2020-06-19'),
|
||||||
timestamp: new Date('2020-06-19').getTime() / 1000,
|
timestamp: new Date('2020-06-19').getTime() / 1000,
|
||||||
});
|
});
|
||||||
expect(getFileCommitDate(path.join(repoDir, 'dest.txt'), {})).toEqual({
|
await expect(
|
||||||
|
getFileCommitDate(path.join(repoDir, 'dest.txt'), {}),
|
||||||
|
).resolves.toEqual({
|
||||||
date: new Date('2020-09-13'),
|
date: new Date('2020-09-13'),
|
||||||
timestamp: new Date('2020-09-13').getTime() / 1000,
|
timestamp: new Date('2020-09-13').getTime() / 1000,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('returns latest commit date', async () => {
|
it('returns latest commit date', async () => {
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'test.txt'), {age: 'newest'}),
|
getFileCommitDate(path.join(repoDir, 'test.txt'), {age: 'newest'}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-09-13'),
|
date: new Date('2020-09-13'),
|
||||||
timestamp: new Date('2020-09-13').getTime() / 1000,
|
timestamp: new Date('2020-09-13').getTime() / 1000,
|
||||||
});
|
});
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'dest.txt'), {age: 'newest'}),
|
getFileCommitDate(path.join(repoDir, 'dest.txt'), {age: 'newest'}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-11-13'),
|
date: new Date('2020-11-13'),
|
||||||
timestamp: new Date('2020-11-13').getTime() / 1000,
|
timestamp: new Date('2020-11-13').getTime() / 1000,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('returns latest commit date with author', async () => {
|
it('returns latest commit date with author', async () => {
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'test.txt'), {
|
getFileCommitDate(path.join(repoDir, 'test.txt'), {
|
||||||
age: 'oldest',
|
age: 'oldest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-06-19'),
|
date: new Date('2020-06-19'),
|
||||||
timestamp: new Date('2020-06-19').getTime() / 1000,
|
timestamp: new Date('2020-06-19').getTime() / 1000,
|
||||||
author: 'Caroline',
|
author: 'Caroline',
|
||||||
});
|
});
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'dest.txt'), {
|
getFileCommitDate(path.join(repoDir, 'dest.txt'), {
|
||||||
age: 'oldest',
|
age: 'oldest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-09-13'),
|
date: new Date('2020-09-13'),
|
||||||
timestamp: new Date('2020-09-13').getTime() / 1000,
|
timestamp: new Date('2020-09-13').getTime() / 1000,
|
||||||
author: 'Caroline',
|
author: 'Caroline',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('returns earliest commit date with author', async () => {
|
it('returns earliest commit date with author', async () => {
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'test.txt'), {
|
getFileCommitDate(path.join(repoDir, 'test.txt'), {
|
||||||
age: 'newest',
|
age: 'newest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-09-13'),
|
date: new Date('2020-09-13'),
|
||||||
timestamp: new Date('2020-09-13').getTime() / 1000,
|
timestamp: new Date('2020-09-13').getTime() / 1000,
|
||||||
author: 'Caroline',
|
author: 'Caroline',
|
||||||
});
|
});
|
||||||
expect(
|
await expect(
|
||||||
getFileCommitDate(path.join(repoDir, 'dest.txt'), {
|
getFileCommitDate(path.join(repoDir, 'dest.txt'), {
|
||||||
age: 'newest',
|
age: 'newest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toEqual({
|
).resolves.toEqual({
|
||||||
date: new Date('2020-11-13'),
|
date: new Date('2020-11-13'),
|
||||||
timestamp: new Date('2020-11-13').getTime() / 1000,
|
timestamp: new Date('2020-11-13').getTime() / 1000,
|
||||||
author: 'Josh-Cena',
|
author: 'Josh-Cena',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('throws custom error when file is not tracked', async () => {
|
it('throws custom error when file is not tracked', async () => {
|
||||||
expect(() =>
|
await expect(() =>
|
||||||
getFileCommitDate(path.join(repoDir, 'untracked.txt'), {
|
getFileCommitDate(path.join(repoDir, 'untracked.txt'), {
|
||||||
age: 'newest',
|
age: 'newest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toThrow(FileNotTrackedError);
|
).rejects.toThrow(FileNotTrackedError);
|
||||||
});
|
});
|
||||||
it('throws when file not found', async () => {
|
it('throws when file not found', async () => {
|
||||||
expect(() =>
|
await expect(() =>
|
||||||
getFileCommitDate(path.join(repoDir, 'nonexistent.txt'), {
|
getFileCommitDate(path.join(repoDir, 'nonexistent.txt'), {
|
||||||
age: 'newest',
|
age: 'newest',
|
||||||
includeAuthor: true,
|
includeAuthor: true,
|
||||||
}),
|
}),
|
||||||
).toThrow(
|
).rejects.toThrow(
|
||||||
/Failed to retrieve git history for ".*nonexistent.txt" because the file does not exist./,
|
/Failed to retrieve git history for ".*nonexistent.txt" because the file does not exist./,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,7 +24,7 @@ export class FileNotTrackedError extends Error {}
|
||||||
* @throws Also throws when `git log` exited with non-zero, or when it outputs
|
* @throws Also throws when `git log` exited with non-zero, or when it outputs
|
||||||
* unexpected text.
|
* unexpected text.
|
||||||
*/
|
*/
|
||||||
export function getFileCommitDate(
|
export async function getFileCommitDate(
|
||||||
/** Absolute path to the file. */
|
/** Absolute path to the file. */
|
||||||
file: string,
|
file: string,
|
||||||
args: {
|
args: {
|
||||||
|
@ -36,12 +36,12 @@ export function getFileCommitDate(
|
||||||
/** Use `includeAuthor: true` to get the author information as well. */
|
/** Use `includeAuthor: true` to get the author information as well. */
|
||||||
includeAuthor?: false;
|
includeAuthor?: false;
|
||||||
},
|
},
|
||||||
): {
|
): Promise<{
|
||||||
/** Relevant commit date. */
|
/** Relevant commit date. */
|
||||||
date: Date;
|
date: Date;
|
||||||
/** Timestamp in **seconds**, as returned from git. */
|
/** Timestamp in **seconds**, as returned from git. */
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
};
|
}>;
|
||||||
/**
|
/**
|
||||||
* Fetches the git history of a file and returns a relevant commit date.
|
* Fetches the git history of a file and returns a relevant commit date.
|
||||||
* It gets the commit date instead of author date so that amended commits
|
* It gets the commit date instead of author date so that amended commits
|
||||||
|
@ -52,7 +52,7 @@ export function getFileCommitDate(
|
||||||
* @throws Also throws when `git log` exited with non-zero, or when it outputs
|
* @throws Also throws when `git log` exited with non-zero, or when it outputs
|
||||||
* unexpected text.
|
* unexpected text.
|
||||||
*/
|
*/
|
||||||
export function getFileCommitDate(
|
export async function getFileCommitDate(
|
||||||
/** Absolute path to the file. */
|
/** Absolute path to the file. */
|
||||||
file: string,
|
file: string,
|
||||||
args: {
|
args: {
|
||||||
|
@ -63,15 +63,16 @@ export function getFileCommitDate(
|
||||||
age?: 'oldest' | 'newest';
|
age?: 'oldest' | 'newest';
|
||||||
includeAuthor: true;
|
includeAuthor: true;
|
||||||
},
|
},
|
||||||
): {
|
): Promise<{
|
||||||
/** Relevant commit date. */
|
/** Relevant commit date. */
|
||||||
date: Date;
|
date: Date;
|
||||||
/** Timestamp in **seconds**, as returned from git. */
|
/** Timestamp in **seconds**, as returned from git. */
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
/** The author's name, as returned from git. */
|
/** The author's name, as returned from git. */
|
||||||
author: string;
|
author: string;
|
||||||
};
|
}>;
|
||||||
export function getFileCommitDate(
|
|
||||||
|
export async function getFileCommitDate(
|
||||||
file: string,
|
file: string,
|
||||||
{
|
{
|
||||||
age = 'oldest',
|
age = 'oldest',
|
||||||
|
@ -80,11 +81,11 @@ export function getFileCommitDate(
|
||||||
age?: 'oldest' | 'newest';
|
age?: 'oldest' | 'newest';
|
||||||
includeAuthor?: boolean;
|
includeAuthor?: boolean;
|
||||||
},
|
},
|
||||||
): {
|
): Promise<{
|
||||||
date: Date;
|
date: Date;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
author?: string;
|
author?: string;
|
||||||
} {
|
}> {
|
||||||
if (!shell.which('git')) {
|
if (!shell.which('git')) {
|
||||||
throw new GitNotFoundError(
|
throw new GitNotFoundError(
|
||||||
`Failed to retrieve git history for "${file}" because git is not installed.`,
|
`Failed to retrieve git history for "${file}" because git is not installed.`,
|
||||||
|
@ -105,11 +106,24 @@ export function getFileCommitDate(
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
|
||||||
const result = shell.exec(`git log ${args} -- "${path.basename(file)}"`, {
|
const result = await new Promise<{
|
||||||
// Setting cwd is important, see: https://github.com/facebook/docusaurus/pull/5048
|
code: number;
|
||||||
cwd: path.dirname(file),
|
stdout: string;
|
||||||
silent: true,
|
stderr: string;
|
||||||
|
}>((resolve) => {
|
||||||
|
shell.exec(
|
||||||
|
`git log ${args} -- "${path.basename(file)}"`,
|
||||||
|
{
|
||||||
|
// Setting cwd is important, see: https://github.com/facebook/docusaurus/pull/5048
|
||||||
|
cwd: path.dirname(file),
|
||||||
|
silent: true,
|
||||||
|
},
|
||||||
|
(code, stdout, stderr) => {
|
||||||
|
resolve({code, stdout, stderr});
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Failed to retrieve the git history for file "${file}" with exit code ${result.code}: ${result.stderr}`,
|
`Failed to retrieve the git history for file "${file}" with exit code ${result.code}: ${result.stderr}`,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue