feat: Add --skip-next-release option to yarn build (#1292)

This commit is contained in:
Parth Patel 2019-03-29 05:17:46 -04:00 committed by Endilie Yacop Sucipto
parent f04eea6b48
commit d279836c40
9 changed files with 165 additions and 96 deletions

View file

@ -59,6 +59,7 @@ Alias: `build`.
| Options | Default | Description | | 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-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. Generates the static website, applying translations if necessary. Useful for building the website prior to deployment.

View file

@ -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);
});
});

View file

@ -18,7 +18,7 @@ const siteConfig = require(`${process.cwd()}/siteConfig.js`);
// siteConfig virtually. // siteConfig virtually.
jest.mock(`${process.cwd()}/siteConfig.js`, () => jest.fn(), {virtual: true}); jest.mock(`${process.cwd()}/siteConfig.js`, () => jest.fn(), {virtual: true});
jest.mock('commander'); jest.genMockFromModule('commander');
jest.mock('react-dev-utils/openBrowser'); jest.mock('react-dev-utils/openBrowser');
jest.mock('portfinder'); jest.mock('portfinder');
jest.mock('../liveReloadServer.js'); jest.mock('../liveReloadServer.js');

View file

@ -10,6 +10,7 @@ const CWD = process.cwd();
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const glob = require('glob'); const glob = require('glob');
const program = require('commander');
const metadataUtils = require('./metadataUtils'); const metadataUtils = require('./metadataUtils');
@ -37,6 +38,8 @@ const SupportedHeaderFields = new Set([
'custom_edit_url', 'custom_edit_url',
]); ]);
program.option('--skip-next-release').parse(process.argv);
let allSidebars; let allSidebars;
if (fs.existsSync(`${CWD}/sidebars.json`)) { if (fs.existsSync(`${CWD}/sidebars.json`)) {
allSidebars = require(`${CWD}/sidebars.json`); allSidebars = require(`${CWD}/sidebars.json`);
@ -54,6 +57,14 @@ function getDocsPath() {
return siteConfig.customDocsPath ? siteConfig.customDocsPath : 'docs'; 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 // returns map from id to object containing sidebar ordering info
function readSidebar(sidebars = {}) { function readSidebar(sidebars = {}) {
Object.assign(sidebars, versionFallback.sidebarData()); Object.assign(sidebars, versionFallback.sidebarData());
@ -220,74 +231,76 @@ function generateMetadataDocs() {
const metadatas = {}; const metadatas = {};
const defaultMetadatas = {}; const defaultMetadatas = {};
// metadata for english files if (shouldGenerateNextReleaseDocs()) {
const docsDir = path.join(CWD, '../', getDocsPath()); // metadata for english files
let files = glob.sync(`${docsDir}/**`); const docsDir = path.join(CWD, '../', getDocsPath());
files.forEach(file => { let files = glob.sync(`${docsDir}/**`);
const extension = path.extname(file); files.forEach(file => {
const extension = path.extname(file);
if (extension === '.md' || extension === '.markdown') { if (extension === '.md' || extension === '.markdown') {
const res = processMetadata(file, docsDir); const res = processMetadata(file, docsDir);
if (!res) { if (!res) {
return; return;
} }
const metadata = res.metadata; const metadata = res.metadata;
metadatas[metadata.id] = metadata; metadatas[metadata.id] = metadata;
// create a default list of documents for each enabled language based on docs in English // 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 // these will get replaced if/when the localized file is downloaded from crowdin
enabledLanguages enabledLanguages
.filter(currentLanguage => currentLanguage !== 'en') .filter(currentLanguage => currentLanguage !== 'en')
.forEach(currentLanguage => { .forEach(currentLanguage => {
const baseMetadata = Object.assign({}, metadata); const baseMetadata = Object.assign({}, metadata);
baseMetadata.id = baseMetadata.id 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
.toString() .toString()
.replace(/^en-/, `${currentLanguage}-`); .replace(/^en-/, `${currentLanguage}-`);
} if (baseMetadata.permalink) {
if (baseMetadata.previous) { baseMetadata.permalink = baseMetadata.permalink
baseMetadata.previous = baseMetadata.previous .toString()
.toString() .replace(
.replace(/^en-/, `${currentLanguage}-`); new RegExp(`^${docsPart}en/`),
} `${docsPart}${currentLanguage}/`,
baseMetadata.language = currentLanguage; );
defaultMetadatas[baseMetadata.id] = baseMetadata; }
}); if (baseMetadata.next) {
Object.assign(metadatas, defaultMetadatas); 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 // metadata for non-english docs
const translatedDir = path.join(CWD, 'translated_docs'); const translatedDir = path.join(CWD, 'translated_docs');
files = glob.sync(`${CWD}/translated_docs/**`); files = glob.sync(`${CWD}/translated_docs/**`);
files.forEach(file => { files.forEach(file => {
if (!utils.getLanguage(file, translatedDir)) { if (!utils.getLanguage(file, translatedDir)) {
return;
}
const extension = path.extname(file);
if (extension === '.md' || extension === '.markdown') {
const res = processMetadata(file, translatedDir);
if (!res) {
return; 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 // metadata for versioned docs
const versionData = versionFallback.docData(); const versionData = versionFallback.docData();

View file

@ -45,8 +45,12 @@ program
'-sic, --skip-image-compression <skipImageCompression>', '-sic, --skip-image-compression <skipImageCompression>',
'Skip compression of image assets (default: false)', 'Skip compression of image assets (default: false)',
) )
.action((siteDir = '.', {skipImageCompression}) => { .option('--skip-next-release', 'Skip documents from next release')
wrapCommand(build)(path.resolve(siteDir), {skipImageCompression}); .action((siteDir = '.', {skipImageCompression, skipNextRelease}) => {
wrapCommand(build)(path.resolve(siteDir), {
skipImageCompression,
skipNextRelease,
});
}); });
program program

View file

@ -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'; process.env.NODE_ENV = 'production';
console.log('Build command invoked ...'); console.log('Build command invoked ...');
const props = await load(siteDir); const props = await load(siteDir, options.skipNextRelease);
// Apply user webpack config. // Apply user webpack config.
const {outDir, plugins} = props; const {outDir, plugins} = props;

View file

@ -12,7 +12,10 @@ const createOrder = require('./order');
const loadSidebars = require('./sidebars'); const loadSidebars = require('./sidebars');
const processMetadata = require('./metadata'); 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 // @tested - load all sidebars including versioned sidebars
const docsSidebars = loadSidebars({siteDir, env}); const docsSidebars = loadSidebars({siteDir, env});
@ -33,30 +36,34 @@ async function loadDocs({siteDir, docsDir, env, siteConfig}) {
// Prepare metadata container. // Prepare metadata container.
const docsMetadatas = {}; const docsMetadatas = {};
// Metadata for default docs files. if (!(versioningEnabled && skipNextRelease)) {
const docsFiles = await globby(['**/*.md'], { // Metadata for default docs files.
cwd: docsDir, const docsFiles = await globby(['**/*.md'], {
}); cwd: docsDir,
await Promise.all( });
docsFiles.map(async source => { await Promise.all(
// Do not allow reserved version/ translated folder name in 'docs' docsFiles.map(async source => {
// e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug // Do not allow reserved version/ translated folder name in 'docs'
const subFolder = getSubFolder(path.resolve(docsDir, source), docsDir); // e.g: 'docs/version-1.0.0/' should not be allowed as it can cause unwanted bug
const versionsFolders = versions.map(version => `version-${version}`); const subFolder = getSubFolder(path.resolve(docsDir, source), docsDir);
if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) { const versionsFolders = versions.map(version => `version-${version}`);
throw new Error(`You cannot have a folder named 'docs/${subFolder}/'`); if ([...enabledLangTags, ...versionsFolders].includes(subFolder)) {
} throw new Error(
`You cannot have a folder named 'docs/${subFolder}/'`,
);
}
const metadata = await processMetadata( const metadata = await processMetadata(
source, source,
docsDir, docsDir,
env, env,
order, order,
siteConfig, siteConfig,
); );
docsMetadatas[metadata.id] = metadata; docsMetadatas[metadata.id] = metadata;
}), }),
); );
}
// Metadata for non-default-language docs. // Metadata for non-default-language docs.
if (translationEnabled) { if (translationEnabled) {

View file

@ -17,7 +17,7 @@ const loadRoutes = require('./routes');
const loadPlugins = require('./plugins'); const loadPlugins = require('./plugins');
const constants = require('../constants'); const constants = require('../constants');
module.exports = async function load(siteDir) { module.exports = async function load(siteDir, skipNextRelease = false) {
const generatedFilesDir = path.resolve( const generatedFilesDir = path.resolve(
siteDir, siteDir,
constants.GENERATED_FILES_DIR_NAME, constants.GENERATED_FILES_DIR_NAME,
@ -42,12 +42,15 @@ module.exports = async function load(siteDir) {
// Docs // Docs
const docsDir = path.resolve(siteDir, '..', siteConfig.customDocsPath); const docsDir = path.resolve(siteDir, '..', siteConfig.customDocsPath);
const {docsMetadatas, docsSidebars} = await loadDocs({ const {docsMetadatas, docsSidebars} = await loadDocs(
siteDir, {
docsDir, siteDir,
env, docsDir,
siteConfig, env,
}); siteConfig,
},
skipNextRelease,
);
await generate( await generate(
generatedFilesDir, generatedFilesDir,
'docsMetadatas.js', 'docsMetadatas.js',

View file

@ -173,4 +173,28 @@ describe('loadDocs', () => {
version: null, 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();
});
}); });