|
| 1 | +import color from '@heroku-cli/color' |
| 2 | +import {Command, flags} from '@heroku-cli/command' |
| 3 | +import * as Heroku from '@heroku-cli/schema' |
| 4 | +import {ux} from '@oclif/core' |
| 5 | +import * as lodash from 'lodash' |
| 6 | +const clipboard = require('copy-paste') |
| 7 | +const {exec} = require('child_process') |
| 8 | +const {promisify} = require('util') |
| 9 | +const execAsync = promisify(exec) |
| 10 | + |
| 11 | +const getLocalNodeVersion = async () => { |
| 12 | + const {stdout} = await execAsync('node -v') |
| 13 | + return stdout |
| 14 | +} |
| 15 | + |
| 16 | +const getInstallMethod = () => { |
| 17 | + return 'brew' |
| 18 | +} |
| 19 | + |
| 20 | +const getInstallLocation = async () => { |
| 21 | + const {stdout} = await execAsync('which heroku') |
| 22 | + const formattedOutput = stdout.replace(/\n/g, '') |
| 23 | + return formattedOutput |
| 24 | +} |
| 25 | + |
| 26 | +const getLocalProxySettings = async (unmasked = false) => { |
| 27 | + const command = `httpsProxy=$(scutil --proxy | awk -F': ' '/HTTPSProxy/ {print $2}') |
| 28 | +
|
| 29 | + # Check if HTTPSProxy has a value |
| 30 | + if [ -n "$httpsProxy" ]; then |
| 31 | + echo "$httpsProxy" |
| 32 | + else |
| 33 | + echo "no proxy set" |
| 34 | + fi` |
| 35 | + |
| 36 | + const {stdout} = await execAsync(command) |
| 37 | + const hasProxySet = !stdout.includes('no proxy set') |
| 38 | + |
| 39 | + if (unmasked) { |
| 40 | + return stdout |
| 41 | + } |
| 42 | + |
| 43 | + return hasProxySet ? 'xxxxx\n' : stdout |
| 44 | +} |
| 45 | + |
| 46 | +const getInstalledPLugins = async () => { |
| 47 | + const {stdout} = await execAsync('heroku plugins') |
| 48 | + return stdout |
| 49 | +} |
| 50 | + |
| 51 | +const getHerokuStatus = async () => { |
| 52 | + const {stdout} = await execAsync('heroku status') |
| 53 | + return stdout |
| 54 | +} |
| 55 | + |
| 56 | +const copyToClipboard = async (value: any) => { |
| 57 | + clipboard.copy(value) |
| 58 | +} |
| 59 | + |
| 60 | +export default class DoctorVitals extends Command { |
| 61 | + static description = 'list local user setup for debugging' |
| 62 | + static topic = 'doctor' |
| 63 | + |
| 64 | + static flags = { |
| 65 | + unmask: flags.boolean({description: 'unmasks fields heroku has deemed potentially sensitive', required: false}), |
| 66 | + 'copy-results': flags.boolean({description: 'copies results to clipboard', required: false}), |
| 67 | + json: flags.boolean({description: 'display as json', required: false}), |
| 68 | + } |
| 69 | + |
| 70 | + async run() { |
| 71 | + const {flags} = await this.parse(DoctorVitals) |
| 72 | + const copyResults = flags['copy-results'] |
| 73 | + const time = new Date() |
| 74 | + const dateChecked = time.toISOString().split('T')[0] |
| 75 | + const cliInstallMethod = getInstallMethod() |
| 76 | + const cliInstallLocation = await getInstallLocation() |
| 77 | + const os = this.config.platform |
| 78 | + const cliVersion = `v${this.config.version}` |
| 79 | + const nodeVersion = await getLocalNodeVersion() |
| 80 | + const networkConfig = { |
| 81 | + httpsProxy: await getLocalProxySettings(flags.unmask), |
| 82 | + } |
| 83 | + const installedPlugins = await getInstalledPLugins() |
| 84 | + const herokuStatus = await getHerokuStatus() |
| 85 | + |
| 86 | + const isHerokuUp = true |
| 87 | + let copiedResults = '' |
| 88 | + |
| 89 | + ux.styledHeader(`${color.heroku('Heroku CLI Doctor')} · ${color.cyan(`User Local Setup on ${dateChecked}`)}`) |
| 90 | + ux.log(`${color.cyan('CLI Install Method:')} ${cliInstallMethod}`) |
| 91 | + ux.log(`${color.cyan('CLI Install Location:')} ${cliInstallLocation}`) |
| 92 | + ux.log(`${color.cyan('OS:')} ${os}`) |
| 93 | + ux.log(`${color.cyan('Heroku CLI Version:')} ${cliVersion}`) |
| 94 | + ux.log(`${color.cyan('Node Version:')} ${nodeVersion}`) |
| 95 | + |
| 96 | + ux.log(`${color.cyan('Network Config')}`) |
| 97 | + ux.log(`HTTPSProxy: ${networkConfig.httpsProxy}`) |
| 98 | + |
| 99 | + ux.log(`${color.cyan('Installed Plugins')}`) |
| 100 | + ux.log(`${installedPlugins}`) |
| 101 | + |
| 102 | + ux.log(`${color.bold(color.heroku('Heroku Status'))}`) |
| 103 | + ux.log(`${color.bold(color.heroku('----------------------------------------'))}`) |
| 104 | + ux.log(isHerokuUp ? color.green(herokuStatus) : color.red(herokuStatus)) |
| 105 | + |
| 106 | + if (copyResults) { |
| 107 | + // copy results to clipboard here |
| 108 | + copiedResults += `Heroku CLI Doctor · User Local Setup on ${dateChecked}\n` |
| 109 | + copiedResults += `CLI Install Method: ${cliInstallMethod}\n` |
| 110 | + copiedResults += `CLI Install Location: ${cliInstallLocation}\n` |
| 111 | + copiedResults += `OS: ${os}\n` |
| 112 | + copiedResults += `Heroku CLI Version: ${cliVersion}\n` |
| 113 | + copiedResults += `Node Version: ${nodeVersion}\n` |
| 114 | + copiedResults += 'Network Config\n' |
| 115 | + copiedResults += `HTTPSProxy: ${networkConfig.httpsProxy}\n` |
| 116 | + copiedResults += 'Installed Plugins\n' |
| 117 | + copiedResults += `${installedPlugins}\n` |
| 118 | + copiedResults += 'Heroku Status\n' |
| 119 | + copiedResults += '----------------------------------------\n' |
| 120 | + copiedResults += herokuStatus |
| 121 | + } |
| 122 | + |
| 123 | + await copyToClipboard(copiedResults) |
| 124 | + } |
| 125 | +} |
0 commit comments