mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-04 12:47:14 +02:00
feat: Add --skip-next-release option to yarn build (#1292)
This commit is contained in:
parent
f04eea6b48
commit
d279836c40
9 changed files with 165 additions and 96 deletions
|
@ -59,6 +59,7 @@ Alias: `build`.
|
|||
| Options | Default | Description |
|
||||
| -------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--skip-image-compression` | `false` | Skip compression of image assets. You usually won't want to skip this unless your images have already been optimized. |
|
||||
| `--skip-next-release` | `false` | Skip the next release documents when versioning is enabled. This will not build HTML files for documents in `/docs` directory.|
|
||||
|
||||
Generates the static website, applying translations if necessary. Useful for building the website prior to deployment.
|
||||
|
||||
|
|
|
@ -94,3 +94,20 @@ describe('Build files', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Build files but skip next release', () => {
|
||||
beforeAll(() => {
|
||||
shell.cd('website-1.x');
|
||||
shell.exec('yarn build --skip-next-release', {silent: true});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
clearBuildFolder();
|
||||
});
|
||||
|
||||
test('Did not generate HTML files from markdown files for next release', () => {
|
||||
expect(
|
||||
glob.sync(`${buildDir}/${siteConfig.projectName}/docs/**/next`).length,
|
||||
).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ const siteConfig = require(`${process.cwd()}/siteConfig.js`);
|
|||
// siteConfig virtually.
|
||||
jest.mock(`${process.cwd()}/siteConfig.js`, () => jest.fn(), {virtual: true});
|
||||
|
||||
jest.mock('commander');
|
||||
jest.genMockFromModule('commander');
|
||||
jest.mock('react-dev-utils/openBrowser');
|
||||
jest.mock('portfinder');
|
||||
jest.mock('../liveReloadServer.js');
|
||||
|
|
|
@ -10,6 +10,7 @@ const CWD = process.cwd();
|
|||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const glob = require('glob');
|
||||
const program = require('commander');
|
||||
|
||||
const metadataUtils = require('./metadataUtils');
|
||||
|
||||
|
@ -37,6 +38,8 @@ const SupportedHeaderFields = new Set([
|
|||
'custom_edit_url',
|
||||
]);
|
||||
|
||||
program.option('--skip-next-release').parse(process.argv);
|
||||
|
||||
let allSidebars;
|
||||
if (fs.existsSync(`${CWD}/sidebars.json`)) {
|
||||
allSidebars = require(`${CWD}/sidebars.json`);
|
||||
|
@ -54,6 +57,14 @@ function getDocsPath() {
|
|||
return siteConfig.customDocsPath ? siteConfig.customDocsPath : 'docs';
|
||||
}
|
||||
|
||||
function shouldGenerateNextReleaseDocs() {
|
||||
return !(
|
||||
env.versioning.enabled &&
|
||||
program.name() === 'docusaurus-build' &&
|
||||
program.skipNextRelease
|
||||
);
|
||||
}
|
||||
|
||||
// returns map from id to object containing sidebar ordering info
|
||||
function readSidebar(sidebars = {}) {
|
||||
Object.assign(sidebars, versionFallback.sidebarData());
|
||||
|
@ -220,74 +231,76 @@ function generateMetadataDocs() {
|
|||
const metadatas = {};
|
||||
const defaultMetadatas = {};
|
||||
|
||||
// metadata for english files
|
||||
const docsDir = path.join(CWD, '../', getDocsPath());
|
||||
let files = glob.sync(`${docsDir}/**`);
|
||||
files.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
if (shouldGenerateNextReleaseDocs()) {
|
||||
// metadata for english files
|
||||
const docsDir = path.join(CWD, '../', getDocsPath());
|
||||
let files = glob.sync(`${docsDir}/**`);
|
||||
files.forEach(file => {
|
||||
const extension = path.extname(file);
|
||||
|
||||
if (extension === '.md' || extension === '.markdown') {
|
||||
const res = processMetadata(file, docsDir);
|
||||
if (extension === '.md' || extension === '.markdown') {
|
||||
const res = processMetadata(file, docsDir);
|
||||
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
const metadata = res.metadata;
|
||||
metadatas[metadata.id] = metadata;
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
const metadata = res.metadata;
|
||||
metadatas[metadata.id] = metadata;
|
||||
|
||||
// create a default list of documents for each enabled language based on docs in English
|
||||
// these will get replaced if/when the localized file is downloaded from crowdin
|
||||
enabledLanguages
|
||||
.filter(currentLanguage => currentLanguage !== 'en')
|
||||
.forEach(currentLanguage => {
|
||||
const baseMetadata = Object.assign({}, metadata);
|
||||
baseMetadata.id = baseMetadata.id
|
||||
.toString()
|
||||
.replace(/^en-/, `${currentLanguage}-`);
|
||||
if (baseMetadata.permalink) {
|
||||
baseMetadata.permalink = baseMetadata.permalink
|
||||
.toString()
|
||||
.replace(
|
||||
new RegExp(`^${docsPart}en/`),
|
||||
`${docsPart}${currentLanguage}/`,
|
||||
);
|
||||
}
|
||||
if (baseMetadata.next) {
|
||||
baseMetadata.next = baseMetadata.next
|
||||
// create a default list of documents for each enabled language based on docs in English
|
||||
// these will get replaced if/when the localized file is downloaded from crowdin
|
||||
enabledLanguages
|
||||
.filter(currentLanguage => currentLanguage !== 'en')
|
||||
.forEach(currentLanguage => {
|
||||
const baseMetadata = Object.assign({}, metadata);
|
||||
baseMetadata.id = baseMetadata.id
|
||||
.toString()
|
||||
.replace(/^en-/, `${currentLanguage}-`);
|
||||
}
|
||||
if (baseMetadata.previous) {
|
||||
baseMetadata.previous = baseMetadata.previous
|
||||
.toString()
|
||||
.replace(/^en-/, `${currentLanguage}-`);
|
||||
}
|
||||
baseMetadata.language = currentLanguage;
|
||||
defaultMetadatas[baseMetadata.id] = baseMetadata;
|
||||
});
|
||||
Object.assign(metadatas, defaultMetadatas);
|
||||
}
|
||||
});
|
||||
if (baseMetadata.permalink) {
|
||||
baseMetadata.permalink = baseMetadata.permalink
|
||||
.toString()
|
||||
.replace(
|
||||
new RegExp(`^${docsPart}en/`),
|
||||
`${docsPart}${currentLanguage}/`,
|
||||
);
|
||||
}
|
||||
if (baseMetadata.next) {
|
||||
baseMetadata.next = baseMetadata.next
|
||||
.toString()
|
||||
.replace(/^en-/, `${currentLanguage}-`);
|
||||
}
|
||||
if (baseMetadata.previous) {
|
||||
baseMetadata.previous = baseMetadata.previous
|
||||
.toString()
|
||||
.replace(/^en-/, `${currentLanguage}-`);
|
||||
}
|
||||
baseMetadata.language = currentLanguage;
|
||||
defaultMetadatas[baseMetadata.id] = baseMetadata;
|
||||
});
|
||||
Object.assign(metadatas, defaultMetadatas);
|
||||
}
|
||||
});
|
||||
|
||||
// metadata for non-english docs
|
||||
const translatedDir = path.join(CWD, 'translated_docs');
|
||||
files = glob.sync(`${CWD}/translated_docs/**`);
|
||||
files.forEach(file => {
|
||||
if (!utils.getLanguage(file, translatedDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extension = path.extname(file);
|
||||
|
||||
if (extension === '.md' || extension === '.markdown') {
|
||||
const res = processMetadata(file, translatedDir);
|
||||
if (!res) {
|
||||
// metadata for non-english docs
|
||||
const translatedDir = path.join(CWD, 'translated_docs');
|
||||
files = glob.sync(`${CWD}/translated_docs/**`);
|
||||
files.forEach(file => {
|
||||
if (!utils.getLanguage(file, translatedDir)) {
|
||||
return;
|
||||
}
|
||||
const metadata = res.metadata;
|
||||
metadatas[metadata.id] = metadata;
|
||||
}
|
||||
});
|
||||
|
||||
const extension = path.extname(file);
|
||||
|
||||
if (extension === '.md' || extension === '.markdown') {
|
||||
const res = processMetadata(file, translatedDir);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
const metadata = res.metadata;
|
||||
metadatas[metadata.id] = metadata;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// metadata for versioned docs
|
||||
const versionData = versionFallback.docData();
|
||||
|
|
|
@ -45,8 +45,12 @@ program
|
|||
'-sic, --skip-image-compression <skipImageCompression>',
|
||||
'Skip compression of image assets (default: false)',
|
||||
)
|
||||
.action((siteDir = '.', {skipImageCompression}) => {
|
||||
wrapCommand(build)(path.resolve(siteDir), {skipImageCompression});
|
||||
.option('--skip-next-release', 'Skip documents from next release')
|
||||
.action((siteDir = '.', {skipImageCompression, skipNextRelease}) => {
|
||||
wrapCommand(build)(path.resolve(siteDir), {
|
||||
skipImageCompression,
|
||||
skipNextRelease,
|
||||
});
|
||||
});
|
||||
|
||||
program
|
||||
|
|
|
@ -38,11 +38,11 @@ function compile(config) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports = async function build(siteDir) {
|
||||
module.exports = async function build(siteDir, options) {
|
||||
process.env.NODE_ENV = 'production';
|
||||
console.log('Build command invoked ...');
|
||||
|
||||
const props = await load(siteDir);
|
||||
const props = await load(siteDir, options.skipNextRelease);
|
||||
|
||||
// Apply user webpack config.
|
||||
const {outDir, plugins} = props;
|
||||
|
|
|
@ -12,7 +12,10 @@ const createOrder = require('./order');
|
|||
const loadSidebars = require('./sidebars');
|
||||
const processMetadata = require('./metadata');
|
||||
|
||||
async function loadDocs({siteDir, docsDir, env, siteConfig}) {
|
||||
async function loadDocs(
|
||||
{siteDir, docsDir, env, siteConfig},
|
||||
skipNextRelease = false,
|
||||
) {
|
||||
// @tested - load all sidebars including versioned sidebars
|
||||
const docsSidebars = loadSidebars({siteDir, env});
|
||||
|
||||
|
@ -33,30 +36,34 @@ async function loadDocs({siteDir, docsDir, env, siteConfig}) {
|
|||
// Prepare metadata container.
|
||||
const docsMetadatas = {};
|
||||
|
||||
// Metadata for default docs files.
|
||||
const docsFiles = await globby(['**/*.md'], {
|
||||
cwd: docsDir,
|
||||
});
|
||||
await Promise.all(
|
||||
docsFiles.map(async source => {
|
||||
// Do not allow reserved version/ translated folder name in 'docs'
|
||||
// e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug
|
||||
const subFolder = getSubFolder(path.resolve(docsDir, source), docsDir);
|
||||
const versionsFolders = versions.map(version => `version-${version}`);
|
||||
if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) {
|
||||
throw new Error(`You cannot have a folder named 'docs/${subFolder}/'`);
|
||||
}
|
||||
if (!(versioningEnabled && skipNextRelease)) {
|
||||
// Metadata for default docs files.
|
||||
const docsFiles = await globby(['**/*.md'], {
|
||||
cwd: docsDir,
|
||||
});
|
||||
await Promise.all(
|
||||
docsFiles.map(async source => {
|
||||
// Do not allow reserved version/ translated folder name in 'docs'
|
||||
// e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug
|
||||
const subFolder = getSubFolder(path.resolve(docsDir, source), docsDir);
|
||||
const versionsFolders = versions.map(version => `version-${version}`);
|
||||
if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) {
|
||||
throw new Error(
|
||||
`You cannot have a folder named 'docs/${subFolder}/'`,
|
||||
);
|
||||
}
|
||||
|
||||
const metadata = await processMetadata(
|
||||
source,
|
||||
docsDir,
|
||||
env,
|
||||
order,
|
||||
siteConfig,
|
||||
);
|
||||
docsMetadatas[metadata.id] = metadata;
|
||||
}),
|
||||
);
|
||||
const metadata = await processMetadata(
|
||||
source,
|
||||
docsDir,
|
||||
env,
|
||||
order,
|
||||
siteConfig,
|
||||
);
|
||||
docsMetadatas[metadata.id] = metadata;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Metadata for non-default-language docs.
|
||||
if (translationEnabled) {
|
||||
|
|
|
@ -17,7 +17,7 @@ const loadRoutes = require('./routes');
|
|||
const loadPlugins = require('./plugins');
|
||||
const constants = require('../constants');
|
||||
|
||||
module.exports = async function load(siteDir) {
|
||||
module.exports = async function load(siteDir, skipNextRelease = false) {
|
||||
const generatedFilesDir = path.resolve(
|
||||
siteDir,
|
||||
constants.GENERATED_FILES_DIR_NAME,
|
||||
|
@ -42,12 +42,15 @@ module.exports = async function load(siteDir) {
|
|||
|
||||
// Docs
|
||||
const docsDir = path.resolve(siteDir, '..', siteConfig.customDocsPath);
|
||||
const {docsMetadatas, docsSidebars} = await loadDocs({
|
||||
siteDir,
|
||||
docsDir,
|
||||
env,
|
||||
siteConfig,
|
||||
});
|
||||
const {docsMetadatas, docsSidebars} = await loadDocs(
|
||||
{
|
||||
siteDir,
|
||||
docsDir,
|
||||
env,
|
||||
siteConfig,
|
||||
},
|
||||
skipNextRelease,
|
||||
);
|
||||
await generate(
|
||||
generatedFilesDir,
|
||||
'docsMetadatas.js',
|
||||
|
|
|
@ -173,4 +173,28 @@ describe('loadDocs', () => {
|
|||
version: null,
|
||||
});
|
||||
});
|
||||
|
||||
test('versioned website with skip next release', async () => {
|
||||
const props = await loadSetup('versioned');
|
||||
const {siteDir, docsDir, versionedDir, env, siteConfig} = props;
|
||||
const {docsMetadatas} = await loadDocs(
|
||||
{siteDir, docsDir, env, siteConfig},
|
||||
true,
|
||||
);
|
||||
expect(docsMetadatas['version-1.0.0-foo/bar']).toEqual({
|
||||
category: 'Test',
|
||||
id: 'version-1.0.0-foo/bar',
|
||||
language: null,
|
||||
localized_id: 'version-1.0.0-foo/bar',
|
||||
next: 'version-1.0.0-foo/baz',
|
||||
next_id: 'version-1.0.0-foo/baz',
|
||||
next_title: 'Baz',
|
||||
permalink: '/docs/1.0.0/foo/bar',
|
||||
sidebar: 'version-1.0.0-docs',
|
||||
source: path.join(versionedDir, 'version-1.0.0/foo/bar.md'),
|
||||
title: 'Bar',
|
||||
version: '1.0.0',
|
||||
});
|
||||
expect(docsMetadatas['foo/bar']).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue