diff --git a/.circleci/config.yml b/.circleci/config.yml index bd3eb3e12..5a473473c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,4 +1,4 @@ -version: 2 +version: 2.1 jobs: build: machine: @@ -7,24 +7,6 @@ jobs: parallelism: 10 steps: - checkout - - run: - name: Assess needs or bail - command: | - # Extract commit range (or single commit) - COMMIT_RANGE=$(echo "${CIRCLE_COMPARE_URL}" | cut -d/ -f7) - # Fix single commit, unfortunately we don't always get a commit range from Circle CI - if [[ $COMMIT_RANGE != *"..."* ]]; then - COMMIT_RANGE="${COMMIT_RANGE}...${COMMIT_RANGE}" - fi - # Print some helpful things - echo "Operating on commit range: $COMMIT_RANGE" - # Check if we need to run tests and bail if we don't - LANDO_CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE | cat) - echo "The following files have changed: $LANDO_CHANGED_FILES" - LANDO_NEEDS_TESTS=$(echo $LANDO_CHANGED_FILES | grep -e .circleci -e bin/ -e lib/ -e plugins/ -e integrations/ -e examples/ -e tests/ &>/dev/null && echo true || echo false) - if [[ "$LANDO_NEEDS_TESTS" == "false" ]]; then - circleci-agent step halt - fi - restore_cache: keys: - yarn-packages-v1-{{ .Branch }}-{{ checksum "yarn.lock" }} @@ -50,6 +32,8 @@ jobs: /tmp/hyperdrive -y --name "Lando System" --email landobot@devwithlando.io # @TODO: anyway hyperdrive can assert dominance here? sudo ln -sf /usr/bin/nodejs /opt/circleci/.nvm/versions/node/v6.1.0/bin/node + # We need to not enforce ssh for github because this breaks some tests + git config --global --unset url.ssh://git@github.com.insteadof - run: name: Install node modules command: yarn diff --git a/.circleci/lando.yml b/.circleci/lando.yml index ccd357546..f37d7186a 100644 --- a/.circleci/lando.yml +++ b/.circleci/lando.yml @@ -6,12 +6,12 @@ mode: cli dockerSupportedVersions: compose: min: "1.23.0" - max: "1.27.4" + max: "1.29.0" link: linux: https://docs.docker.com/compose/install/#install-compose-on-linux-systems desktop: min: "2.1.0.0" - max: "3.0.1" + max: "3.3.99" link: darwin: https://docs.docker.com/docker-for-mac/release-notes/ win32: https://docs.docker.com/docker-for-windows/release-notes/ diff --git a/.platform/.platform.docs.yaml b/.platform/.platform.docs.yaml index 640ce8aaf..099fa8e2c 100644 --- a/.platform/.platform.docs.yaml +++ b/.platform/.platform.docs.yaml @@ -12,7 +12,7 @@ build: flavor: none # The size of the persistent disk of the application (in MB). -disk: 5000 +disk: 4000 # The configuration of app when it is exposed to the web. web: diff --git a/.platform/.platform.metrics.yaml b/.platform/.platform.metrics.yaml index 2aabc29db..69ae8d7a5 100644 --- a/.platform/.platform.metrics.yaml +++ b/.platform/.platform.metrics.yaml @@ -1,7 +1,7 @@ name: metrics source: root: "/" -type: nodejs:14 +type: nodejs:12 dependencies: nodejs: @@ -26,7 +26,7 @@ mounts: source: local source_path: run -disk: 5000 +disk: 6000 hooks: build: | @@ -49,3 +49,8 @@ crons: if [ "$PLATFORM_BRANCH" = master ]; then /app/.platformsh/bin/platform redeploy --yes --no-wait fi + flushlogs: + # Flush the PM2 logs once a month + spec: '0 1 1 * *' + cmd: | + PM2_HOME=/app/run pm2 flush diff --git a/.travis.yml b/.travis.yml index 5cb31b5bc..ce9e023f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: 12 -dist: xenial +dist: bionic cache: yarn: true directories: @@ -194,10 +194,10 @@ jobs: - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.deb release/lando-$TRAVIS_TAG.deb; fi - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.deb release/lando-stable.deb; fi # pacman - - cp -rf dist/lando.pacman release/lando-latest-dev.pacman - - cp -rf dist/lando.pacman release/lando-$TRAVIS_COMMIT-dev.pacman - - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.pacman release/lando-$TRAVIS_TAG.pacman; fi - - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.pacman release/lando-stable.pacman; fi + # - cp -rf dist/lando.pacman release/lando-latest-dev.pacman + # - cp -rf dist/lando.pacman release/lando-$TRAVIS_COMMIT-dev.pacman + # - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.pacman release/lando-$TRAVIS_TAG.pacman; fi + # - if [ ! -z "$TRAVIS_TAG" ]; then cp -rf dist/lando.pacman release/lando-stable.pacman; fi # rpm - cp -rf dist/lando.rpm release/lando-latest-dev.rpm - cp -rf dist/lando.rpm release/lando-$TRAVIS_COMMIT-dev.rpm @@ -221,7 +221,7 @@ jobs: secure: UXDea6KLTOOiUaUfhYqE7stUY74VE2gOdi3No5NscD0Lg3xB/EMf1wzpVe2nuTpjn1CbDBsGXXHqRRpy2IZj6qp21D39+Wygznv9PpSGPgTAB2ZHRYhpux1Qf/HxD8R/NhvISNMXukNLyd66OyiJlz5RWoLWQvLIiJgT1Uczc3Sj8iOJOmYaxQZku/3/q/LmjKKHVJ9vq7ail4l4SoNmLqh6sdDt9utJtavWHMa0hN5kF+CwoV5Vk/z2RFzYNInGwlJggwV7Y/Kf3TmOQv0CiKgxdEQqR8LfTDGIvkxFwpPSf7JnQYnsZWcOWW08oousN7tjc1L1ow2dzPnT2zRYNyx73FwkjWtZ7SLQCkU95pq6FgSy31+w6iWU6Rvwd9mgdX4sfxgdwxLwiF38Rki5TxXtMRGWW1qYRYvnCcc7gpPUPFv0PzsQYZiFSGxMF3uKdKxmKzYd+tfCMvE5YhfkDtCM+LeJBlSL5hZspMUezXEFtiKSv7fDmBKtGGFUsEruNqMphKEbH1kY1UT9SXUu+uxWN40ciJTXfQXJAGMSh34WkZFAgEP/r61+SZDlpuyYPQ8l8fOOcX2uaJYD0LJBSERVmVAX00SNxWSVdTTGibadRXWWuJ4gd4PGCXUhSJI9r1QLfMLyZtt5P3i9SUL2X4cO9isKysBjOq/5DZXjqq0= file: - release/lando-$TRAVIS_TAG.deb - - release/lando-$TRAVIS_TAG.pacman + # - release/lando-$TRAVIS_TAG.pacman - release/lando-$TRAVIS_TAG.rpm skip_cleanup: true on: diff --git a/config.yml b/config.yml index 8b66ddf86..62f62c1d1 100644 --- a/config.yml +++ b/config.yml @@ -6,12 +6,12 @@ mode: cli dockerSupportedVersions: compose: min: "1.23.0" - max: "1.27.4" + max: "1.29.0" link: linux: https://docs.docker.com/compose/install/#install-compose-on-linux-systems desktop: min: "2.1.0.0" - max: "3.0.1" + max: "3.3.99" link: darwin: https://docs.docker.com/docker-for-mac/release-notes/ win32: https://docs.docker.com/docker-for-windows/release-notes/ diff --git a/contributors.yml b/contributors.yml index b678406e3..00a76250b 100644 --- a/contributors.yml +++ b/contributors.yml @@ -191,3 +191,10 @@ title: Contributor pic: 'https://www.gravatar.com/avatar/b497056d7679e425fdb3d6f7fca7d05b' id: a42fa56eb47d917eeb086338cdc37efb635bef51 +- name: Xaq Rothman + location: 'Washington, D.C.' + github: xaqrox + twitter: xaqrox + title: Contributor + pic: 'https://www.gravatar.com/avatar/c335f31e62b453f747f39a84240b3bbd' + id: 443e9ca6ae16555ec9d336447aaac3a944eebf5b diff --git a/core/art.js b/core/art.js new file mode 100644 index 000000000..6799b5d62 --- /dev/null +++ b/core/art.js @@ -0,0 +1,421 @@ +'use strict'; + +// Modules +const _ = require('lodash'); +const niceFont = require('yargonaut').asFont; +const chalk = require('yargonaut').chalk(); +const os = require('os'); + +/* + * Helper to stylize code or a command + */ +const codeMe = text => chalk.italic(text); + +/* + * Helper to stylize an italicize + */ +const italicize = name => chalk.italic(name); + +/* + * Helper to stylize a warning message + */ +const warningMessage = ({title, detail = [], command = '', url = ''} = {}) => ` + ${chalk.yellow(`■ ${title}`)} + ${detail.join(`${os.EOL} `)} + ${(url) ? chalk.green(url) : codeMe(command)} +`; + +/* + * Helper to show that an app has started + */ +exports.appDestroy = ({name, phase = 'pre'} = {}) => { + switch (phase) { + case 'abort': + return chalk.yellow('DESTRUCTION AVERTED!'); + case 'pre': + return chalk.cyan(`Preparing to consign ${italicize(name)} to the dustbin of history...`); + case 'post': + return [ + chalk.red(`The app known as ${italicize(name)} has paid the ${chalk.bold('IRON PRICE')}. App destroyed!`), + ].join(os.EOL); + } +}; + +/* + * Helper to show that an app has restarted + */ +exports.appRebuild = ({name, phase = 'pre', warnings = {}} = {}) => { + switch (phase) { + case 'abort': + return chalk.yellow('REBUILD ABORTED!'); + case 'error': + return exports.appStart({name, phase: 'error', warnings}); + case 'pre': + return chalk.cyan('Rising anew like a fire phoenix from the ashes! Rebuilding app...'); + case 'post': + return exports.appStart({name, phase: 'post'}); + case 'report': + return exports.appStart({name, phase: 'report', warnings}); + } +}; + +/* + * Helper to show that an app has restarted + */ +exports.appRestart = ({name, phase = 'pre', warnings = {}} = {}) => { + switch (phase) { + case 'error': + return exports.appStart({name, phase: 'error', warnings}); + case 'pre': + return chalk.cyan('Stopping and restarting your app...Shiny!'); + case 'post': + return exports.appStart({name, phase: 'post'}); + case 'report': + return exports.appStart({name, phase: 'report', warnings}); + } +}; + +/* + * Helper to show that an app has started + */ +exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => { + switch (phase) { + case 'error': + return [ + '', + chalk.red(niceFont('Uh oh!', 'ANSI Shadow')), + '', + 'An error occurred while starting up your app!', + 'Here are a few things you can try to get back into a good state:', + '', + chalk.yellow(` ■ Try running ${codeMe('lando rebuild')}`), + chalk.yellow(` ■ Try restarting in debug mode ${codeMe('lando restart -vvv')}`), + chalk.yellow(` ■ Try checking the logs with ${codeMe('lando logs')}`), + '', + 'If those fail then consult the troubleshooting materials:', + '', + chalk.magenta(' ■ https://docs.lando.dev/help/logs.html'), + chalk.magenta(' ■ https://docs.lando.dev/help/updating.html'), + '', + 'Or post your issue to Slack or GitHub', + '', + chalk.green(' ■ Slack - https://launchpass.com/devwithlando'), + chalk.green(' ■ GitHub - https://github.com/lando/lando/issues/new/choose'), + '', + ].join(os.EOL); + case 'pre': + return chalk.cyan(`Let\'s get this party started! Starting app ${italicize(name)}...`); + case 'post': + return [ + '', + chalk.magenta(niceFont('Boomshakalaka!!!', 'Small Slant')), + '', + 'Your app has started up correctly.', + 'Here are some vitals:', + '', + ].join(os.EOL); + case 'report': + const message = [ + '', + chalk.yellow(niceFont('Warning!', 'Small Slant')), + '', + 'Your app started up but we detected some things you may wish to investigate.', + `These only ${italicize('may')} be a problem.`, + '', + ]; + + // Add in all our warnings + _.forEach(warnings, warning => { + message.push(warningMessage(warning)); + }); + + message.push(''); + message.push('Here are some vitals:'); + message.push(''); + return message.join(os.EOL); + } +}; + +/* + * Helper to show that an app has stopped + */ +exports.appStop = ({name, phase = 'pre'} = {}) => { + switch (phase) { + case 'pre': + return chalk.cyan(`This party\'s over :( Stopping app ${italicize(name)}`); + case 'post': + return chalk.red(`App ${italicize(name)} has been stopped!`); + } +}; + +/* + * Helper to show that a first error has occurred + */ +exports.crash = () => [ + '', + chalk.red(niceFont('CRASH!!!', 'ANSI Shadow')), + '', + 'Would you like to report it, and subsequent crashes, to Lando?', + '', + 'This data is only used by the Lando team to ensure the application runs as well as it can.', + chalk.green('For more details check out https://docs.lando.dev/privacy/'), +].join(os.EOL); + +/* + * Helper to show status of experimental toggle + */ +exports.experimental = (on = false) => { + switch (on) { + case true: + return [ + '', + chalk.green(niceFont('Activated!!!', 'Small Slant')), + chalk.magenta('Experimental features are now ON'), + '', + ].join(os.EOL); + case false: + return [ + '', + chalk.red(niceFont('Deactivated!', 'Small Slant')), + chalk.grey('Experimental features are now OFF'), + '', + ].join(os.EOL); + } +}; + +/* + * Helper to show init header + */ +exports.init = () => [ + '', + chalk.green(niceFont('Now we\'re', 'Small Slant')), + chalk.magenta(niceFont('COOKING WITH FIRE!', 'Small Slant')), + 'Your app has been initialized!', + '', + `Go to the directory where your app was initialized and run ${codeMe('lando start')} to get rolling.`, + 'Check the LOCATION printed below if you are unsure where to go.', + '', + 'Oh... and here are some vitals:', + '', +].join(os.EOL); + +/* + * Helper to show new content + */ +exports.newContent = (type = 'guide') => [ + '', + chalk.green(niceFont(`New ${type} has been...`, 'Small Slant')), + chalk.magenta(niceFont('Created!', 'Small Slant')), + '', + `Make sure you have run ${codeMe('lando start')} to get the docs running locally.`, + '', + 'Oh... and here are some vitals about your new content:', + '', +].join(os.EOL); + +/* + * Helper to show NO DOCKER error message + */ +exports.noDockerDep = (dep = 'Docker') => [ + '', + chalk.red(niceFont('Uh oh!', 'ANSI Shadow')), + '', + `Lando could not detect an installation of ${dep}, which is a required dependency!`, + 'This most often happens if you have installed from source and have not RTFM.', + '', + 'We recommend you check out the Install From Source docs and make sure you have', + 'manually installed all the needed dependencies first.', + chalk.green('https://docs.lando.dev/basics/installation.html#from-source'), + '', + 'When you have completed the above, try running Lando again. If you still have issues', + 'we recommend you install Lando from the latest package installer as this will install', + 'and setup the needed dependencies for you.', + chalk.green('https://github.com/lando/lando/releases'), + '', + 'If you are still having issues after that we recommend you post an issue on Github', + 'or ping us in the Slack channel', + '', + chalk.magenta(' ■ Slack - https://launchpass.com/devwithlando'), + chalk.magenta(' ■ GitHub - https://github.com/lando/lando/issues/new/choose'), + '', +].join(os.EOL); + +/* + * Helper to show status of secret toggle + */ +exports.poweroff = ({phase = 'pre'} = {}) => { + switch (phase) { + case 'pre': + return [ + '', + chalk.cyan('NO!! SHUT IT ALL DOWN!!!'), + chalk.magenta(niceFont('Powering off...', 'Small Slant')), + '', + ].join(os.EOL); + case 'post': + return chalk.green('Lando containers have been spun down.'); + } +}; + +/* + * Helper to show status of secret toggle + */ +exports.print = ({text, color = 'white'} = {}) => { + return chalk[color](text); +}; + +/* + * Helper to show status of secret toggle + */ +exports.printFont = ({text, color = 'magenta', font = 'Small Slant'} = {}) => { + return chalk[color](niceFont(text, 'Small Slant')); +}; + +/* + * Helper to show status of release channel + */ +exports.releaseChannel = (channel = 'stable') => { + switch (channel) { + case 'edge': + return [ + '', + chalk.green('You are now living on the'), + chalk.magenta(niceFont('EDGE', 'Small Slant')), + 'Lando will update you about ALL new releases!', + '', + ].join(os.EOL); + case 'none': + return [ + '', + chalk.green('You will no longer receive update notifications.'), + chalk.yellow(niceFont('WARNING', 'Small Slant')), + 'If you do not continue to update manually this may limit our ability to support you!', + '', + ].join(os.EOL); + case 'stable': + return [ + '', + chalk.green('Slowing things down to get more'), + chalk.magenta(niceFont('STABLE', 'Small Slant')), + 'Lando will only update you about new stable releases!', + '', + ].join(os.EOL); + } +}; + +/* + * Helper to show status of secret toggle + */ +exports.secretToggle = (on = false) => { + switch (on) { + case true: + return [ + '', + chalk.green(niceFont('Activated!!!', 'Small Slant')), + chalk.magenta('The secret toggle is now ON'), + '', + `Rerun ${codeMe('lando')} to see the secret commands `, + '', + ].join(os.EOL); + case false: + return [ + '', + chalk.red(niceFont('Deactivated!', 'Small Slant')), + chalk.grey('The secret toggle is now OFF'), + '', + ].join(os.EOL); + } +}; + +/* + * Helper to show status of secret toggle + */ +exports.secretToggleDenied = (on = false) => [ + '', + chalk.red(niceFont('Toggle Denied!', 'Small Slant', true)), + '', + chalk.magenta('You can only toggle the secret toggle when running Lando from source'), + 'See https://docs.lando.dev/contrib/activate.html', + '', +].join(os.EOL); + +/* + * Sharing under construction + */ +exports.shareWait = () => [ + '', + chalk.red(niceFont('OFFLINE!!!', 'ANSI Shadow')), + '', + 'localtunnel.me has finally sunsetted it\'s free service. Lando thanks them for their great and free service.', + '', + 'We are hard at work on a new sharing solution but it is not quite ready!', + '', + 'Due to our massive user base we might not be able to offer free sharing to all users.', + 'So, if you are interested in using our new sharing service we recommend you sponsor at the link below!', + chalk.green('https://lando.dev/sponsor'), + '', +].join(os.EOL); + +/* + * Helper to show status of secret toggle + */ +exports.sudoRun = () => [ + chalk.red('Lando should never ever ever be run as root...'), + chalk.magenta(niceFont('like ever!!!', 'Small Slant')), +].join(os.EOL); + +/* + * Helper to show status of secret toggle + */ +exports.tunnel = ({url, phase = 'pre'} = {}) => { + switch (phase) { + case 'pre': + return chalk.cyan('About to share your app to a whole new world!'); + case 'post': + return [ + '', + chalk.magenta(niceFont('Connected!!!', 'Small Slant')), + 'A tunnel to your local Lando app been established.', + '', + 'Here is your public url:', + chalk.green(url), + '', + 'Press any key to close the tunnel...', + ].join(os.EOL); + case 'closed': + return chalk.green('Tunnel closed!'); + } +}; + +/* + * Update available + */ +exports.updateAvailable = url => [ + '', + chalk.magenta(niceFont('Update Available!!!', 'Small Slant')), + '', + 'Updating helps us provide the best support and saves us tons of time', + '', + 'Use the link below to get the latest and greatest', + chalk.green(url), + '', + `Lando is ${chalk.bold('FREE')} and ${chalk.bold('OPEN SOURCE')} software that relies on contributions` + + ` from developers like you!`, + 'If you like Lando then help us spend more time making, updating and supporting it by contributing at the link below', + chalk.green('https://github.com/sponsors/lando'), + '', + 'If you would like to customize the behavior of this message then check out:', + chalk.green('https://docs.lando.dev/config/releases.html'), +].join(os.EOL); + +exports.badToken = () => { + return warningMessage({ + title: 'Invalid Machine Token', + detail: [ + 'Your machine token has been rejected by Pantheon. It may have been revoked or corrupted.', + 'Please use a different token.', + 'You can generate a new token using this link:', + ], + url: 'https://dashboard.pantheon.io/machine-token/create/Lando', + }); +}; diff --git a/core/formatters.js b/core/formatters.js new file mode 100644 index 000000000..5c334aa5e --- /dev/null +++ b/core/formatters.js @@ -0,0 +1,123 @@ +'use strict'; + +// Modules +const _ = require('lodash'); +const os = require('os'); +const util = require('util'); + +// Const +const formats = ['default', 'json', 'table']; +const formatOpts = { + format: { + describe: `Output in given format: ${formats.join(', ')}`, + choices: formats, + string: true, + }, + path: { + describe: 'Only return the value at the given path', + default: null, + string: true, + }, + filter: { + describe: 'Filter data by "key=value"', + array: true, + }, +}; + +/* + * Format data + */ +exports.formatData = (data, {path = '', format = 'default', filter = []} = {}, opts = {}) => { + // Attempt to filter if we can + if (_.isArray(data) && !_.isEmpty(filter)) { + const filters = _(filter).map(f => f.split('=')).fromPairs().value(); + data = _.filter(data, filters); + } + // Attempt to get a path if we can + if (_.isObject(data) && !_.isEmpty(path)) { + data = _.get(data, path, data); + } + // data = _.get(data, path, data); + switch (format) { + case 'json': + return JSON.stringify(data); + break; + case 'table': + const Table = require('./table'); + if (!_.isArray(data)) { + const table = new Table(data, opts); + return table.toString(); + } + return _(data) + .map((value, index) => new Table(value, opts)) + .map(table => table.toString()) + .thru(data => data.join(os.EOL)) + .value(); + break; + default: + return util.inspect(data, { + colors: process.stdout.isTTY, + depth: 10, + compact: true, + sorted: _.get(opts, 'sort', false), + }); + } +}; + +/* + * FormatOptios + */ +exports.formatOptions = (omit = []) => _.omit(formatOpts, omit); + +/* + * Helper to get interactive options + */ +exports.getInteractive = (options, argv) => _(options) + .map((option, name) => _.merge({}, {name}, {option})) + .filter(option => !_.isEmpty(_.get(option, 'option.interactive', {}))) + .map(option => _.merge({}, {name: option.name, weight: 0}, option.option.interactive)) + .map(option => { + if (_.isNil(argv[option.name]) || argv[option.name] === false) return option; + else { + return _.merge({}, option, {when: answers => { + answers[option.name] = argv[option.name]; + return false; + }}); + } + }) + .value(); + +/* + * Helper to prompt the user if needed + */ +exports.handleInteractive = (inquiry, argv, command, lando) => lando.Promise.try(() => { + if (_.isEmpty(inquiry)) return {}; + else { + const inquirer = require('inquirer'); + inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt')); + // Try to rebuild the inquiry if this is app level bootstrap and we have an app + if (!_.isEmpty(argv._app) && lando._bootstrap === 'app') { + // NOTE: We need to clone deep here otherwise any apps with interactive options get 2x all their events + // NOTE: Not exactly clear on why app here gets conflated with the app returned from lando.getApp + const app = _.cloneDeep(lando.getApp(argv._app.root)); + return app.init().then(() => { + inquiry = exports.getInteractive(_.find(app.tasks.concat(lando.tasks), {command: command}).options, argv); + return inquirer.prompt(_.sortBy(inquiry, 'weight')); + }); + // Otherwise just run + } else { + inquiry = exports.getInteractive(_.find(lando.tasks, {command: command}).options, argv); + return inquirer.prompt(_.sortBy(inquiry, 'weight')); + } + } +}); + +/* + * Helper to sort options + */ +exports.sortOptions = options => _(options) + .keys() + .sortBy() + .map(key => [key, options[key]]) + .fromPairs() + .value(); diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 2ac58356d..4d2490208 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -142,6 +142,7 @@ module.exports = { title: 'Recipes', collapsable: false, children: [ + 'acquia', 'backdrop', 'drupal6', 'drupal7', @@ -235,6 +236,7 @@ module.exports = { title: 'Changelog', collapsable: false, children: [ + '2021-changelog', '2020-changelog', '2019-changelog', '2018-changelog', @@ -318,6 +320,7 @@ module.exports = { collapsable: false, children: [ 'sponsor-intro', + 'sponsor-upsell', 'sponsor-faq', ], }, diff --git a/docs/.vuepress/guides.json b/docs/.vuepress/guides.json index 422d0895c..7a01b58eb 100644 --- a/docs/.vuepress/guides.json +++ b/docs/.vuepress/guides.json @@ -1,23 +1,4 @@ [ - { - "title": "Lando Courses", - "collapsable": false, - "children": [ - { - "title": "Lando 101", - "collapsable": true, - "children": [ - "lando-101/lando-overview", - "lando-101/lando-init", - "lando-101/lando-start", - "lando-101/lando-config", - "lando-101/lando-services", - "lando-101/lando-proxy", - "lando-101/lando-tooling" - ] - } - ] - }, { "title": "Databases", "collapsable": false, @@ -39,7 +20,8 @@ "children": [ "how-do-i-configure-a-lando-recipe", "how-do-i-set-the-timezone-of-a-lando-service", - "lando-info" + "lando-info", + "setup-lando-on-windows-with-wsl-2" ] }, { @@ -50,6 +32,25 @@ "lando-with-vscode" ] }, + { + "title": "Lando Courses", + "collapsable": false, + "children": [ + { + "title": "Lando 101", + "collapsable": true, + "children": [ + "lando-101/lando-overview", + "lando-101/lando-init", + "lando-101/lando-start", + "lando-101/lando-config", + "lando-101/lando-services", + "lando-101/lando-proxy", + "lando-101/lando-tooling" + ] + } + ] + }, { "title": "Networking", "collapsable": false, @@ -120,4 +121,4 @@ "updating-to-rc2" ] } -] +] \ No newline at end of file diff --git a/docs/.vuepress/theme/components/Footer.vue b/docs/.vuepress/theme/components/Footer.vue index e1598df40..f61f4d910 100644 --- a/docs/.vuepress/theme/components/Footer.vue +++ b/docs/.vuepress/theme/components/Footer.vue @@ -54,6 +54,7 @@