UNPKG

5.36 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3/**
4 * Copyright (c) 2017-present, Facebook, Inc.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10require('@babel/register')({
11 babelrc: false,
12 only: [__dirname, `${process.cwd()}/core`],
13 plugins: [
14 require('./server/translate-plugin.js'),
15 require('@babel/plugin-proposal-class-properties').default,
16 require('@babel/plugin-proposal-object-rest-spread').default,
17 ],
18 presets: [
19 require('@babel/preset-react').default,
20 require('@babel/preset-env').default,
21 ],
22});
23
24const program = require('commander');
25const chalk = require('chalk');
26const glob = require('glob');
27const fs = require('fs-extra');
28const mkdirp = require('mkdirp');
29const path = require('path');
30
31const readMetadata = require('./server/readMetadata.js');
32const utils = require('./server/utils.js');
33const versionFallback = require('./server/versionFallback.js');
34const metadataUtils = require('./server/metadataUtils.js');
35const env = require('./server/env.js');
36
37const CWD = process.cwd();
38let versions;
39if (fs.existsSync(`${CWD}/versions.json`)) {
40 versions = require(`${CWD}/versions.json`);
41} else {
42 versions = [];
43}
44
45let version;
46
47program
48 .arguments('<version>')
49 .action(ver => {
50 version = ver;
51 })
52 .parse(process.argv);
53
54if (env.versioning.missingVersionsPage) {
55 env.versioning.printMissingVersionsPageError();
56 process.exit(1);
57}
58
59if (version.includes('/')) {
60 console.error(
61 `${chalk.red(
62 'Invalid version number specified! Do not include slash (/). Try something like: 1.0.0',
63 )}`,
64 );
65 process.exit(1);
66}
67
68if (typeof version === 'undefined') {
69 console.error(
70 `${chalk.yellow(
71 'No version number specified!',
72 )}\nPass the version you wish to create as an argument.\nEx: 1.0.0`,
73 );
74 process.exit(1);
75}
76
77if (versions.includes(version)) {
78 console.error(
79 `${chalk.yellow(
80 'This version already exists!',
81 )}\nSpecify a new version to create that does not already exist.`,
82 );
83 process.exit(1);
84}
85
86function makeHeader(metadata) {
87 let header = '---\n';
88 Object.keys(metadata).forEach(key => {
89 header += `${key}: ${metadata[key]}\n`;
90 });
91 header += '---\n';
92 return header;
93}
94
95function writeFileAndCreateFolder(file, content, encoding) {
96 mkdirp.sync(path.dirname(file));
97
98 fs.writeFileSync(file, content, encoding);
99}
100
101const versionFolder = `${CWD}/versioned_docs/version-${version}`;
102
103mkdirp.sync(versionFolder);
104
105// copy necessary files to new version, changing some of its metadata to reflect the versioning
106const files = glob.sync(`${CWD}/../${readMetadata.getDocsPath()}/**`);
107files.forEach(file => {
108 const ext = path.extname(file);
109 if (ext !== '.md' && ext !== '.markdown') {
110 return;
111 }
112
113 const res = metadataUtils.extractMetadata(fs.readFileSync(file, 'utf8'));
114 const metadata = res.metadata;
115 // Don't version any docs without any metadata whatsoever.
116 if (Object.keys(metadata).length === 0) {
117 return;
118 }
119 const rawContent = res.rawContent;
120 if (!metadata.id) {
121 metadata.id = path.basename(file, path.extname(file));
122 }
123 if (metadata.id.includes('/')) {
124 throw new Error('Document id cannot include "/".');
125 }
126 if (!metadata.title) {
127 metadata.title = metadata.id;
128 }
129
130 const docsDir = path.join(CWD, '../', readMetadata.getDocsPath());
131 const subDir = utils.getSubDir(file, docsDir);
132 const docId = subDir ? `${subDir}/${metadata.id}` : metadata.id;
133 if (!versionFallback.diffLatestDoc(file, docId)) {
134 return;
135 }
136
137 metadata.original_id = metadata.id;
138 metadata.id = `version-${version}-${metadata.id}`;
139 const targetFile = subDir
140 ? `${versionFolder}/${subDir}/${path.basename(file)}`
141 : `${versionFolder}/${path.basename(file)}`;
142
143 writeFileAndCreateFolder(
144 targetFile,
145 makeHeader(metadata) + rawContent,
146 'utf8',
147 );
148});
149
150// copy sidebar if necessary
151if (versionFallback.diffLatestSidebar()) {
152 mkdirp(`${CWD}/versioned_sidebars`);
153 const sidebar = JSON.parse(fs.readFileSync(`${CWD}/sidebars.json`, 'utf8'));
154 const versioned = {};
155
156 Object.keys(sidebar).forEach(sb => {
157 const versionSidebar = `version-${version}-${sb}`;
158 versioned[versionSidebar] = {};
159
160 const categories = sidebar[sb];
161 Object.keys(categories).forEach(category => {
162 versioned[versionSidebar][category] = [];
163
164 const categoryItems = categories[category];
165 categoryItems.forEach(categoryItem => {
166 let versionedCategoryItem = categoryItem;
167 if (typeof categoryItem === 'object') {
168 if (categoryItem.ids && categoryItem.ids.length > 0) {
169 versionedCategoryItem.ids = categoryItem.ids.map(
170 id => `version-${version}-${id}`,
171 );
172 }
173 } else if (typeof categoryItem === 'string') {
174 versionedCategoryItem = `version-${version}-${categoryItem}`;
175 }
176 versioned[versionSidebar][category].push(versionedCategoryItem);
177 });
178 });
179 });
180
181 fs.writeFileSync(
182 `${CWD}/versioned_sidebars/version-${version}-sidebars.json`,
183 `${JSON.stringify(versioned, null, 2)}\n`,
184 'utf8',
185 );
186}
187
188// update versions.json file
189versions.unshift(version);
190fs.writeFileSync(
191 `${CWD}/versions.json`,
192 `${JSON.stringify(versions, null, 2)}\n`,
193);
194
195console.log(`${chalk.green(`Version ${version} created!\n`)}`);