Skip to content

Commit

Permalink
Warn about unsupported shells (#1550)
Browse files Browse the repository at this point in the history
* Warn about unsupported shells

This PR introduces changes to do a best effort to determine if the shell
is supported. Without exposing it to users yet.
  • Loading branch information
pastuxso authored Aug 28, 2024
1 parent ea2be63 commit f40f661
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 69 deletions.
12 changes: 12 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,12 @@
"default": true,
"markdownDescription": "If set to `true`, the extension will bring up the GRPC server."
},
"runme.experiments.shellWarning": {
"type": "boolean",
"scope": "window",
"default": false,
"markdownDescription": "If set to `true`, the extension will display an error message if an unsupported shell is detected."
},
"runme.checkout.projectDir": {
"type": "string",
"scope": "machine",
Expand Down Expand Up @@ -844,6 +850,12 @@
"type": "string",
"default": "http://localhost:8877/api",
"description": "The base URL of the AI service."
},
"runme.app.docsUrl": {
"type": "string",
"scope": "window",
"default": "https://docs.runme.dev",
"markdownDescription": "Documentation Base URL"
}
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/client/components/configuration/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { LitElement, html } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { when } from 'lit/directives/when.js'

import type { ClientMessage, CellAnnotations, CellAnnotationsErrorResult } from '../../../types'
import type {
ClientMessage,
CellAnnotations,
CellAnnotationsErrorResult,
Settings,
} from '../../../types'
import { CellAnnotationsSchema, AnnotationSchema } from '../../../schema'
import {
ClientMessages,
Expand Down Expand Up @@ -90,6 +95,9 @@ export class Annotations extends LitElement {
@property({ type: Array })
categories: string[] = []

@property({ type: Object })
settings: Settings = {}

#getTargetValue(e: Target) {
switch (e.target.type) {
case 'text':
Expand Down Expand Up @@ -228,7 +236,7 @@ export class Annotations extends LitElement {
}

renderDocsLink(id: string) {
const link = `https://docs.runme.dev/r/extension/${id}`
const link = `${this.settings?.docsUrl}/r/extension/${id}`
return html`<vscode-link href="${link}">(docs ${ExternalLinkIcon})</vscode-link>`
}

Expand Down Expand Up @@ -298,6 +306,7 @@ export class Annotations extends LitElement {
identifier="${id}"
@onChange=${this.onCategorySelectorChange}
@onCreateNewCategory=${this.createNewCategoryClick}
@settings=${this.settings}
></category-selector>
</div>
</div>`
Expand Down
7 changes: 6 additions & 1 deletion src/client/components/configuration/categorySelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { TextField } from '@vscode/webview-ui-toolkit'

import { ExternalLinkIcon } from '../icons/external'
import { CATEGORY_SEPARATOR } from '../../../constants'
import { Settings } from '../../../types'

export interface ISelectedCategory {
name: string
Expand Down Expand Up @@ -302,6 +303,9 @@ export class CategorySelector extends LitElement {
@property()
identifier: string | undefined

@property({ type: Object })
settings: Settings = {}

private dispatchComponentEvent(name: string, e: Event) {
if (e.defaultPrevented) {
e.preventDefault()
Expand Down Expand Up @@ -334,7 +338,8 @@ export class CategorySelector extends LitElement {
}

renderLink() {
return html`<vscode-link href="https://docs.runme.dev/configuration#run-all-cells-by-category"
return html`<vscode-link
href="${this.settings?.docsUrl}/configuration#run-all-cells-by-category"
>(docs ${ExternalLinkIcon})</vscode-link
>`
}
Expand Down
5 changes: 3 additions & 2 deletions src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ActivationFunction, RendererContext } from 'vscode-notebook-renderer'
import type { ActivationFunction } from 'vscode-notebook-renderer'

import { OutputType, RENDERERS } from '../constants'
import type { CellOutput } from '../types'
Expand All @@ -13,7 +13,7 @@ import './components'
// rendering logic inside of the `render()` function.
// ----------------------------------------------------------------------------

export const activate: ActivationFunction = (context: RendererContext<void>) => {
export const activate: ActivationFunction<void> = (context) => {
setContext(context)
return {
renderOutputItem(outputItem, element) {
Expand Down Expand Up @@ -90,6 +90,7 @@ export const activate: ActivationFunction = (context: RendererContext<void>) =>
'validationErrors',
JSON.stringify(payload.output.validationErrors ?? []),
)
annoElem.setAttribute('settings', JSON.stringify(payload.output.settings))
element.appendChild(annoElem)
break
case OutputType.terminal:
Expand Down
4 changes: 4 additions & 0 deletions src/extension/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from '../types'
import { Mutex } from '../utils/sync'
import {
getDocsUrl,
getNotebookTerminalConfigurations,
getSessionOutputs,
isPlatformAuthEnabled,
Expand Down Expand Up @@ -169,6 +170,9 @@ export class NotebookCellOutputManager {
annotations: getAnnotations(cell),
validationErrors: validateAnnotations(cell),
id: cell.metadata['runme.dev/id'],
settings: {
docsUrl: getDocsUrl(),
},
},
}

Expand Down
60 changes: 6 additions & 54 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,19 @@ 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 profile = ''
const result = await kernel.runProgram(programOptions)

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

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'
credentials = fromIni({ profile })

switch (awsResolver.view) {
Expand Down
10 changes: 6 additions & 4 deletions src/extension/executors/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ export const uri: IKernelRunner = async ({

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

const success = await new Promise<boolean>((resolve, reject) => {
const success = new Promise<boolean>((resolve, reject) => {
program.onDidClose(async (code) => {
if (code !== 0) {
return resolve(false)
Expand Down Expand Up @@ -107,6 +106,9 @@ export const uri: IKernelRunner = async ({
}
})

const cellText = success ? execRes?.trim() : undefined
return runScript?.(cellText) || success
program.run()
const result = await success

const cellText = result ? execRes?.trim() : undefined
return runScript?.(cellText) || result
}
37 changes: 37 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 {
getDocsUrlFor,
getForceNewWindowConfig,
getRunmeAppUrl,
getSessionOutputs,
Expand Down Expand Up @@ -79,6 +80,8 @@ import { NotebookPanel as EnvStorePanel } from './panels/notebook'
import { NotebookCellStatusBarProvider } from './provider/cellStatusBar/notebook'
import { SessionOutputCellStatusBarProvider } from './provider/cellStatusBar/sessionOutput'
import * as manager from './ai/manager'
import getLogger from './logger'

export class RunmeExtension {
protected serializer?: SerializerBase

Expand Down Expand Up @@ -356,6 +359,40 @@ export class RunmeExtension {
}

await bootFile(context)

if (kernel.hasExperimentEnabled('shellWarning', false)) {
const showUnsupportedShellMessage = async () => {
const showMore = 'Show more'

const answer = await window.showErrorMessage('Unsupported shell', showMore)
if (answer === showMore) {
const url = getDocsUrlFor('/r/extension/supported-shells')
env.openExternal(Uri.parse(url))
}
}

const logger = getLogger('runme.beta.shellWarning')

kernel
.runProgram('echo $SHELL')
.then((output) => {
if (output === false) {
return
}

const supportedShells = ['bash', 'zsh']
const isSupported = supportedShells.some((sh) => output?.includes(sh))
logger.info(`Shell: ${output}`)

if (!isSupported) {
showUnsupportedShellMessage()
}
})
.catch((e) => {
logger.error(e)
showUnsupportedShellMessage()
})
}
}

protected handleMasking(kernel: Kernel, maskingIsOn: boolean): (e: NotebookUiEvent) => void {
Expand Down
Loading

0 comments on commit f40f661

Please sign in to comment.