mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-11 08:07:26 +02:00
92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
import path from 'path';
|
|
import shell from 'shelljs';
|
|
|
|
export class GitNotFoundError extends Error {}
|
|
|
|
export const getFileCommitDate = (
|
|
file: string,
|
|
{
|
|
age = 'oldest',
|
|
includeAuthor = false,
|
|
}: {
|
|
age?: 'oldest' | 'newest';
|
|
includeAuthor?: boolean;
|
|
},
|
|
): {
|
|
date: Date;
|
|
timestamp: number;
|
|
author?: string;
|
|
} => {
|
|
if (!shell.which('git')) {
|
|
throw new GitNotFoundError(
|
|
`Failed to retrieve git history for "${file}" because git is not installed.`,
|
|
);
|
|
}
|
|
|
|
if (!shell.test('-f', file)) {
|
|
throw new Error(
|
|
`Failed to retrieve git history for "${file}" because the file does not exist.`,
|
|
);
|
|
}
|
|
|
|
const fileBasename = path.basename(file);
|
|
const fileDirname = path.dirname(file);
|
|
|
|
let formatArg = '--format=%ct';
|
|
if (includeAuthor) {
|
|
formatArg += ',%an';
|
|
}
|
|
|
|
let extraArgs = '--max-count=1';
|
|
if (age === 'oldest') {
|
|
// --follow is necessary to follow file renames
|
|
// --diff-filter=A ensures we only get the commit which (A)dded the file
|
|
extraArgs += ' --follow --diff-filter=A';
|
|
}
|
|
|
|
const result = shell.exec(
|
|
`git log ${extraArgs} ${formatArg} -- "${fileBasename}"`,
|
|
{
|
|
// cwd is important, see: https://github.com/facebook/docusaurus/pull/5048
|
|
cwd: fileDirname,
|
|
silent: true,
|
|
},
|
|
);
|
|
if (result.code !== 0) {
|
|
throw new Error(
|
|
`Failed to retrieve the git history for file "${file}" with exit code ${result.code}: ${result.stderr}`,
|
|
);
|
|
}
|
|
let regex = /^(?<timestamp>\d+)$/;
|
|
if (includeAuthor) {
|
|
regex = /^(?<timestamp>\d+),(?<author>.+)$/;
|
|
}
|
|
|
|
const output = result.stdout.trim();
|
|
const match = output.match(regex);
|
|
|
|
if (
|
|
!match ||
|
|
!match.groups ||
|
|
!match.groups.timestamp ||
|
|
(includeAuthor && !match.groups.author)
|
|
) {
|
|
throw new Error(
|
|
`Failed to retrieve the git history for file "${file}" with unexpected output: ${output}`,
|
|
);
|
|
}
|
|
|
|
const timestamp = Number(match.groups.timestamp);
|
|
const date = new Date(timestamp * 1000);
|
|
|
|
if (includeAuthor) {
|
|
return {date, timestamp, author: match.groups.author};
|
|
}
|
|
return {date, timestamp};
|
|
};
|