From 48a92c592e08151764199cf7b878a897ddfe8bfe Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Fri, 13 Apr 2018 13:42:50 -0700 Subject: [PATCH] Moved versions control into versions.yml and Gatsby plug-in --- content/versions.yml | 9 +++ gatsby-config.js | 1 + .../create-redirects.js | 65 +++++++++++++++++++ .../gatsby-node.js | 32 +++++++++ .../package.json | 4 ++ src/pages/versions.js | 25 +++---- static/_redirects | 6 +- 7 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 content/versions.yml create mode 100644 plugins/gatsby-transformer-versions-yaml/create-redirects.js create mode 100644 plugins/gatsby-transformer-versions-yaml/gatsby-node.js create mode 100644 plugins/gatsby-transformer-versions-yaml/package.json diff --git a/content/versions.yml b/content/versions.yml new file mode 100644 index 00000000..fae7e84b --- /dev/null +++ b/content/versions.yml @@ -0,0 +1,9 @@ +- title: '16.2.0' + path: /version/16.2 + url: https://5abc31d8be40f1556f06c4be--reactjs.netlify.com +- title: '16.1.1' + path: /version/16.1 + url: https://5a1dbcf14c4b93299e65b9a9--reactjs.netlify.com +- title: '16.0.0' + path: /version/16.0 + url: https://5a046bf5a6188f4b8fa4938a--reactjs.netlify.com \ No newline at end of file diff --git a/gatsby-config.js b/gatsby-config.js index 66f84a54..fe4410e9 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -20,6 +20,7 @@ module.exports = { 'gatsby-source-react-error-codes', 'gatsby-transformer-authors-yaml', 'gatsby-transformer-home-example-code', + 'gatsby-transformer-versions-yaml', 'gatsby-plugin-netlify', 'gatsby-plugin-glamor', 'gatsby-plugin-react-next', diff --git a/plugins/gatsby-transformer-versions-yaml/create-redirects.js b/plugins/gatsby-transformer-versions-yaml/create-redirects.js new file mode 100644 index 00000000..bd6e2d3e --- /dev/null +++ b/plugins/gatsby-transformer-versions-yaml/create-redirects.js @@ -0,0 +1,65 @@ +const {appendFile, exists, readFile, writeFile} = require('fs-extra'); + +const HEADER_COMMENT = `## Created with gatsby-transformer-versions-yaml`; + +module.exports = async function writeRedirectsFile(redirects, publicFolder) { + if (!redirects.length) { + return null; + } + + const FILE_PATH = publicFolder(`_redirects`); + + // Map redirect data to the format Netlify expects + // https://www.netlify.com/docs/redirects/ + redirects = redirects.map(redirect => { + const { + fromPath, + isPermanent, + redirectInBrowser, // eslint-disable-line no-unused-vars + toPath, + ...rest + } = redirect; + + // The order of the first 3 parameters is significant. + // The order for rest params (key-value pairs) is arbitrary. + const pieces = [ + fromPath, + toPath, + isPermanent ? 301 : 302, // Status + ]; + + for (let key in rest) { + const value = rest[key]; + + if (typeof value === `string` && value.indexOf(` `) >= 0) { + console.warn( + `Invalid redirect value "${value}" specified for key "${key}". ` + + `Values should not contain spaces.`, + ); + } else { + pieces.push(`${key}=${value}`); + } + } + + return pieces.join(` `); + }); + + let appendToFile = false; + + // Websites may also have statically defined redirects + // In that case we should append to them (not overwrite) + // Make sure we aren't just looking at previous build results though + const fileExists = await exists(FILE_PATH); + if (fileExists) { + const fileContents = await readFile(FILE_PATH); + if (fileContents.indexOf(HEADER_COMMENT) < 0) { + appendToFile = true; + } + } + + const data = `${HEADER_COMMENT}\n\n${redirects.join(`\n`)}`; + + return appendToFile + ? appendFile(FILE_PATH, `\n\n${data}`) + : writeFile(FILE_PATH, data); +}; diff --git a/plugins/gatsby-transformer-versions-yaml/gatsby-node.js b/plugins/gatsby-transformer-versions-yaml/gatsby-node.js new file mode 100644 index 00000000..d5bca5d6 --- /dev/null +++ b/plugins/gatsby-transformer-versions-yaml/gatsby-node.js @@ -0,0 +1,32 @@ +const readFileSync = require('fs').readFileSync; +const resolve = require('path').resolve; +const safeLoad = require('js-yaml').safeLoad; +const createRedirects = require('./create-redirects'); +const path = require('path'); + +// Reads versions.yml data into GraphQL. +// This is used to generate redirect rules for older documentation versions. +exports.onPostBuild = async ({store}) => { + const path = resolve(__dirname, '../../content/versions.yml'); + const file = readFileSync(path, 'utf8'); + const versions = safeLoad(file); + + // versions.yml structure is [{title: string, path: string, url: string}, ...] + createRedirects( + versions.map(version => ({ + fromPath: version.path, + toPath: version.url, + })), + getPublicFolder(store), + ); +}; + +function buildPrefixer(prefix, ...paths) { + return (...subpaths) => path.join(prefix, ...paths, ...subpaths); +} + +function getPublicFolder(store) { + const {program} = store.getState(); + + return buildPrefixer(program.directory, `public`); +} diff --git a/plugins/gatsby-transformer-versions-yaml/package.json b/plugins/gatsby-transformer-versions-yaml/package.json new file mode 100644 index 00000000..dcfada5c --- /dev/null +++ b/plugins/gatsby-transformer-versions-yaml/package.json @@ -0,0 +1,4 @@ +{ + "name": "gatsby-transformer-versions-yaml", + "version": "0.0.1" +} \ No newline at end of file diff --git a/src/pages/versions.js b/src/pages/versions.js index 6d4d8b3a..2695da7b 100644 --- a/src/pages/versions.js +++ b/src/pages/versions.js @@ -11,6 +11,9 @@ import TitleAndMetaTags from 'components/TitleAndMetaTags'; import React from 'react'; import {sharedStyles} from 'theme'; +// $FlowFixMe This is a valid path +import versions from '../../content/versions.yml'; + const Versions = () => (
@@ -29,21 +32,13 @@ const Versions = () => (

Documentation for recent releases can also be accessed below:

diff --git a/static/_redirects b/static/_redirects index 37534ccf..7db75e0c 100644 --- a/static/_redirects +++ b/static/_redirects @@ -1,6 +1,2 @@ /html-jsx.html http://magic.reactjs.net/htmltojsx.htm 301 -/tips/controlled-input-null-value.html /docs/forms.html#controlled-input-null-value - -/version/16.2 https://5abc31d8be40f1556f06c4be--reactjs.netlify.com/ 301 -/version/16.1 https://5a1dbcf14c4b93299e65b9a9--reactjs.netlify.com/ 301 -/version/16.0 https://5a046bf5a6188f4b8fa4938a--reactjs.netlify.com/ 301 \ No newline at end of file +/tips/controlled-input-null-value.html /docs/forms.html#controlled-input-null-value \ No newline at end of file