Skip to content

Commit

Permalink
Warn about unsupported shells
Browse files Browse the repository at this point in the history
This PR introduces changes to do a best effort to determine if the shell
is supported.

Closes: #1393
  • Loading branch information
pastuxso committed Aug 16, 2024
1 parent 60a938f commit 91e08b6
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 58 deletions.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,12 @@
"type": "string",
"default": "http://localhost:8080/api",
"description": "The base URL of the AI service."
},
"runme.app.faqUrl": {
"type": "string",
"scope": "window",
"default": "https://docs.runme.dev/faq",
"markdownDescription": "Frequently Asked Questions page"
}
}
}
Expand Down
61 changes: 4 additions & 57 deletions src/extension/executors/aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { resolveProgramOptionsScript } from './runner'
import { IKernelExecutor } from '.'

export const aws: IKernelExecutor = async (executor) => {
const { cellText, exec, runner, runnerEnv, doc, outputs, context } = executor
const { cellText, exec, runner, runnerEnv, doc, outputs, kernel } = executor

const annotations = getAnnotations(exec.cell)

Expand All @@ -41,67 +41,14 @@ export const aws: IKernelExecutor = async (executor) => {
cellId,
})

// todo(sebastian): move down into kernel?
switch (programOptions.exec?.type) {
case 'script':
{
programOptions.exec.script = 'echo $AWS_PROFILE'
}
programOptions.exec.script = 'echo $AWS_PROFILE'
break
}

const program = await runner.createProgramSession(programOptions)
context.subscriptions.push(program)

let execRes: string | undefined
const onData = (data: string | Uint8Array) => {
if (execRes === undefined) {
execRes = ''
}
execRes += data.toString()
}

program.onDidWrite(onData)
program.onDidErr(onData)
program.run()

const success = await new Promise<boolean>((resolve, reject) => {
program.onDidClose(async (code) => {
if (code !== 0) {
return resolve(false)
}
return resolve(true)
})

program.onInternalErr((e) => {
reject(e)
})

const exitReason = program.hasExited()

// unexpected early return, likely an error
if (exitReason) {
switch (exitReason.type) {
case 'error':
{
reject(exitReason.error)
}
break

case 'exit':
{
resolve(exitReason.code === 0)
}
break

default: {
resolve(false)
}
}
}
})

const profile = success ? execRes?.trim() : 'default'
const result = await kernel.runProgram(programOptions)
const profile = result.code === 0 ? result.output : 'default'
credentials = fromIni({ profile })

