Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink committed Mar 19, 2024
1 parent 4a32990 commit 41f05f2
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 181 deletions.
10 changes: 6 additions & 4 deletions extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { TestProvider } from './test-provider/test-provider'
import { StorageProvider } from './storage/storage-provider'
import * as path from 'path'
import { NotificationProvider } from './ui/notification-provider'
import { CliSelectionProvider } from './ui/cli-selection-provider'
import { CliSelectionProvider } from './flow-cli/cli-selection-provider'

// The container for all data relevant to the extension.
export class Extension {
Expand All @@ -32,6 +32,7 @@ export class Extension {
#commands: CommandController
#testProvider: TestProvider
#schemaProvider: JSONSchemaProvider
#cliSelectionProvider: CliSelectionProvider

private constructor (settings: Settings, ctx: ExtensionContext) {
this.ctx = ctx
Expand All @@ -47,7 +48,7 @@ export class Extension {
const cliProvider = new CliProvider(settings)

// Register CliSelectionProvider
const cliSelectionProvider = new CliSelectionProvider(cliProvider)
this.#cliSelectionProvider = new CliSelectionProvider(cliProvider)

// Register JSON schema provider
this.#schemaProvider = new JSONSchemaProvider(ctx.extensionPath, cliProvider)
Expand Down Expand Up @@ -84,7 +85,8 @@ export class Extension {
// Called on exit
async deactivate (): Promise<void> {
await this.languageServer.deactivate()
this.#testProvider?.dispose()
this.#schemaProvider?.dispose()
this.#testProvider.dispose()
this.#schemaProvider.dispose()
this.#cliSelectionProvider.dispose()
}
}
22 changes: 11 additions & 11 deletions extension/src/flow-cli/cli-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ const KNOWN_BINS = ['flow', 'flow-c1']

const CADENCE_V1_CLI_REGEX = /-cadence-v1.0.0/g

export type CliBinary = {
export interface CliBinary {
name: string
version: semver.SemVer
}

type AvailableBinariesCache = {
interface AvailableBinariesCache {
[key: string]: StateCache<CliBinary | null>
}

Expand All @@ -33,27 +33,28 @@ export class CliProvider {
this.#selectedBinaryName.next(flowCommand)
})

this.#availableBinaries = KNOWN_BINS.reduce((acc, bin) => {
this.#availableBinaries = KNOWN_BINS.reduce<AvailableBinariesCache>((acc, bin) => {
acc[bin] = new StateCache(async () => await this.#fetchBinaryInformation(bin))
acc[bin].subscribe(() => {
this.#availableBinaries$.invalidate()
})
return acc
}, {} as AvailableBinariesCache)
}, {})

this.#availableBinaries$ = new StateCache(async () => {
return this.getAvailableBinaries()
return await this.getAvailableBinaries()
})

this.#currentBinary$ = new StateCache(async () => {
const name: string = this.#selectedBinaryName.getValue()
return this.#availableBinaries[name].getValue()
return await this.#availableBinaries[name].getValue()
})

// Subscribe to changes in the selected binary to update the caches
this.#selectedBinaryName.pipe(distinctUntilChanged(), startWith(null), pairwise()).subscribe(([prev, curr]) => {
// Swap out the cache for the selected binary
if (prev != null && !KNOWN_BINS.includes(prev)) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete this.#availableBinaries[prev]
}
if (curr != null && !KNOWN_BINS.includes(curr)) {
Expand Down Expand Up @@ -109,7 +110,6 @@ export class CliProvider {
})
}


