feat(content-docs): make docs:version command work on localized docs (#7106)

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
Joshua Chen 2022-04-08 01:43:24 +08:00 committed by GitHub
parent 0a3aad618e
commit 4134ebb3fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 165 additions and 183 deletions

View file

@ -8,10 +8,7 @@
import {jest} from '@jest/globals'; import {jest} from '@jest/globals';
import path from 'path'; import path from 'path';
import {cliDocsVersionCommand} from '../cli'; import {cliDocsVersionCommand} from '../cli';
import type { import type {PluginOptions} from '@docusaurus/plugin-content-docs';
PathOptions,
SidebarOptions,
} from '@docusaurus/plugin-content-docs';
import fs from 'fs-extra'; import fs from 'fs-extra';
import { import {
getVersionedDocsDirPath, getVersionedDocsDirPath,
@ -26,7 +23,8 @@ describe('docsVersion', () => {
const simpleSiteDir = path.join(fixtureDir, 'simple-site'); const simpleSiteDir = path.join(fixtureDir, 'simple-site');
const versionedSiteDir = path.join(fixtureDir, 'versioned-site'); const versionedSiteDir = path.join(fixtureDir, 'versioned-site');
const DEFAULT_OPTIONS: PathOptions & SidebarOptions = { const DEFAULT_OPTIONS: PluginOptions = {
id: 'default',
path: 'docs', path: 'docs',
sidebarPath: '', sidebarPath: '',
sidebarCollapsed: true, sidebarCollapsed: true,
@ -35,32 +33,19 @@ describe('docsVersion', () => {
it('no version tag provided', async () => { it('no version tag provided', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(null, DEFAULT_OPTIONS, {siteDir: simpleSiteDir}),
null,
simpleSiteDir,
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand(undefined, DEFAULT_OPTIONS, {
undefined, siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('', DEFAULT_OPTIONS, {siteDir: simpleSiteDir}),
'',
simpleSiteDir,
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`, `"[docs]: no version tag specified! Pass the version you wish to create as an argument, for example: 1.0.0."`,
); );
@ -68,22 +53,16 @@ describe('docsVersion', () => {
it('version tag should not have slash', async () => { it('version tag should not have slash', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('foo/bar', DEFAULT_OPTIONS, {
'foo/bar', siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowError( ).rejects.toThrowError(
'[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.', '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.',
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('foo\\bar', DEFAULT_OPTIONS, {
'foo\\bar', siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowError( ).rejects.toThrowError(
'[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.', '[docs]: invalid version tag specified! Do not include slash (/) or backslash (\\). Try something like: 1.0.0.',
); );
@ -91,12 +70,9 @@ describe('docsVersion', () => {
it('version tag should not be too long', async () => { it('version tag should not be too long', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('a'.repeat(255), DEFAULT_OPTIONS, {
'a'.repeat(255), siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Length cannot exceed 32 characters. Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Length cannot exceed 32 characters. Try something like: 1.0.0."`,
); );
@ -104,22 +80,12 @@ describe('docsVersion', () => {
it('version tag should not be a dot or two dots', async () => { it('version tag should not be a dot or two dots', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('..', DEFAULT_OPTIONS, {siteDir: simpleSiteDir}),
'..',
simpleSiteDir,
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`,
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('.', DEFAULT_OPTIONS, {siteDir: simpleSiteDir}),
'.',
simpleSiteDir,
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Do not name your version \\".\\" or \\"..\\". Try something like: 1.0.0."`,
); );
@ -127,32 +93,23 @@ describe('docsVersion', () => {
it('version tag should be a valid pathname', async () => { it('version tag should be a valid pathname', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('<foo|bar>', DEFAULT_OPTIONS, {
'<foo|bar>', siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('foo\x00bar', DEFAULT_OPTIONS, {
'foo\x00bar', siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('foo:bar', DEFAULT_OPTIONS, {
'foo:bar', siteDir: simpleSiteDir,
simpleSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`, `"[docs]: invalid version tag specified! Please ensure its a valid pathname too. Try something like: 1.0.0."`,
); );
@ -160,12 +117,9 @@ describe('docsVersion', () => {
it('version tag already exist', async () => { it('version tag already exist', async () => {
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('1.0.0', DEFAULT_OPTIONS, {
'1.0.0', siteDir: versionedSiteDir,
versionedSiteDir, }),
DEFAULT_PLUGIN_ID,
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: this version already exists! Use a version tag that does not already exist."`, `"[docs]: this version already exists! Use a version tag that does not already exist."`,
); );
@ -174,14 +128,12 @@ describe('docsVersion', () => {
it('no docs file to version', async () => { it('no docs file to version', async () => {
const emptySiteDir = path.join(fixtureDir, 'empty-site'); const emptySiteDir = path.join(fixtureDir, 'empty-site');
await expect(() => await expect(() =>
cliDocsVersionCommand( cliDocsVersionCommand('1.0.0', DEFAULT_OPTIONS, {
'1.0.0', siteDir: emptySiteDir,
emptySiteDir, i18n: {locales: ['en', 'zh-Hans'], defaultLocale: 'en'},
DEFAULT_PLUGIN_ID, }),
DEFAULT_OPTIONS,
),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"[docs]: no docs found in <PROJECT_ROOT>/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/empty-site/docs."`, `"[docs]: no docs found in \\"<PROJECT_ROOT>/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/empty-site/docs\\"."`,
); );
}); });
@ -205,12 +157,10 @@ describe('docsVersion', () => {
...DEFAULT_OPTIONS, ...DEFAULT_OPTIONS,
sidebarPath: path.join(simpleSiteDir, 'sidebars.json'), sidebarPath: path.join(simpleSiteDir, 'sidebars.json'),
}; };
await cliDocsVersionCommand( await cliDocsVersionCommand('1.0.0', options, {
'1.0.0', siteDir: simpleSiteDir,
simpleSiteDir, i18n: {locales: ['en', 'zh-Hans'], defaultLocale: 'en'},
DEFAULT_PLUGIN_ID, });
options,
);
expect(copyMock).toHaveBeenCalledWith( expect(copyMock).toHaveBeenCalledWith(
path.join(simpleSiteDir, options.path), path.join(simpleSiteDir, options.path),
path.join( path.join(
@ -218,6 +168,16 @@ describe('docsVersion', () => {
'version-1.0.0', 'version-1.0.0',
), ),
); );
expect(copyMock).toHaveBeenCalledWith(
path.join(
simpleSiteDir,
'i18n/zh-Hans/docusaurus-plugin-content-docs/current',
),
path.join(
simpleSiteDir,
'i18n/zh-Hans/docusaurus-plugin-content-docs/version-1.0.0',
),
);
expect(versionedSidebar).toMatchSnapshot(); expect(versionedSidebar).toMatchSnapshot();
expect(versionedSidebarPath).toEqual( expect(versionedSidebarPath).toEqual(
path.join( path.join(
@ -256,16 +216,15 @@ describe('docsVersion', () => {
versions = JSON.parse(content as string); versions = JSON.parse(content as string);
}); });
const consoleMock = jest.spyOn(console, 'log').mockImplementation(() => {}); const consoleMock = jest.spyOn(console, 'log').mockImplementation(() => {});
const warnMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
const options = { const options = {
...DEFAULT_OPTIONS, ...DEFAULT_OPTIONS,
sidebarPath: path.join(versionedSiteDir, 'sidebars.json'), sidebarPath: path.join(versionedSiteDir, 'sidebars.json'),
}; };
await cliDocsVersionCommand( await cliDocsVersionCommand('2.0.0', options, {
'2.0.0', siteDir: versionedSiteDir,
versionedSiteDir, i18n: {locales: ['en', 'zh-Hans'], defaultLocale: 'en'},
DEFAULT_PLUGIN_ID, });
options,
);
expect(copyMock).toHaveBeenCalledWith( expect(copyMock).toHaveBeenCalledWith(
path.join(versionedSiteDir, options.path), path.join(versionedSiteDir, options.path),
path.join( path.join(
@ -289,7 +248,11 @@ describe('docsVersion', () => {
/.*\[SUCCESS\].*\[docs\].*: version .*2\.0\.0.* created!.*/, /.*\[SUCCESS\].*\[docs\].*: version .*2\.0\.0.* created!.*/,
), ),
); );
expect(warnMock.mock.calls[0][0]).toMatchInlineSnapshot(
`"[WARNING] [docs]: no docs found in \\"<PROJECT_ROOT>/packages/docusaurus-plugin-content-docs/src/__tests__/__fixtures__/versioned-site/i18n/zh-Hans/docusaurus-plugin-content-docs/current\\". Skipping."`,
);
warnMock.mockRestore();
copyMock.mockRestore(); copyMock.mockRestore();
writeMock.mockRestore(); writeMock.mockRestore();
consoleMock.mockRestore(); consoleMock.mockRestore();
@ -315,10 +278,14 @@ describe('docsVersion', () => {
const consoleMock = jest.spyOn(console, 'log').mockImplementation(() => {}); const consoleMock = jest.spyOn(console, 'log').mockImplementation(() => {});
const options = { const options = {
...DEFAULT_OPTIONS, ...DEFAULT_OPTIONS,
id: pluginId,
path: 'community', path: 'community',
sidebarPath: path.join(versionedSiteDir, 'community_sidebars.json'), sidebarPath: path.join(versionedSiteDir, 'community_sidebars.json'),
}; };
await cliDocsVersionCommand('2.0.0', versionedSiteDir, pluginId, options); await cliDocsVersionCommand('2.0.0', options, {
siteDir: versionedSiteDir,
i18n: {locales: ['en', 'fr'], defaultLocale: 'en'},
});
expect(copyMock).toHaveBeenCalledWith( expect(copyMock).toHaveBeenCalledWith(
path.join(versionedSiteDir, options.path), path.join(versionedSiteDir, options.path),
path.join( path.join(
@ -326,6 +293,16 @@ describe('docsVersion', () => {
'version-2.0.0', 'version-2.0.0',
), ),
); );
expect(copyMock).toHaveBeenCalledWith(
path.join(
versionedSiteDir,
'i18n/fr/docusaurus-plugin-content-docs-community/current',
),
path.join(
versionedSiteDir,
'i18n/fr/docusaurus-plugin-content-docs-community/version-2.0.0',
),
);
expect(versionedSidebar).toMatchSnapshot(); expect(versionedSidebar).toMatchSnapshot();
expect(versionedSidebarPath).toEqual( expect(versionedSidebarPath).toEqual(
path.join( path.join(

View file

@ -16,7 +16,7 @@ import pluginContentDocs from '../index';
import {loadContext} from '@docusaurus/core/src/server/index'; import {loadContext} from '@docusaurus/core/src/server/index';
import {applyConfigureWebpack} from '@docusaurus/core/src/webpack/utils'; import {applyConfigureWebpack} from '@docusaurus/core/src/webpack/utils';
import type {RouteConfig} from '@docusaurus/types'; import type {RouteConfig} from '@docusaurus/types';
import {posixPath, DEFAULT_PLUGIN_ID} from '@docusaurus/utils'; import {posixPath} from '@docusaurus/utils';
import {sortConfig} from '@docusaurus/core/src/server/plugins/routeConfig'; import {sortConfig} from '@docusaurus/core/src/server/plugins/routeConfig';
import * as cliDocs from '../cli'; import * as cliDocs from '../cli';
@ -230,23 +230,21 @@ describe('simple website', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'simple-site'); const siteDir = path.join(__dirname, '__fixtures__', 'simple-site');
const context = await loadContext({siteDir}); const context = await loadContext({siteDir});
const sidebarPath = path.join(siteDir, 'sidebars.json'); const sidebarPath = path.join(siteDir, 'sidebars.json');
const plugin = await pluginContentDocs( const options = validateOptions({
context, validate: normalizePluginOptions,
validateOptions({ options: {
validate: normalizePluginOptions, path: 'docs',
options: { sidebarPath,
path: 'docs', },
sidebarPath, });
}, const plugin = await pluginContentDocs(context, options);
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name); const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
return {siteDir, context, sidebarPath, plugin, pluginContentDir}; return {siteDir, context, sidebarPath, plugin, options, pluginContentDir};
} }
it('extendCli - docsVersion', async () => { it('extendCli - docsVersion', async () => {
const {siteDir, sidebarPath, plugin} = await loadSite(); const {plugin, options, context} = await loadSite();
const mock = jest const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand') .spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation(async () => {}); .mockImplementation(async () => {});
@ -256,12 +254,7 @@ describe('simple website', () => {
plugin.extendCli!(cli); plugin.extendCli!(cli);
cli.parse(['node', 'test', 'docs:version', '1.0.0']); cli.parse(['node', 'test', 'docs:version', '1.0.0']);
expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith('1.0.0', siteDir, DEFAULT_PLUGIN_ID, { expect(mock).toHaveBeenCalledWith('1.0.0', options, context);
path: 'docs',
sidebarPath,
sidebarCollapsed: true,
sidebarCollapsible: true,
});
mock.mockRestore(); mock.mockRestore();
}); });
@ -344,29 +337,28 @@ describe('versioned website', () => {
const context = await loadContext({siteDir}); const context = await loadContext({siteDir});
const sidebarPath = path.join(siteDir, 'sidebars.json'); const sidebarPath = path.join(siteDir, 'sidebars.json');
const routeBasePath = 'docs'; const routeBasePath = 'docs';
const plugin = await pluginContentDocs( const options = validateOptions({
context, validate: normalizePluginOptions,
validateOptions({ options: {
validate: normalizePluginOptions, routeBasePath,
options: { sidebarPath,
routeBasePath, },
sidebarPath, });
}, const plugin = await pluginContentDocs(context, options);
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name); const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
return { return {
siteDir, siteDir,
context, context,
routeBasePath, routeBasePath,
sidebarPath, sidebarPath,
options,
plugin, plugin,
pluginContentDir, pluginContentDir,
}; };
} }
it('extendCli - docsVersion', async () => { it('extendCli - docsVersion', async () => {
const {siteDir, routeBasePath, sidebarPath, plugin} = await loadSite(); const {plugin, context, options} = await loadSite();
const mock = jest const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand') .spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation(async () => {}); .mockImplementation(async () => {});
@ -376,12 +368,7 @@ describe('versioned website', () => {
plugin.extendCli!(cli); plugin.extendCli!(cli);
cli.parse(['node', 'test', 'docs:version', '2.0.0']); cli.parse(['node', 'test', 'docs:version', '2.0.0']);
expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith('2.0.0', siteDir, DEFAULT_PLUGIN_ID, { expect(mock).toHaveBeenCalledWith('2.0.0', options, context);
path: routeBasePath,
sidebarPath,
sidebarCollapsed: true,
sidebarCollapsible: true,
});
mock.mockRestore(); mock.mockRestore();
}); });
@ -474,18 +461,16 @@ describe('versioned website (community)', () => {
const sidebarPath = path.join(siteDir, 'community_sidebars.json'); const sidebarPath = path.join(siteDir, 'community_sidebars.json');
const routeBasePath = 'community'; const routeBasePath = 'community';
const pluginId = 'community'; const pluginId = 'community';
const plugin = await pluginContentDocs( const options = validateOptions({
context, validate: normalizePluginOptions,
validateOptions({ options: {
validate: normalizePluginOptions, id: 'community',
options: { path: 'community',
id: 'community', routeBasePath,
path: 'community', sidebarPath,
routeBasePath, },
sidebarPath, });
}, const plugin = await pluginContentDocs(context, options);
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name); const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
return { return {
siteDir, siteDir,
@ -493,14 +478,14 @@ describe('versioned website (community)', () => {
routeBasePath, routeBasePath,
sidebarPath, sidebarPath,
pluginId, pluginId,
options,
plugin, plugin,
pluginContentDir, pluginContentDir,
}; };
} }
it('extendCli - docsVersion', async () => { it('extendCli - docsVersion', async () => {
const {siteDir, routeBasePath, sidebarPath, pluginId, plugin} = const {pluginId, plugin, options, context} = await loadSite();
await loadSite();
const mock = jest const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand') .spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation(async () => {}); .mockImplementation(async () => {});
@ -510,12 +495,7 @@ describe('versioned website (community)', () => {
plugin.extendCli!(cli); plugin.extendCli!(cli);
cli.parse(['node', 'test', `docs:version:${pluginId}`, '2.0.0']); cli.parse(['node', 'test', `docs:version:${pluginId}`, '2.0.0']);
expect(mock).toHaveBeenCalledTimes(1); expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith('2.0.0', siteDir, pluginId, { expect(mock).toHaveBeenCalledWith('2.0.0', options, context);
path: routeBasePath,
sidebarPath,
sidebarCollapsed: true,
sidebarCollapsible: true,
});
mock.mockRestore(); mock.mockRestore();
}); });

View file

@ -9,16 +9,16 @@ import {
getVersionsFilePath, getVersionsFilePath,
getVersionedDocsDirPath, getVersionedDocsDirPath,
getVersionedSidebarsDirPath, getVersionedSidebarsDirPath,
getDocsDirPathLocalized,
} from './versions'; } from './versions';
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
import type { import type {PluginOptions} from '@docusaurus/plugin-content-docs';
PathOptions,
SidebarOptions,
} from '@docusaurus/plugin-content-docs';
import {loadSidebarsFileUnsafe, resolveSidebarPathOption} from './sidebars'; import {loadSidebarsFileUnsafe, resolveSidebarPathOption} from './sidebars';
import {CURRENT_VERSION_NAME} from './constants';
import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils'; import {DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
import logger from '@docusaurus/logger'; import logger from '@docusaurus/logger';
import type {LoadContext} from '@docusaurus/types';
async function createVersionedSidebarFile({ async function createVersionedSidebarFile({
siteDir, siteDir,
@ -58,9 +58,8 @@ async function createVersionedSidebarFile({
// Tests depend on non-default export for mocking. // Tests depend on non-default export for mocking.
export async function cliDocsVersionCommand( export async function cliDocsVersionCommand(
version: string | null | undefined, version: string | null | undefined,
siteDir: string, {id: pluginId, path: docsPath, sidebarPath}: PluginOptions,
pluginId: string, {siteDir, i18n}: LoadContext,
options: PathOptions & SidebarOptions,
): Promise<void> { ): Promise<void> {
// It wouldn't be very user-friendly to show a [default] log prefix, // It wouldn't be very user-friendly to show a [default] log prefix,
// so we use [docs] instead of [default] // so we use [docs] instead of [default]
@ -114,22 +113,53 @@ export async function cliDocsVersionCommand(
); );
} }
const {path: docsPath, sidebarPath} = options; if (i18n.locales.length > 1) {
logger.info`Versioned docs will be created for the following locales: name=${i18n.locales}`;
// Copy docs files.
const docsDir = path.resolve(siteDir, docsPath);
if (
(await fs.pathExists(docsDir)) &&
(await fs.readdir(docsDir)).length > 0
) {
const versionedDir = getVersionedDocsDirPath(siteDir, pluginId);
const newVersionDir = path.join(versionedDir, `version-${version}`);
await fs.copy(docsDir, newVersionDir);
} else {
throw new Error(`${pluginIdLogPrefix}: no docs found in ${docsDir}.`);
} }
await Promise.all(
i18n.locales.map(async (locale) => {
// Copy docs files.
const docsDir =
locale === i18n.defaultLocale
? path.resolve(siteDir, docsPath)
: getDocsDirPathLocalized({
siteDir,
locale,
pluginId,
versionName: CURRENT_VERSION_NAME,
});
if (
!(await fs.pathExists(docsDir)) ||
(await fs.readdir(docsDir)).length === 0
) {
if (locale === i18n.defaultLocale) {
throw new Error(
logger.interpolate`${pluginIdLogPrefix}: no docs found in path=${docsDir}.`,
);
} else {
logger.warn`${pluginIdLogPrefix}: no docs found in path=${docsDir}. Skipping.`;
return;
}
}
const newVersionDir =
locale === i18n.defaultLocale
? path.join(
getVersionedDocsDirPath(siteDir, pluginId),
`version-${version}`,
)
: getDocsDirPathLocalized({
siteDir,
locale,
pluginId,
versionName: version,
});
await fs.copy(docsDir, newVersionDir);
}),
);
await createVersionedSidebarFile({ await createVersionedSidebarFile({
siteDir, siteDir,
pluginId, pluginId,

View file

@ -67,7 +67,7 @@ export default async function pluginContentDocs(
const versionsMetadata = await readVersionsMetadata({context, options}); const versionsMetadata = await readVersionsMetadata({context, options});
const pluginId = options.id ?? DEFAULT_PLUGIN_ID; const pluginId = options.id;
const pluginDataDirRoot = path.join( const pluginDataDirRoot = path.join(
generatedFilesDir, generatedFilesDir,
@ -97,12 +97,7 @@ export default async function pluginContentDocs(
.arguments('<version>') .arguments('<version>')
.description(commandDescription) .description(commandDescription)
.action((version) => { .action((version) => {
cliDocsVersionCommand(version, siteDir, pluginId, { cliDocsVersionCommand(version, options, context);
path: options.path,
sidebarPath: options.sidebarPath,
sidebarCollapsed: options.sidebarCollapsed,
sidebarCollapsible: options.sidebarCollapsible,
});
}); });
}, },

View file

@ -133,7 +133,7 @@ export async function readVersionNames(
return versions; return versions;
} }
function getDocsDirPathLocalized({ export function getDocsDirPathLocalized({
siteDir, siteDir,
locale, locale,
pluginId, pluginId,
@ -143,7 +143,7 @@ function getDocsDirPathLocalized({
locale: string; locale: string;
pluginId: string; pluginId: string;
versionName: string; versionName: string;
}) { }): string {
return getPluginI18nPath({ return getPluginI18nPath({
siteDir, siteDir,
locale, locale,