Skip to content

Commit

Permalink
prep for lando mgmt commands (#228)
Browse files Browse the repository at this point in the history
* bump to latest @lando/core-next

* add interactive boole to cli config

* add powershell scripts to cli pkg

* update to latest @lando/core

* rework addWarning to be more generic

* improve status messages and app start stuff

* update to new messaging framework

* update to new messaging framework part 2

* allow plugins to be loaded from cli node_modules, again

* remove CLI update checks

* lando version is now governed by the @lando/core version

* add additional CLI metadata

* update to latest @lando/core

* fix tests

* skip common plugins on @lando/setup-lando for now

* update to latest @lando/core
  • Loading branch information
pirog authored Dec 3, 2023
1 parent ce8789f commit 47bcfed
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 163 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/pr-runtime-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ jobs:
git diff
# package cli so we can use that in setup lando
# @TODO: remove skip-common-plugins when fatcore stuff is done
- name: Package CLI
run: yarn cli:build
- name: Setup locally built lando
uses: lando/setup-lando@v2
with:
lando-version: ./dist/@lando/cli
telemetry: false
config: |
setup.skipCommonPlugins=true
- name: Verify we can run the packaged CLI in both runtimes
run: |
# v3 things
Expand Down
174 changes: 107 additions & 67 deletions lib/art.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,70 @@
const _ = require('lodash');
const niceFont = require('yargonaut').asFont;
const chalk = require('yargonaut').chalk();
const figures = require('figures');
const os = require('os');

/*
* Helper to stylize code or a command
*/
const codeMe = text => chalk.italic(text);
const codeMe = text => `Run ${chalk.bold(text)}`;

/*
* Helper to stylize an italicize
*/
const italicize = name => chalk.italic(name);

/*
* determines the "best" header message to display
*/
const getHeader = (messages = []) => {
const types = messages.map(message => message.type);
// error
if (types.includes('error')) return chalk.red(niceFont('UH OH!', 'ANSI Shadow'));
// warning
else if (types.includes('warning')) return chalk.yellow(niceFont('Warning!', 'Small Slant'));
else if (types.includes('warn')) return chalk.yellow(niceFont('Warning!', 'Small Slant'));
// tip/info
else if (types.includes('info')) return chalk.cyan(niceFont('Boomshakalaka!!!!', 'Small Slant'));
else if (types.includes('tip')) return chalk.cyan(niceFont('Boomshakalaka!!!!', 'Small Slant'));
// everything else
else return chalk.magenta(niceFont('Boomshakalaka!!!!', 'Small Slant'));
};

const getStyle = (type = 'tip') => {
switch (type) {
case 'error':
return {color: 'red', figure: figures.cross};
case 'warn':
case 'warning':
return {color: 'yellow', figure: figures.warning};
case 'info':
case 'tip':
default:
return {color: 'cyan', figure: figures.info};
}
};

/*
* 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)}
`;
const statusMessage = ({title, type = 'info', detail = [], command, url} = {}) => {
const style = getStyle(type);
const message = [chalk[style.color](`${style.figure} ${title}`)];

// if we have detail add that
if (detail.length > 0) detail.map(line => message.push(` ${line}`));

// if we have a url then add that
if (url) message.push(` ${chalk.green(url)}`);
else if (command) message.push(` ${codeMe(command)}`);

// add some padding
message.push('');

// return
return message.map(line => ` ${line}`).join(os.EOL);
};

/*
* Helper to show that an app has started
Expand All @@ -44,79 +88,79 @@ exports.appDestroy = ({name, phase = 'pre'} = {}) => {
/*
* Helper to show that an app has restarted
*/
exports.appRebuild = ({name, phase = 'pre', warnings = {}} = {}) => {
exports.appRebuild = ({name, phase = 'pre', messages = {}} = {}) => {
switch (phase) {
case 'abort':
return chalk.yellow('REBUILD ABORTED!');
case 'error':
return exports.appStart({name, phase: 'error', warnings});
return exports.appStart({name, phase: 'error', messages});
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 'post_legacy':
return exports.appStart({name, phase: 'post_legacy'});
case 'report':
return exports.appStart({name, phase: 'report', warnings});
return exports.appStart({name, phase: 'report', messages});
case 'report_legacy':
return exports.appStart({name, phase: 'report_legacy', warnings});
return exports.appStart({name, phase: 'report_legacy', messages});
}
};

/*
* Helper to show that an app has restarted
*/
exports.appRestart = ({name, phase = 'pre', warnings = {}} = {}) => {
exports.appRestart = ({name, phase = 'pre', messages = {}} = {}) => {
switch (phase) {
case 'error':
return exports.appStart({name, phase: 'error', warnings});
return exports.appStart({name, phase: 'error', messages});
case 'pre':
return chalk.cyan('Stopping and restarting your app...Shiny!');
case 'post':
return exports.appStart({name, phase: 'post'});
case 'post_legacy':
return exports.appStart({name, phase: 'post_legacy'});
case 'report':
return exports.appStart({name, phase: 'report', warnings});
return exports.appStart({name, phase: 'report', messages});
case 'report_legacy':
return exports.appStart({name, phase: 'report_legacy', warnings});
return exports.appStart({name, phase: 'report_legacy', messages});
}
};

/*
* Helper to show that an app has started
*/
exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => {
exports.appStart = ({name, phase = 'pre', messages = {}} = {}) => {
switch (phase) {
case 'error':
return [
'',
chalk.red(niceFont('Uh oh!', 'ANSI Shadow')),
'',
'An error occurred while starting up your app!',
'An unrecoverable 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')}`),
chalk.yellow(` ${figures.squareSmallFilled} Try running ${codeMe('lando rebuild')}`),
chalk.yellow(` ${figures.squareSmallFilled} Try restarting in debug mode ${codeMe('lando restart --debug')}`),
chalk.yellow(` ${figures.squareSmallFilled} 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'),
chalk.magenta(` ${figures.squareSmallFilled} https://docs.lando.dev/help/logs.html`),
chalk.magenta(` ${figures.squareSmallFilled} 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'),
chalk.green(` ${figures.squareSmallFilled} Slack - https://launchpass.com/devwithlando`),
chalk.green(` ${figures.squareSmallFilled} 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')),
getHeader(messages),
'',
'Your app is starting up... See scanning below for real time status',
'In the meantime, here are some vitals:',
Expand All @@ -125,7 +169,7 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => {
case 'post_legacy':
return [
'',
chalk.magenta(niceFont('Boomshakalaka!!!', 'Small Slant')),
getHeader(messages),
'',
'Your app has started up correctly.',
'Here are some vitals:',
Expand All @@ -134,15 +178,15 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => {
case 'report_legacy':
const reportLegacy = [
'',
chalk.yellow(niceFont('Warning!', 'Small Slant')),
getHeader(messages),
'',
`Your app started up but we detected some things you ${italicize('may')} wish to investigate.`,
`Your app started up but we detected some things you ${chalk.bold('may')} wish to investigate.`,
'',
];

// Add in all our warnings
_.forEach(warnings, warning => {
reportLegacy.push(warningMessage(warning));
// Add in all our messages
_.forEach(messages, message => {
reportLegacy.push(statusMessage(message));
});

reportLegacy.push('');
Expand All @@ -152,16 +196,16 @@ exports.appStart = ({name, phase = 'pre', warnings = {}} = {}) => {
case 'report':
const report = [
'',
chalk.yellow(niceFont('Warning!', 'Small Slant')),
getHeader(messages),
'',
'Your app is starting up but we have already detected some things you may wish to investigate.',
`These only ${italicize('may')} be a problem.`,
'Your app is starting up but we have already detected some things you should investigate.',
`These ${chalk.bold('may')} or ${chalk.bold('may not')} prevent your app from working.`,
'',
];

// Add in all our warnings
_.forEach(warnings, warning => {
report.push(warningMessage(warning));
// Add in all our messages
_.forEach(messages, message => {
report.push(statusMessage(message));
});

report.push('');
Expand Down Expand Up @@ -248,30 +292,46 @@ exports.newContent = (type = 'guide') => [
'',
].join(os.EOL);

exports.setupHeader = (bengine = process.platform === 'linux' ? 'Engine' : 'Desktop') => [
'',
chalk.magenta(niceFont('Lando Setup!', 'Small Slant')),
'',
`${chalk.bold('lando setup')} is a convenience command to help you satisify the dependencies needed`,
'to run Lando. Typically it includes the installation and setup of some combination of the below',
'However, if you already have the needed dependencies it will happily do nothing and exit.',
'',
chalk.cyan(` ${figures.squareSmallFilled} Common Lando Plugins`),
chalk.cyan(` ${figures.squareSmallFilled} Docker ${bengine}`),
chalk.cyan(` ${figures.squareSmallFilled} Docker Compose`),
'',
'It will attempt to install plugins first and then it will run any needed setup tasks. For more information on',
`customizing setup please run ${chalk.bold('lando setup --help')}`,
'',
].join(os.EOL);

/*
* Helper to show NO DOCKER error message
*/
exports.noDockerDep = (dep = 'Docker') => [
exports.noDockerDep = (dep = 'Docker Desktop') => [
'',
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.',
`Lando could not detect an installation of ${dep.toUpperCase()} which is a required dependency!`,
'This most often happens if you have installed Lando manually or 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'),
`You should run ${chalk.bold('lando setup')} which will attempt to install the things Lando needs to work`,
'correctly.',
'',
'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',
'we recommend you install Lando using the convenience script 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'),
chalk.magenta(` ${figures.squareSmallFilled} Slack - https://launchpass.com/devwithlando`),
chalk.magenta(` ${figures.squareSmallFilled} GitHub - https://github.com/lando/lando/issues/new/choose`),
'',
].join(os.EOL);

Expand Down Expand Up @@ -422,29 +482,9 @@ exports.tunnel = ({url, phase = 'pre'} = {}) => {
}
};

/*
* 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({
return statusMessage({
type: 'warning',
title: 'Invalid Machine Token',
detail: [
'Your machine token has been rejected by Pantheon. It may have been revoked or corrupted.',
Expand Down
Loading

0 comments on commit 47bcfed

Please sign in to comment.