async getAvailableBinaries (): Promise<CliBinary[]> {
const bins: CliBinary[] = []
for (const name in this.#availableBinaries) {
Expand All @@ -126,16 +126,16 @@ export class CliProvider {
}

async getCurrentBinary (): Promise<CliBinary | null> {
return this.#currentBinary$.getValue()
return await this.#currentBinary$.getValue()
}

setCurrentBinary (name: string): void {
this.#settings.updateSettings({ flowCommand: name })
async setCurrentBinary (name: string): Promise<void> {
await this.#settings.updateSettings({ flowCommand: name })
}
}

export function isCadenceV1Cli (version: semver.SemVer): boolean {
return CADENCE_V1_CLI_REGEX.test(version.raw)
return CADENCE_V1_CLI_REGEX.test(version.raw)
}

export function parseFlowCliVersion (buffer: Buffer | string): string {
Expand Down
145 changes: 145 additions & 0 deletions extension/src/flow-cli/cli-selection-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import { zip } from 'rxjs'
import { CliBinary, CliProvider } from './cli-provider'
import { SemVer } from 'semver'
import * as vscode from 'vscode'

const TOGGLE_CADENCE_VERSION_COMMAND = 'cadence.changeCadenceVersion'
const CADENCE_V1_CLI_REGEX = /-cadence-v1.0.0/g
const GET_BINARY_LABEL = (version: SemVer): string => `Flow CLI v${version.format()}`

export class CliSelectionProvider implements vscode.Disposable {
#statusBarItem: vscode.StatusBarItem | undefined
#cliProvider: CliProvider
#showSelector: boolean = false
#versionSelector: vscode.QuickPick<AvailableBinaryItem | CustomBinaryItem> | undefined
#disposables: vscode.Disposable[] = []

constructor (cliProvider: CliProvider) {
this.#cliProvider = cliProvider

// Register the command to toggle the version
vscode.commands.registerCommand(TOGGLE_CADENCE_VERSION_COMMAND, async () => await this.#toggleSelector(true))

// Register UI components
zip(this.#cliProvider.currentBinary$, this.#cliProvider.availableBinaries$).subscribe(() => {
void this.#refreshSelector()
})
this.#cliProvider.currentBinary$.subscribe((binary) => {
if (binary === null) return
this.#statusBarItem?.dispose()
this.#statusBarItem = this.#createStatusBarItem(binary?.version)
this.#statusBarItem.show()
})
}

#createStatusBarItem (version: SemVer): vscode.StatusBarItem {
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1)
statusBarItem.command = TOGGLE_CADENCE_VERSION_COMMAND
statusBarItem.color = new vscode.ThemeColor('statusBar.foreground')
statusBarItem.tooltip = 'Click to change the Flow CLI version'

// Update the status bar text when the version changes
statusBarItem.text = GET_BINARY_LABEL(version)

return statusBarItem
}

#createVersionSelector (currentBinary: CliBinary | null, availableBinaries: CliBinary[]): vscode.QuickPick<AvailableBinaryItem | CustomBinaryItem> {
const versionSelector = vscode.window.createQuickPick<AvailableBinaryItem | CustomBinaryItem>()
versionSelector.title = 'Select a Flow CLI version'

// Update selected binary when the user selects a version
this.#disposables.push(versionSelector.onDidAccept(async () => {
if (versionSelector.selectedItems.length === 0) return
await this.#toggleSelector(false)

const selected = versionSelector.selectedItems[0]

if (selected instanceof CustomBinaryItem) {
void vscode.window.showInputBox({
placeHolder: 'Enter the path to the Flow CLI binary',
prompt: 'Enter the path to the Flow CLI binary'
}).then((path) => {
if (path != null) {
this.#cliProvider.setCurrentBinary(path)
}
})
} else if (selected instanceof AvailableBinaryItem) {
this.#cliProvider.setCurrentBinary(selected.path)
}
}))

// Update available versions
const items: Array<AvailableBinaryItem | CustomBinaryItem> = availableBinaries.map(binary => new AvailableBinaryItem(binary))
items.push(new CustomBinaryItem())
versionSelector.items = items

// Select the current binary
if (currentBinary !== null) {
const currentBinaryItem = versionSelector.items.find(item => item instanceof AvailableBinaryItem && item.path === currentBinary.name)
console.log(currentBinaryItem)
if (currentBinaryItem != null) {
versionSelector.selectedItems = [currentBinaryItem]
}
}

return versionSelector
}

