Skip to content

Commit

Permalink
Add ask, diagnose, and recommend commands w/ temp font lib
Browse files Browse the repository at this point in the history
  • Loading branch information
zwhitfield3 committed Dec 1, 2023
1 parent 900dd16 commit 75d18ac
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 0 deletions.
36 changes: 36 additions & 0 deletions packages/cli/src/commands/doctor/ask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import color from '@heroku-cli/color'
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {Args, ux} from '@oclif/core'

export default class DoctorAsk extends Command {
static description = 'recieve responses from HerokAI'
static topic = 'doctor'

static flags = {
interactive: flags.boolean({description: 'use interactive mode with HerokAI', required: false}),
json: flags.boolean({description: 'display doctor:ask input/output as json', required: false}),
}

static args = {
question: Args.string({description: 'question to ask HerokAI', required: true}),
}

async run() {
const {args, flags} = await this.parse(DoctorAsk)
const {body: user} = await this.heroku.get<Heroku.Account>('/account', {retryAuth: false})
const userName = (user && user.name) ? ` ${user.name}` : ''
const herokAIResponse = `${color.heroku(`Hi${userName},`)} \n\nI'm just a concept right now. Remember?`

const dialogue = {
question: args.question,
response: herokAIResponse,
}

if (flags.json) {
ux.styledJSON(dialogue)
} else {
ux.log(herokAIResponse)
}
}
}
125 changes: 125 additions & 0 deletions packages/cli/src/commands/doctor/diagnose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import color from '@heroku-cli/color'
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {ux} from '@oclif/core'
import * as lodash from 'lodash'
const clipboard = require('copy-paste')
const {exec} = require('child_process')
const {promisify} = require('util')
const execAsync = promisify(exec)

const getLocalNodeVersion = async () => {
const {stdout} = await execAsync('node -v')
return stdout
}

const getInstallMethod = () => {
return 'brew'
}

const getInstallLocation = async () => {
const {stdout} = await execAsync('which heroku')
const formattedOutput = stdout.replace(/\n/g, '')
return formattedOutput
}

const getLocalProxySettings = async (unmasked = false) => {
const command = `httpsProxy=$(scutil --proxy | awk -F': ' '/HTTPSProxy/ {print $2}')
# Check if HTTPSProxy has a value
if [ -n "$httpsProxy" ]; then
echo "$httpsProxy"
else
echo "no proxy set"
fi`

const {stdout} = await execAsync(command)
const hasProxySet = !stdout.includes('no proxy set')

if (unmasked) {
return stdout
}

return hasProxySet ? 'xxxxx\n' : stdout
}

const getInstalledPLugins = async () => {
const {stdout} = await execAsync('heroku plugins')
return stdout
}

const getHerokuStatus = async () => {
const {stdout} = await execAsync('heroku status')
return stdout
}

const copyToClipboard = async (value: any) => {
clipboard.copy(value)
}

export default class DoctorVitals extends Command {
static description = 'list local user setup for debugging'
static topic = 'doctor'

static flags = {
unmask: flags.boolean({description: 'unmasks fields heroku has deemed potentially sensitive', required: false}),
'copy-results': flags.boolean({description: 'copies results to clipboard', required: false}),
json: flags.boolean({description: 'display as json', required: false}),
}

async run() {
const {flags} = await this.parse(DoctorVitals)
const copyResults = flags['copy-results']
const time = new Date()
const dateChecked = time.toISOString().split('T')[0]
const cliInstallMethod = getInstallMethod()
const cliInstallLocation = await getInstallLocation()
const os = this.config.platform
const cliVersion = `v${this.config.version}`
const nodeVersion = await getLocalNodeVersion()
const networkConfig = {
httpsProxy: await getLocalProxySettings(flags.unmask),
}
const installedPlugins = await getInstalledPLugins()
const herokuStatus = await getHerokuStatus()

const isHerokuUp = true
let copiedResults = ''

ux.styledHeader(`${color.heroku('Heroku CLI Doctor')} · ${color.cyan(`User Local Setup on ${dateChecked}`)}`)
ux.log(`${color.cyan('CLI Install Method:')} ${cliInstallMethod}`)
ux.log(`${color.cyan('CLI Install Location:')} ${cliInstallLocation}`)
ux.log(`${color.cyan('OS:')} ${os}`)
ux.log(`${color.cyan('Heroku CLI Version:')} ${cliVersion}`)
ux.log(`${color.cyan('Node Version:')} ${nodeVersion}`)

ux.log(`${color.cyan('Network Config')}`)
ux.log(`HTTPSProxy: ${networkConfig.httpsProxy}`)

ux.log(`${color.cyan('Installed Plugins')}`)
ux.log(`${installedPlugins}`)

ux.log(`${color.bold(color.heroku('Heroku Status'))}`)
ux.log(`${color.bold(color.heroku('----------------------------------------'))}`)
ux.log(isHerokuUp ? color.green(herokuStatus) : color.red(herokuStatus))

if (copyResults) {
// copy results to clipboard here
copiedResults += `Heroku CLI Doctor · User Local Setup on ${dateChecked}\n`
copiedResults += `CLI Install Method: ${cliInstallMethod}\n`
copiedResults += `CLI Install Location: ${cliInstallLocation}\n`
copiedResults += `OS: ${os}\n`
copiedResults += `Heroku CLI Version: ${cliVersion}\n`
copiedResults += `Node Version: ${nodeVersion}\n`
copiedResults += 'Network Config\n'
copiedResults += `HTTPSProxy: ${networkConfig.httpsProxy}\n`
copiedResults += 'Installed Plugins\n'
copiedResults += `${installedPlugins}\n`
copiedResults += 'Heroku Status\n'
copiedResults += '----------------------------------------\n'
copiedResults += herokuStatus
}

await copyToClipboard(copiedResults)
}
}
125 changes: 125 additions & 0 deletions packages/cli/src/commands/doctor/recommend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import color from '@heroku-cli/color'
import {Command, flags} from '@heroku-cli/command'
import * as Heroku from '@heroku-cli/schema'
import {ux} from '@oclif/core'
import * as lodash from 'lodash'
const clipboard = require('copy-paste')
const {exec} = require('child_process')
const {promisify} = require('util')
const execAsync = promisify(exec)