switch (awsResolver.view) {
Expand Down
19 changes: 19 additions & 0 deletions src/extension/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Channel from 'tangle/webviews'

import { NotebookUiEvent, Serializer, SyncSchema } from '../types'
import {
getFaqUrl,
getForceNewWindowConfig,
getRunmeAppUrl,
getSessionOutputs,
Expand Down Expand Up @@ -80,6 +81,7 @@ import { NotebookCellStatusBarProvider } from './provider/cellStatusBar/notebook
import { SessionOutputCellStatusBarProvider } from './provider/cellStatusBar/sessionOutput'
import * as generate from './ai/generate'
import * as manager from './ai/manager'

export class RunmeExtension {
protected serializer?: SerializerBase

Expand Down Expand Up @@ -129,6 +131,23 @@ export class RunmeExtension {
*/
try {
await server.launch()
kernel.runProgram('echo $0').then(async ({ output }) => {
const supportedShells = ['zsh', 'bash']
const isSupported = supportedShells.some((sh) => output?.includes(sh))

if (isSupported) {
return
}

const showMore = 'Show more'
const answer = await window.showWarningMessage('Unsupported shell', showMore)

if (answer === showMore) {
const dashboardUri = getFaqUrl('supported-shells')
const uri = Uri.parse(dashboardUri)
env.openExternal(uri)
}
})
} catch (e) {
// Unrecoverable error happened
if (e instanceof KernelServerError) {
Expand Down
73 changes: 72 additions & 1 deletion src/extension/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import {
import { getSystemShellPath, isShellLanguage } from './executors/utils'
import './wasm/wasm_exec.js'
import { RpcError } from './grpc/client'
import { IRunner, IRunnerReady } from './runner'
import { IRunner, IRunnerReady, RunnerExitReason, RunProgramOptions } from './runner'
import { IRunnerEnvironment } from './runner/environment'
import { IKernelRunnerOptions, executeRunner } from './executors/runner'
import { ITerminalState, NotebookTerminalType } from './terminal/terminalState'
Expand Down Expand Up @@ -1119,4 +1119,75 @@ export class Kernel implements Disposable {
public getPlainCache(cacheId: string): Promise<Uint8Array> | undefined {
return this.serializer?.getPlainCache(cacheId)
}

async runProgram(program?: RunProgramOptions | string) {
let programOptions: RunProgramOptions

if (typeof program === 'object') {
programOptions = program
} else if (typeof program === 'string') {
programOptions = {
programName: '',
background: false,
exec: {
type: 'script',
script: program,
},
languageId: 'sh',
storeLastOutput: false,
tty: true,
}
} else {
return Promise.reject(new Error('Invalid runProgram arguments'))
}
const runner = this.runner!
const programSession = await runner.createProgramSession(programOptions)

Check failure on line 1144 in src/extension/kernel.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Unhandled error

TypeError: Cannot read properties of undefined (reading 'createProgramSession') ❯ Kernel.runProgram src/extension/kernel.ts:1144:41 ❯ RunmeExtension.initialize src/extension/extension.ts:134:14 ❯ processTicksAndRejections node:internal/process/task_queues:95:5 ❯ tests/extension/extension.test.ts:99:3 ❯ runTest node_modules/@vitest/runner/dist/index.js:960:11 ❯ runSuite node_modules/@vitest/runner/dist/index.js:1116:15 ❯ runFiles node_modules/@vitest/runner/dist/index.js:1173:5 ❯ startTests node_modules/@vitest/runner/dist/index.js:1182:3 ❯ node_modules/vitest/dist/chunks/runBaseTests.CyvqmuC9.js:130:11 ❯ withEnv node_modules/vitest/dist/chunks/runBaseTests.CyvqmuC9.js:94:5 This error originated in "tests/extension/extension.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running. The latest test that might've caused the error is "tests/extension/extension.test.ts". It might mean one of the following: - The error was thrown, while Vitest was running this test. - If the error occurred after the test had been completed, this was the last documented test before it was thrown.
this.context.subscriptions.push(programSession)

let execRes: string | undefined
const onData = (data: string | Uint8Array) => {
if (execRes === undefined) {
execRes = ''
}
execRes += data.toString()
}

programSession.onDidWrite(onData)
programSession.onDidErr(onData)
programSession.run()

return new Promise<{ exitReason?: RunnerExitReason; code?: number | void; output?: string }>(
(resolve, reject) => {
programSession.onDidClose(async (code) => {
return resolve({ code, output: execRes?.trim() })
})

programSession.onInternalErr((e) => {
reject(e)
})

const exitReason = programSession.hasExited()

if (exitReason) {
switch (exitReason.type) {
case 'error':
{
reject({ exitReason, output: execRes?.trim() })
}
break

case 'exit':
{
resolve({ exitReason, code: exitReason.code, output: execRes?.trim() })
}
break

default: {
resolve({ exitReason, output: execRes?.trim() })
}
}
}
},
)
}
}
8 changes: 8 additions & 0 deletions src/utils/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const DEFAULT_WORKSPACE_FILE_ORDER = ['.env.local', '.env']
const DEFAULT_RUNME_APP_API_URL = 'https://platform.stateful.com'
const DEFAULT_RUNME_BASE_DOMAIN = 'platform.stateful.com'
const DEFAULT_RUNME_REMOTE_DEV = 'staging.platform.stateful.com'
const DEFAULT_FAQ_URL = 'https://docs.runme.dev/faq'
const APP_LOOPBACKS = ['127.0.0.1', 'localhost']
const APP_LOOPBACK_MAPPING = new Map<string, string>([
['api.', ':4000'],
Expand Down Expand Up @@ -90,6 +91,7 @@ const configurationSchema = {
maskOutputs: z.boolean().default(true),
loginPrompt: z.boolean().default(true),
platformAuth: z.boolean().default(false),
faqUrl: z.string().default(DEFAULT_FAQ_URL),
},
}

Expand Down Expand Up @@ -432,6 +434,11 @@ const isPlatformAuthEnabled = (): boolean => {
return getCloudConfigurationValue('platformAuth', false)
}

const getFaqUrl = (hash: string): string => {
const baseUrl = getCloudConfigurationValue('faqUrl', DEFAULT_FAQ_URL)
return `${baseUrl}#${hash}`
}

export {
enableServerLogs,
getActionsOpenViewInEditor,
Expand Down Expand Up @@ -462,4 +469,5 @@ export {
getSessionOutputs,
getMaskOutputs,
getLoginPrompt,
getFaqUrl,
}

0 comments on commit 91e08b6

Please sign in to comment.