From 2e2e5f0496376ea162ccc42dc6c2922660913ce8 Mon Sep 17 00:00:00 2001 From: mbrookes Date: Tue, 16 Feb 2016 02:29:57 +0000 Subject: [PATCH] [Docs] Add gh-pages-build script, add versions DropDownMenu to LeftNav --- ROADMAP.md | 4 +- docs/gh-pages-build.js | 145 +++++++++++++++++++++++++ docs/package.json | 1 + docs/src/app/components/AppLeftNav.jsx | 100 +++++++++++++---- docs/src/www/versions.json | 44 ++++++++ 5 files changed, 273 insertions(+), 21 deletions(-) create mode 100755 docs/gh-pages-build.js create mode 100644 docs/src/www/versions.json diff --git a/ROADMAP.md b/ROADMAP.md index f7809eb2606c9a..a47acca303c15d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -31,11 +31,11 @@ The roadmap is a living document, and it is likely that priorities will change, - [ ] [[1321](https://github.com/callemall/material-ui/pull/1321#issuecomment-174108805)] Composable AppBar component. - [ ] [[#2493](https://github.com/callemall/material-ui/pull/2493)] New Stepper component. - [ ] [[#3132](https://github.com/callemall/material-ui/pull/3132)] Scrollable Tabs. -- [X] [[#3033](https://github.com/callemall/material-ui/pull/3132)] New Subheader component. +- [x] [[#3033](https://github.com/callemall/material-ui/pull/3132)] New Subheader component. #### Documentation -- [ ] Documentation versioning. +- [x] [#1986](https://github.com/callemall/material-ui/issues/1986)]Documentation versioning. - [ ] Add example on how to use [react-list](https://github.com/orgsync/react-list) for lists, menu items and table. - [x] [[#2635](https://github.com/callemall/material-ui/pull/2635)] Document the new theme calculation, and it's usage. - [ ] [[#3191](https://github.com/callemall/material-ui/issues/3191)] Improve component property documentation. diff --git a/docs/gh-pages-build.js b/docs/gh-pages-build.js new file mode 100755 index 00000000000000..3d2fcfb5680caf --- /dev/null +++ b/docs/gh-pages-build.js @@ -0,0 +1,145 @@ +#!/usr/local/bin/node +/** + * Build a release for the gh-pages docs site. + */ + +var fs = require('fs'); +var execSync = require('child_process').execSync; + +var usage = '\nbuild | [-p]\n'; +var versionsFile = './src/www/versions.json'; + +// Read the command-line args +var args = process.argv; + +if (args.length < 3) { + exit(usage); +} + +var version = args[2]; + +// The regex isn't a perfect filter (it allows any component parts of a pre-release in the right order) +if (!version.match(/v\d{1,2}.\d{1,2}.\d{1,2}-?\w*\.?\d{0,2}/) && version !== 'HEAD') { + exit(usage); +} + +// Exit with a message +function exit(message) { + console.log(message,'\n'); + process.exit(); +} + +// Exec with echo +function execho(command) { + console.log(command); + try { + execSync(command, {stdio: 'inherit'}); + } catch (error) { + console.error(error.output[1]); + process.exit(error.status); + } +} + +// Exec with return value or error +function execReturn(command) { + console.log(command); + try { + return execSync(command, {encoding: 'utf8'}); + } catch (error) { + console.error(error.output[1]); + process.exit(error.status); + } +} + +function preRelease(version) { + return /-/.test(version) || version === 'HEAD'; +} + +function lastCommitIsHead() { + // All the versions + var log = execReturn('git log'); + + // Get the version number of the current commit (line 5, strip leading whitespace and trailing text) + var version = (log.split('\n')[4]+' ').replace(/\s*(\S*).*/, '$1'); + + return version === 'HEAD'; +} + +/** + * Build the docs site on a detached branch, commit it on gh-pages branch. + */ +function buildDocs() { + // Ensure we're starting in the docs dir + process.chdir(__dirname); + + // Checkout the tag 'version' + execho('git checkout gh-pages'); + + // Delete last HEAD commit to keep the history clean + if (lastCommitIsHead()) { + execho('git reset --hard HEAD~1'); + } + + // Checkout the tag 'version' + if (version === 'HEAD') { + execho('git checkout --detach master'); + } else { + execho('git checkout tags/' + version); + } + + // Build the docs site + execho('npm install && npm run browser:build'); + + // Version it + execho('mv build ../' + version); + + // Move to the gh-pages branch + execho('git checkout gh-pages'); + + // Symbolic link 'release' to latest version + if (!preRelease(version)) { + execho('ln -sfh ../' + version + ' ../release'); + } + + // Commit the new version + execho('git add .. && git commit -m \'' + version + '\''); + + if (args[3] === '-p') { + execho('git push -f'); + } +} + +/** + * Add new version number to versions.js + * The checks for HEAD can be removed once HEAD builds are automated, as the first entry will always be HEAD. + */ +function addMenuVersion(version) { + // Return to master + execho('git checkout master'); + + var versions = JSON.parse(fs.readFileSync(versionsFile, 'utf8')); + var head; + + // If HEAD is first in the array, shift it off. + if (versions[0] === 'HEAD') { + head = versions.shift() + } + + // Add the new version + versions.unshift(version); + + // If the array had a HEAD version, and we didn't just add one, put it back. + if (head && version !== 'HEAD') { + versions.unshift('HEAD'); + } + + fs.writeFileSync(versionsFile, JSON.stringify(versions, null, 2)); + + // If we're adding a new version, or first instance of 'HEAD', commit it (on master branch) + if (version !=='HEAD' || (version === 'HEAD' && !head)) { + execho('git add ' + versionsFile + ' && git commit -m ' + '\'Add ' + version + ' to versions.json\''); + } +} + +buildDocs(version); +addMenuVersion(version); diff --git a/docs/package.json b/docs/package.json index 504b69db086551..6e3d0882b26b06 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,6 +15,7 @@ "browser:development": "webpack-dev-server --config webpack-dev-server.config.js --progress --colors --inline", "browser:build": "NODE_ENV=docs-production webpack --config webpack-production.config.js --progress --colors --profile", "browser:prd": "NODE_ENV=docs-production webpack-dev-server --config webpack-production.config.js --progress --colors", + "gh-pages:build": "node ./gh-pages-build.js", "native:development": "node_modules/react-native/packager/packager.sh --reset-cache", "android:setup-port": "adb reverse tcp:8081 tcp:8081" }, diff --git a/docs/src/app/components/AppLeftNav.jsx b/docs/src/app/components/AppLeftNav.jsx index 9c1a268baeef37..60a208a2b16ec8 100644 --- a/docs/src/app/components/AppLeftNav.jsx +++ b/docs/src/app/components/AppLeftNav.jsx @@ -4,6 +4,8 @@ import List from 'material-ui/lib/lists/list'; import ListItem from 'material-ui/lib/lists/list-item'; import Divider from 'material-ui/lib/divider'; import Subheader from 'material-ui/lib/Subheader'; +import DropDownMenu from 'material-ui/lib/DropDownMenu'; +import MenuItem from 'material-ui/lib/menus/menu-item'; import {SelectableContainerEnhance} from 'material-ui/lib/hoc/selectable-enhance'; import { Spacing, @@ -30,6 +32,46 @@ const AppLeftNav = React.createClass({ router: React.PropTypes.object.isRequired, }, + getInitialState: () => { + return ({ + muiVersions: [], + }); + }, + + componentDidMount: function() { + const self = this; + const url = 'versions.json'; + const request = new XMLHttpRequest(); + + request.onreadystatechange = function() { + if (request.readyState === 4 && request.status === 200) { + self.setState({ + muiVersions: JSON.parse(request.responseText), + version: JSON.parse(request.responseText)[0], + }); + } + }; + + request.open('GET', url, true); + request.send(); + }, + + firstNonPreReleaseVersion: function() { + let version; + for (let i = 0; i < this.state.muiVersions.length; i++) { + version = this.state.muiVersions[i]; + // If the version doesn't contain '-' and isn't 'HEAD' + if (!/-/.test(version) && version !== 'HEAD') { + break; + } + } + return version; + }, + + handleVersionChange: function(event, index, value) { + window.location = value; + }, + handleRequestChangeLink(event, value) { window.location = value; }, @@ -39,19 +81,21 @@ const AppLeftNav = React.createClass({ this.props.onRequestChangeLeftNav(false); }, - getStyles() { - return { - logo: { - cursor: 'pointer', - fontSize: 24, - color: Typography.textFullWhite, - lineHeight: `${Spacing.desktopKeylineIncrement}px`, - fontWeight: Typography.fontWeightLight, - backgroundColor: cyan500, - paddingLeft: Spacing.desktopGutter, - marginBottom: 8, - }, - }; + styles: { + logo: { + cursor: 'pointer', + fontSize: 24, + color: Typography.textFullWhite, + lineHeight: `${Spacing.desktopKeylineIncrement}px`, + fontWeight: Typography.fontWeightLight, + backgroundColor: cyan500, + paddingLeft: Spacing.desktopGutter, + marginBottom: 8, + }, + version: { + paddingLeft: Spacing.desktopGutterLess, + fontSize: 16, + }, }, render() { @@ -64,11 +108,12 @@ const AppLeftNav = React.createClass({ style, } = this.props; - const { - prepareStyles, - } = this.context.muiTheme; - - const styles = this.getStyles(); + let currentVersion; + if (window.location.pathname === '/') { + currentVersion = this.firstNonPreReleaseVersion(); + } else { + currentVersion = window.location.pathname; + } return ( -
+
Material-UI
+ + Version: + + {this.state.muiVersions.map((version) => ( + + ))} + + diff --git a/docs/src/www/versions.json b/docs/src/www/versions.json new file mode 100644 index 00000000000000..9a8086113df706 --- /dev/null +++ b/docs/src/www/versions.json @@ -0,0 +1,44 @@ +[ + "v0.14.4", + "v0.14.3", + "v0.14.2", + "v0.14.1", + "v0.14.0", + "v0.13.4", + "v0.13.3", + "v0.13.2", + "v0.13.1", + "v0.13.0", + "v0.12.5", + "v0.12.4", + "v0.12.3", + "v0.12.2", + "v0.12.1", + "v0.12.0", + "v0.11.1", + "v0.11.0", + "v0.10.4", + "v0.10.3", + "v0.10.2", + "v0.10.1", + "v0.10.0", + "v0.9.2", + "v0.9.1", + "v0.9.0", + "v0.8.0", + "v0.7.5", + "v0.7.2", + "v0.7.1", + "v0.5.0", + "v0.7.4", + "v0.7.3", + "v0.7.0", + "v0.6.1", + "v0.6.0", + "v0.4.1", + "v0.4.0", + "v0.3.3", + "v0.3.2", + "v0.3.1", + "v0.3.0" +]