105 lines
4.0 KiB
JavaScript
105 lines
4.0 KiB
JavaScript
import { getFullLocaleConfig } from '@vuepress/helper';
|
|
import { isPlainObject } from 'vuepress/shared';
|
|
import { path } from 'vuepress/utils';
|
|
import { gitLocaleInfo } from './locales.js';
|
|
import { prepareClientConfigFile } from './prepareClientConfigFile.js';
|
|
import { resolveChangelog } from './resolveChangelog.js';
|
|
import { resolveContributors } from './resolveContributors.js';
|
|
import { PLUGIN_NAME, getCommits, inferGitProvider, injectGitOptions, isGitRepo, } from './utils/index.js';
|
|
/**
|
|
* Git plugin
|
|
*
|
|
* Git 插件
|
|
*
|
|
* @param [options={}] - Plugin options / 插件选项
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* import { gitPlugin } from '@vuepress/plugin-git'
|
|
*
|
|
* export default {
|
|
* plugins: [
|
|
* gitPlugin({
|
|
* createdTime: true,
|
|
* updatedTime: true,
|
|
* contributors: true,
|
|
* changelog: false
|
|
* })
|
|
* ]
|
|
* }
|
|
* ```
|
|
*/
|
|
export const gitPlugin = ({ createdTime = true, updatedTime = true, contributors = true, changelog = false, filter,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
transformContributors, locales = {}, } = {}) => (app) => {
|
|
const cwd = app.dir.source();
|
|
const isGitRepoValid = isGitRepo(cwd);
|
|
const gitProvider = isGitRepoValid ? inferGitProvider(cwd) : null;
|
|
return {
|
|
name: PLUGIN_NAME,
|
|
define: {
|
|
__GIT_CHANGELOG__: Boolean(changelog),
|
|
__GIT_CONTRIBUTORS__: Boolean(contributors),
|
|
__GIT_LOCALES__: getFullLocaleConfig({
|
|
app,
|
|
name: PLUGIN_NAME,
|
|
default: gitLocaleInfo,
|
|
config: locales,
|
|
}),
|
|
__GIT_OPTIONS__: injectGitOptions(gitProvider, changelog),
|
|
},
|
|
extendsPage: async (page) => {
|
|
page.data.git = {};
|
|
if (!isGitRepoValid || page.filePathRelative === null) {
|
|
return;
|
|
}
|
|
if (filter && !filter(page))
|
|
return;
|
|
const { frontmatter } = page;
|
|
// skip if all features are disabled
|
|
if (!(frontmatter.contributors ?? contributors) &&
|
|
!(frontmatter.changelog ?? changelog) &&
|
|
!createdTime &&
|
|
!updatedTime) {
|
|
return;
|
|
}
|
|
const filePaths = [
|
|
page.filePathRelative,
|
|
...(page.frontmatter.gitInclude ?? []).map((item) => path.join(page.filePathRelative, '..', item)),
|
|
];
|
|
const commits = await getCommits(filePaths, cwd, {
|
|
contributors: (frontmatter.contributors ?? contributors) !== false,
|
|
changelog: frontmatter.changelog ?? changelog,
|
|
});
|
|
if (commits.length === 0)
|
|
return;
|
|
if (createdTime) {
|
|
page.data.git.createdTime = commits[commits.length - 1].time;
|
|
}
|
|
if (updatedTime) {
|
|
page.data.git.updatedTime = commits[0].time;
|
|
}
|
|
const contributorsOptions = isPlainObject(contributors)
|
|
? contributors
|
|
: {};
|
|
if (frontmatter.contributors ?? contributors) {
|
|
contributorsOptions.transform ??= transformContributors;
|
|
page.data.git.contributors = resolveContributors(commits, gitProvider, contributorsOptions, Array.isArray(frontmatter.contributors)
|
|
? frontmatter.contributors
|
|
: []);
|
|
}
|
|
if (frontmatter.changelog ?? changelog) {
|
|
const changelogOptions = isPlainObject(changelog) ? changelog : {};
|
|
page.data.git.changelog = resolveChangelog(app, commits, changelogOptions, contributorsOptions.info ?? []);
|
|
}
|
|
},
|
|
// remove `gitInclude` from frontmatter
|
|
onInitialized: () => {
|
|
app.pages.forEach((page) => {
|
|
delete page.frontmatter.gitInclude;
|
|
});
|
|
},
|
|
clientConfigFile: () => prepareClientConfigFile(app, { changelog, contributors }),
|
|
};
|
|
};
|