Files
react-native/docgen/server/import-existing-docs.js
T
2017-09-05 09:31:56 -07:00

215 lines
5.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
"use strict";
const fm = require("front-matter");
const fs = require("fs");
const glob = require("glob");
const mkdirp = require("mkdirp");
const shell = require("shelljs");
const GIT_USER = process.env.GIT_USER;
const GITHUB_USERNAME = process.env.GITHUB_USERNAME;
const GITHUB_REPONAME = process.env.GITHUB_REPONAME;
const remoteBranch = `https://${GIT_USER}@github.com/${GITHUB_USERNAME}/${GITHUB_REPONAME}.git`;
const targetDir = `${GITHUB_REPONAME}-docs`;
const DOCS_DIR = `../docs`;
if (!GIT_USER) {
shell.echo("GIT_USER undefined.");
shell.exit(1);
}
if (!GITHUB_USERNAME) {
shell.echo("GITHUB_USERNAME undefined.");
shell.exit(1);
}
if (!GITHUB_REPONAME) {
shell.echo("GITHUB_REPONAME undefined.");
shell.exit(1);
}
if (!shell.which("git")) {
shell.echo("Sorry, this script requires git");
shell.exit(1);
}
function prepareFilesystem() {
shell.cd(process.cwd());
shell.exec(`rm -rf build/`);
shell.mkdir(`build`);
shell.cd(`build`);
shell.exec(`rm -rf ${targetDir}`);
shell.mkdir(targetDir);
}
function checkOutDocs() {
shell.cd(targetDir);
shell.exec(`git init`).code !== 0;
if (shell.exec(`git remote add origin ${remoteBranch}`).code !== 0) {
shell.echo("Error: git remote failed");
shell.exit(1);
}
shell.exec(`git config core.sparsecheckout true`).code !== 0;
shell.exec(`echo "docs/*" >> .git/info/sparse-checkout`).code !== 0;
if (shell.exec(`git fetch --depth 1 origin master`).code !== 0) {
shell.echo("Error: git fetch failed");
shell.exit(1);
}
if (shell.exec(`git pull --depth 1 origin master`).code !== 0) {
shell.echo("Error: git pull failed");
shell.exit(1);
}
shell.echo(`Checked out ${targetDir}`);
shell.cd(`../..`);
}
function generateDocsMetadata(files) {
let sidebarsMetadata = new Object();
files.forEach(function(file) {
const data = fs.readFileSync(file, "utf8");
const content = fm(data);
const metadata = content.attributes;
const rawContent = content.body;
if (metadata.layout !== "docs") {
console.log(`Skipping ${file} due to non-docs layout ${metadata.layout}`);
return;
}
if (metadata.category) {
if (!Object.keys(sidebarsMetadata).includes(metadata.category)) {
sidebarsMetadata = Object.assign({}, sidebarsMetadata, {
[metadata.category]: {}
});
}
const sidebarMetadata = {
previous: metadata.previous,
next: metadata.next,
id: metadata.id,
title: metadata.title,
content: rawContent,
filename: file
};
const updatedCategory = Object.assign(
{},
sidebarsMetadata[metadata.category],
{ [sidebarMetadata.id]: sidebarMetadata }
);
sidebarsMetadata = Object.assign({}, sidebarsMetadata, {
[metadata.category]: updatedCategory
});
} else {
console.log(`Skipping ${file} due to lack of category`);
return;
}
if (!metadata.permalink) {
console.log(`Skipping ${file} due to lack of permalink`);
return;
}
if (metadata.permalink.match(/^https?:/)) {
console.log(`Skipping ${file} as its permalink is external`);
return;
}
});
fs.writeFileSync(
`build/sidebars-metadata.json`,
JSON.stringify(sidebarsMetadata)
);
return sidebarsMetadata;
}
function generateSidebarsFromMetadata(sidebarsMetadata) {
let sidebars = new Object();
Object.keys(sidebarsMetadata).forEach(function(category) {
if (!Object.keys(sidebars).includes(category)) {
sidebars = Object.assign({}, sidebars, { [category]: [] });
}
let categoryHead;
let allFilesInCategory = Object.keys(sidebarsMetadata[category]);
Object.entries(sidebarsMetadata[category]).forEach(function([id, file]) {
if (allFilesInCategory.includes(file.previous)) {
// skip, we're looking for head
console.log(`skipping ${file.id}`);
return;
}
categoryHead = file;
});
let updatedCategory = [categoryHead.id];
let currentFile = categoryHead;
while (allFilesInCategory.includes(currentFile.next)) {
updatedCategory = updatedCategory.concat([currentFile.next]);
currentFile = sidebarsMetadata[category][currentFile.next];
}
sidebars = Object.assign({}, sidebars, { [category]: updatedCategory });
});
return sidebars;
}
function generateMarkdownFromMetadata(sidebarMetadata) {
Object.keys(sidebarMetadata).forEach(function(category) {
Object.keys(sidebarMetadata[category]).forEach(function(docId) {
const doc = sidebarMetadata[category][docId];
const targetFile = `../docs/${doc.id}.md`;
const migratedContent = doc.content.replace('src="img/', 'src="/react-native/img/');
const res = [
"---",
"id: " + doc.id,
"title: " + doc.title,
"---",
migratedContent
]
.filter(function(line) {
return line;
})
.join("\n");
fs.writeFileSync(targetFile, res);
console.log(`Wrote ${targetFile}`);
});
});
}
function processDocs() {
// Generate sidebars.json
glob(`build/${targetDir}/docs/*.md`, function(er, files) {
const sidebarsMetadata = generateDocsMetadata(files);
const sidebars = generateSidebarsFromMetadata(sidebarsMetadata);
fs.writeFileSync(
`../website/sidebars.json`,
JSON.stringify({
docs: sidebars
})
);
console.log("Generated sidebars.json file from docs");
generateMarkdownFromMetadata(sidebarsMetadata);
console.log("Generated markdown files from docs");
});
}
prepareFilesystem();
checkOutDocs();
processDocs();