async #toggleSelector (show: boolean): Promise<void> {
this.#showSelector = show
await this.#refreshSelector()
}

async #refreshSelector (): Promise<void> {
if (this.#showSelector) {
this.#versionSelector?.dispose()
const currentBinary = await this.#cliProvider.getCurrentBinary()
const availableBinaries = await this.#cliProvider.getAvailableBinaries()
this.#versionSelector = this.#createVersionSelector(currentBinary, availableBinaries)
this.#disposables.push(this.#versionSelector)
this.#versionSelector.show()
} else {
this.#versionSelector?.dispose()
}
}

dispose (): void {
this.#disposables.forEach(disposable => disposable.dispose())
}
}

class AvailableBinaryItem implements vscode.QuickPickItem {
detail?: string
picked?: boolean
alwaysShow?: boolean
#binary: CliBinary

constructor (binary: CliBinary) {
this.#binary = binary
}

get label (): string {
return GET_BINARY_LABEL(this.#binary.version)
}

get description (): string {
return `(${this.#binary.name})`
}

get path (): string {
return this.#binary.name
}
}

class CustomBinaryItem implements vscode.QuickPickItem {
label: string

constructor () {
this.label = 'Choose a custom version...'
}
}

export function isCliCadenceV1 (version: SemVer): boolean {
return CADENCE_V1_CLI_REGEX.test(version.raw)
}
4 changes: 1 addition & 3 deletions extension/src/json-schema-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { CliProvider } from './flow-cli/cli-provider'
const CADENCE_SCHEMA_URI = 'cadence-schema'
const GET_FLOW_SCHEMA_URL = (version: string): string => `https://raw.githubusercontent.com/onflow/flow-cli/v${version}/flowkit/schema.json`

const LOCAL_SCHEMA_KEY = 'local'

// This class provides the JSON schema for the flow.json file
// It is accessible via the URI scheme "cadence-schema:///flow.json"
export class JSONSchemaProvider implements vscode.FileSystemProvider, vscode.Disposable {
Expand Down Expand Up @@ -52,7 +50,7 @@ export class JSONSchemaProvider implements vscode.FileSystemProvider, vscode.Dis
return await this.getLocalSchema()
})
}

return await this.#schemaCache[version]
}

Expand Down
2 changes: 1 addition & 1 deletion extension/src/server/language-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class LanguageServerAPI {
exec('killall dlv') // Required when running language server locally on mac
} catch (err) { void err }
}

const env = await envVars.getValue()
this.client = new LanguageClient(
'cadence',
Expand Down
18 changes: 9 additions & 9 deletions extension/src/settings/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Workspace Settings */
import { BehaviorSubject, Observable, distinctUntilChanged, map, skip } from 'rxjs'
import { BehaviorSubject, Observable, distinctUntilChanged, map } from 'rxjs'
import { workspace, Disposable, ConfigurationTarget } from 'vscode'
import { isEqual } from 'lodash'

Expand Down Expand Up @@ -54,20 +54,20 @@ export class Settings implements Disposable {
return this.#configuration$.value
}

updateSettings (config: Partial<CadenceConfiguration>, target?: ConfigurationTarget): void {
async updateSettings (config: Partial<CadenceConfiguration>, target?: ConfigurationTarget): Promise<void> {
// Recursively update all keys in the configuration
function update(section: string, obj: any) {
Object.entries(obj).forEach(([key, value]) => {
const newKey = section ? `${section}.${key}` : key
async function update (section: string, obj: any): Promise<void> {
await Promise.all(Object.entries(obj).map(async ([key, value]) => {
const newKey = `${section}.${key}`
if (typeof value === 'object' && !Array.isArray(value)) {
update(newKey, value)
await update(newKey, value)
} else {
workspace.getConfiguration().update(newKey, value, target)
await workspace.getConfiguration().update(newKey, value, target)
}
})
}))
}

update(CONFIGURATION_KEY, config)
await update(CONFIGURATION_KEY, config)
}

dispose (): void {
Expand Down
Loading

0 comments on commit 41f05f2

Please sign in to comment.