const getLocalNodeVersion = async () => {
const {stdout} = await execAsync('node -v')
return stdout
}

const getInstallMethod = () => {
return 'brew'
}

const getInstallLocation = async () => {
const {stdout} = await execAsync('which heroku')
const formattedOutput = stdout.replace(/\n/g, '')
return formattedOutput
}

const getLocalProxySettings = async (unmasked = false) => {
const command = `httpsProxy=$(scutil --proxy | awk -F': ' '/HTTPSProxy/ {print $2}')
# Check if HTTPSProxy has a value
if [ -n "$httpsProxy" ]; then
echo "$httpsProxy"
else
echo "no proxy set"
fi`

const {stdout} = await execAsync(command)
const hasProxySet = !stdout.includes('no proxy set')

if (unmasked) {
return stdout
}

return hasProxySet ? 'xxxxx\n' : stdout
}

const getInstalledPLugins = async () => {
const {stdout} = await execAsync('heroku plugins')
return stdout
}

const getHerokuStatus = async () => {
const {stdout} = await execAsync('heroku status')
return stdout
}

const copyToClipboard = async (value: any) => {
clipboard.copy(value)
}

export default class DoctorVitals extends Command {
static description = 'list local user setup for debugging'
static topic = 'doctor'

static flags = {
unmask: flags.boolean({description: 'unmasks fields heroku has deemed potentially sensitive', required: false}),
'copy-results': flags.boolean({description: 'copies results to clipboard', required: false}),
json: flags.boolean({description: 'display as json', required: false}),
}

async run() {
const {flags} = await this.parse(DoctorVitals)
const copyResults = flags['copy-results']
const time = new Date()
const dateChecked = time.toISOString().split('T')[0]
const cliInstallMethod = getInstallMethod()
const cliInstallLocation = await getInstallLocation()
const os = this.config.platform
const cliVersion = `v${this.config.version}`
const nodeVersion = await getLocalNodeVersion()
const networkConfig = {
httpsProxy: await getLocalProxySettings(flags.unmask),
}
const installedPlugins = await getInstalledPLugins()
const herokuStatus = await getHerokuStatus()

const isHerokuUp = true
let copiedResults = ''

ux.styledHeader(`${color.heroku('Heroku CLI Doctor')} · ${color.cyan(`User Local Setup on ${dateChecked}`)}`)
ux.log(`${color.cyan('CLI Install Method:')} ${cliInstallMethod}`)
ux.log(`${color.cyan('CLI Install Location:')} ${cliInstallLocation}`)
ux.log(`${color.cyan('OS:')} ${os}`)
ux.log(`${color.cyan('Heroku CLI Version:')} ${cliVersion}`)
ux.log(`${color.cyan('Node Version:')} ${nodeVersion}`)

ux.log(`${color.cyan('Network Config')}`)
ux.log(`HTTPSProxy: ${networkConfig.httpsProxy}`)

ux.log(`${color.cyan('Installed Plugins')}`)
ux.log(`${installedPlugins}`)

ux.log(`${color.bold(color.heroku('Heroku Status'))}`)
ux.log(`${color.bold(color.heroku('----------------------------------------'))}`)
ux.log(isHerokuUp ? color.green(herokuStatus) : color.red(herokuStatus))

if (copyResults) {
// copy results to clipboard here
copiedResults += `Heroku CLI Doctor · User Local Setup on ${dateChecked}\n`
copiedResults += `CLI Install Method: ${cliInstallMethod}\n`
copiedResults += `CLI Install Location: ${cliInstallLocation}\n`
copiedResults += `OS: ${os}\n`
copiedResults += `Heroku CLI Version: ${cliVersion}\n`
copiedResults += `Node Version: ${nodeVersion}\n`
copiedResults += 'Network Config\n'
copiedResults += `HTTPSProxy: ${networkConfig.httpsProxy}\n`
copiedResults += 'Installed Plugins\n'
copiedResults += `${installedPlugins}\n`
copiedResults += 'Heroku Status\n'
copiedResults += '----------------------------------------\n'
copiedResults += herokuStatus
}

await copyToClipboard(copiedResults)
}
}
Binary file not shown.
1 change: 1 addition & 0 deletions packages/cli/src/lib/doctor/font/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is just temporary proof of concept. Actual font should be imported via heroku's cdn.

0 comments on commit 75d18ac

Please sign in to comment.