From d8c49101ea698f4a3bb386e0e94902835928773f Mon Sep 17 00:00:00 2001 From: Nick Novitski Date: Thu, 10 Jan 2019 15:45:01 -0800 Subject: [PATCH] [ci] Add build step to check docs for broken links --- .circleci/config.yml | 7 +++++++ bin/wget | 3 +++ docs/components/DocumentationHeader.js | 2 +- docs/components/DocumentationPage.js | 10 ++++++---- docs/components/DocumentationSidebarLink.js | 5 +++++ docs/mdjs/generate-navigation.js | 2 +- docs/mdjs/index.js | 10 ++++++---- docs/next.config.js | 13 ++++--------- docs/package.json | 4 +++- docs/robots.txt | 0 docs/scripts/import-react-native-docs.js | 14 ++++++++++++++ docs/scripts/test-links-all-versions.sh | 15 +++++++++++++++ docs/server.js | 17 +++++++---------- update-dependencies | 1 + 14 files changed, 73 insertions(+), 30 deletions(-) create mode 100755 bin/wget create mode 100644 docs/robots.txt create mode 100755 docs/scripts/test-links-all-versions.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index c0738a81033cfc..6c2de56f563480 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -343,6 +343,13 @@ jobs: - yarn: command: export working_directory: docs + - run: + working_directory: docs + command: nix run expo.python --command yarn run export-server + background: true + - run: + working_directory: docs + command: yarn run test-links:all http://localhost:8000 - deploy: command: | if [ "${CIRCLE_BRANCH}" == "master" ]; then diff --git a/bin/wget b/bin/wget new file mode 100755 index 00000000000000..54186853df19e4 --- /dev/null +++ b/bin/wget @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +# This file was generated by nix-binstubs +exec nix run -f "$(dirname "$0")/../nix" wget --command wget "$@" diff --git a/docs/components/DocumentationHeader.js b/docs/components/DocumentationHeader.js index 9881976758b4a4..f3b10752cd38a6 100644 --- a/docs/components/DocumentationHeader.js +++ b/docs/components/DocumentationHeader.js @@ -107,7 +107,7 @@ export default class DocumentationHeader extends React.PureComponent {
- + diff --git a/docs/components/DocumentationPage.js b/docs/components/DocumentationPage.js index c739566d66928e..5cdb70c7d82685 100644 --- a/docs/components/DocumentationPage.js +++ b/docs/components/DocumentationPage.js @@ -97,12 +97,14 @@ export default class DocumentationPage extends React.Component { _handleSetVersion = version => { this._version = version; + let newPath = '/versions/' + version; - if (version === 'latest') { - Router.push('/versions/' + LATEST_VERSION + '/', '/versions/' + version + '/'); - } else { - Router.push('/versions/' + version + '/', '/versions/' + version + '/'); + // TODO: Find what's stripping trailing slashes from these + if (version.startsWith('v')) { + newPath += '/' } + + Router.push(newPath + '/'); }; _handleShowMenu = () => { diff --git a/docs/components/DocumentationSidebarLink.js b/docs/components/DocumentationSidebarLink.js index 3ffed205f60b29..c275019ed070ea 100644 --- a/docs/components/DocumentationSidebarLink.js +++ b/docs/components/DocumentationSidebarLink.js @@ -39,6 +39,11 @@ const STYLES_DEFAULT = css` `; export default class DocumentationSidebarLink extends React.Component { + componentDidMount() { + // Consistent link behavior across dev server and static export + global.__NEXT_DATA__.nextExport = true + } + isSelected() { if (!this.props.url) { return false; diff --git a/docs/mdjs/generate-navigation.js b/docs/mdjs/generate-navigation.js index b88658bf8b9ee6..019a8a74b92eb7 100644 --- a/docs/mdjs/generate-navigation.js +++ b/docs/mdjs/generate-navigation.js @@ -74,7 +74,7 @@ const generateNavLinks = (path_, arr) => { let items = fs.readdirSync(path_); let processUrl = path => { - let newPath = path.replace(/^versions/, '/versions').replace(/.md$/, '/'); + let newPath = path.replace(/^versions/, '/versions').replace(/.md$/, ''); return newPath; }; diff --git a/docs/mdjs/index.js b/docs/mdjs/index.js index 38a087a85476b1..2c0ae1216d4273 100644 --- a/docs/mdjs/index.js +++ b/docs/mdjs/index.js @@ -75,12 +75,14 @@ export default redirect('/versions/latest/'); console.timeEnd('Compiling *.md files to *.js'); -// symlink versions/latest to versions/v(latest version) +// copy versions/v(latest version) to versions/latest +// (next only half-handles symlinks) const LATEST_VERSION = 'v' + require('../package.json').version; -vLatest = path.join(DESTINATION_PATH_PREFIX, LATEST_VERSION); -latest = path.join(DESTINATION_PATH_PREFIX, "latest"); +const vLatest = path.join(DESTINATION_PATH_PREFIX, LATEST_VERSION + "/"); +const latest = path.join(DESTINATION_PATH_PREFIX, "latest/"); +console.log(vLatest, latest); fs.removeSync(latest) -fs.ensureSymlink(vLatest, latest) +fs.copySync(vLatest, latest) // Watch for changes in directory if (process.argv.length < 3) { diff --git a/docs/next.config.js b/docs/next.config.js index ad0b0698a6f522..662ddb89948a5c 100644 --- a/docs/next.config.js +++ b/docs/next.config.js @@ -1,10 +1,12 @@ -const LATEST_VERSION = 'v' + require('./package.json').version; +const { join } = require('path'); +const { copyFileSync } = require('fs-extra'); module.exports = { - async exportPathMap(defaultPathMap, {dev}) { + async exportPathMap(defaultPathMap, {dev, dir, outDir}) { if (dev) { return defaultPathMap } + copyFileSync(join(dir, 'robots.txt'), join(outDir, 'robots.txt')) return Object.assign( ...Object.entries(defaultPathMap).map(([pathname, page]) => { if (pathname.match(/\/v[1-9][^\/]*$/)) { @@ -14,13 +16,6 @@ module.exports = { result = { [pathname]: page }; - // For every path which doesn't end in ".html" (except "/"), create a matching copy with ".html" added - // (We have many internal links of this sort) - if (! pathname.match(/\.html$/) && pathname.match(/[a-z]$/)) { - result[pathname + ".html"] = page; - } - - return result; }) ); diff --git a/docs/package.json b/docs/package.json index d97421f51269cb..d4aa8d3f5f75f5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,7 +11,9 @@ "mdjs-prod": "node ./mdjs --no-watch", "fix-markdown": "node ./transition/fix-markdown.js", "clean": "rm -r docs pages/versions generated/navigation-data.json static/images/generated", - "import-react-native-docs": "node ./scripts/import-react-native-docs.js" + "import-react-native-docs": "node ./scripts/import-react-native-docs.js", + "test-links": "wget --page-requisites --spider --random-wait --recursive", + "test-links:all": "scripts/test-links-all-versions.sh" }, "dependencies": { "babel-plugin-module-resolver": "3.1.1", diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/docs/scripts/import-react-native-docs.js b/docs/scripts/import-react-native-docs.js index f3b8f6ab5dd428..83453936f0feb8 100755 --- a/docs/scripts/import-react-native-docs.js +++ b/docs/scripts/import-react-native-docs.js @@ -74,6 +74,20 @@ let mainAsync = async () => { '(https://facebook.github.io/react-native/docs/more-resources.html)' ); + l.replace( + /\[`Toolbar` widget\]\([^\)]+\)/, + '[`Toolbar` widget](https://developer.android.com/reference/android/support/v7/widget/Toolbar.html)' + ); + l.replace( + /\[navigator\.geolocation\]\([^\)]+\)/g, + '[navigator.geolocation](../../sdk/location/)' + ); + + l.replace( + /\[CameraRoll\]([^\)]+\)/g, + '[CameraRoll](https://facebook.github.io/react-native/docs/cameraroll.html)' + ); + // `](./foo` -> `](foo` l = l.replace( /\]\(\.\/([^\):]+)/g, diff --git a/docs/scripts/test-links-all-versions.sh b/docs/scripts/test-links-all-versions.sh new file mode 100755 index 00000000000000..de6153a474ade6 --- /dev/null +++ b/docs/scripts/test-links-all-versions.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +root=$1 +docsDir="$(dirname "$0")/.." + +pushd "$docsDir" + +# TODO: add hidden links between version pages and delete this script + +for v in versions/latest $(ls -d versions/v*); do + yarn run test-links "$root/$v" +done + +popd diff --git a/docs/server.js b/docs/server.js index 33d54744223636..fbe2161995e874 100644 --- a/docs/server.js +++ b/docs/server.js @@ -9,7 +9,6 @@ const app = next({ dev }); const port = 3000; const handle = app.getRequestHandler(); -const LATEST_VERSION = 'v' + require('./package.json').version; const { WORKFLOW, DISTRIBUTION, EXPOKIT } = require('./transition/sections'); const CATEGORY_ALIASES = [ { path: 'workflow', files: WORKFLOW }, @@ -50,26 +49,24 @@ app.prepare().then(() => { } // NOTE(jim): Mutations have to line up with FS paths provided by mdjs. - server.get('/versions/:version/:category/:post', (req, res) => { + server.get('/versions/:version/:category/:post/', (req, res) => { const { query } = parse(req.url, true); let { version, category, post } = req.params; - post = stripTrailingSlashAndExtensions(post); - - if (version === 'latest') { - version = LATEST_VERSION; - } - category = mutateCategoryWithRedirectAlias(category, post); const updatedPath = `/versions/${version}/${category}/${post}`; - req.originalPath = updatedPath; app.render(req, res, updatedPath, query); }); + server.get('/', (req, res) => { + const { pathname, query } = parse(req.url, true); + app.render(req, res, pathname, query) + }) + server.get('*', (req, res) => { const { pathname, query } = parse(req.url, true); - app.render(req, res, pathname, query); + app.render(req, res, pathname.slice(0,-1), query); }); server.listen(port, err => { diff --git a/update-dependencies b/update-dependencies index a5ce94cafc844d..3b2614448c4641 100755 --- a/update-dependencies +++ b/update-dependencies @@ -27,6 +27,7 @@ bin/nix-binstubs \ git-lfs \ nodePackages.gulp-cli \ nodejs-10_x \ + wget \ xcpretty \ yarn