From f95fb4c53a5b80573a19f59db7f1e806311d4a58 Mon Sep 17 00:00:00 2001 From: Tom French Date: Fri, 16 Feb 2024 17:48:21 +0000 Subject: [PATCH] feat: click status bar icon to select nargo install --- src/extension.ts | 15 ++++++++-- src/find-nargo.ts | 70 +++++++++++++++++++++++++++++------------------ src/noir.ts | 1 + 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 575c070..99bc7a6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -36,11 +36,13 @@ import { window, ProgressLocation, } from 'vscode'; +import os from 'os'; import { languageId } from './constants'; import Client from './client'; -import findNargo from './find-nargo'; -import { lspClients, editorLineDecorationManager, getNoirStatusBarItem, handleClientStartError } from './noir'; +import findNargo, { findNargoBinaries } from './find-nargo'; +import { lspClients, editorLineDecorationManager } from './noir'; +import { getNoirStatusBarItem, handleClientStartError } from './noir'; const activeCommands: Map = new Map(); @@ -168,6 +170,15 @@ function registerCommands(uri: Uri) { }); commands$.push(hideProfileInformationCommand$); + const selectNargoPathCommand$ = commands.registerCommand('nargo.config.path.select', async (..._args) => { + const homeDir = os.homedir(); + const foundNargoBinaries = findNargoBinaries(homeDir); + const result = await window.showQuickPick(foundNargoBinaries, { placeHolder: 'Select the Nargo binary to use' }); + const config = workspace.getConfiguration('noir', uri); + config.update('nargoPath', result); + }); + commands$.push(selectNargoPathCommand$); + activeCommands.set(file, Disposable.from(...commands$)); } diff --git a/src/find-nargo.ts b/src/find-nargo.ts index 07e1869..1785df6 100644 --- a/src/find-nargo.ts +++ b/src/find-nargo.ts @@ -1,4 +1,4 @@ -import os from 'os'; +import os, { homedir } from 'os'; import path from 'path'; import fs from 'fs'; import which from 'which'; @@ -6,45 +6,61 @@ import { NargoNotFoundError } from './noir'; import { MarkdownString } from 'vscode'; // List of possible nargo binaries to find on Path -// We prioritize 'aztec-nargo' as more specialised case -const nargoBinaries = ['aztec-nargo', 'nargo']; +// We prioritize 'nargo' as the more standard version. +const NARGO_BINARIES = ['nargo', 'aztec-nargo']; // List of possible default installations in users folder -const nargoInstallLocationPostix = ['.aztec/bin/aztec-nargo', '.nargo/bin/nargo']; +const NARGO_INSTALL_LOCATION_POSTFIXES = ['.nargo/bin/nargo', '.aztec/bin/aztec-nargo']; -export default function findNargo() { - for (const bin of nargoBinaries) { +function absoluteInstallLocationPaths(homeDir: string): string[] { + return NARGO_INSTALL_LOCATION_POSTFIXES.map((postfix) => path.join(homeDir, postfix)).filter((filePath) => + fs.existsSync(filePath), + ); +} + +export function findNargoBinaries(homeDir: string): string[] { + // Note that JS sets maintain insertion order. + const nargoBinaryPaths: Set = new Set(); + + for (const bin of NARGO_BINARIES) { try { - const nargo = which.sync(bin); + const path = which.sync(bin); // If it didn't throw, we found a nargo binary - return nargo; + nargoBinaryPaths.add(path); } catch (err) { // Not found } } - const homeDir = os.homedir(); // So far we have not found installations on path // Let's check default installation locations - for (const postfix of nargoInstallLocationPostix) { - const filePath = path.join(homeDir, postfix); - if (fs.existsSync(filePath)) { - return filePath; - } + for (const filePath of absoluteInstallLocationPaths(homeDir)) { + nargoBinaryPaths.add(filePath); } - const message = new MarkdownString(); - message.appendText(`Could not locate any of\n`); - for (const nargoBinary of nargoBinaries) { - message.appendMarkdown(`\`${nargoBinary}\``); - message.appendText(`\n`); - } + return [...nargoBinaryPaths]; +} - message.appendText(`on \`$PATH\`, or one of default installation locations\n`); - for (const postfix of nargoInstallLocationPostix) { - const filePath = path.join(homeDir, postfix); - message.appendMarkdown(`\`${filePath}\``); - message.appendText(`\n`); - } +export default function findNargo() { + const homeDir = os.homedir(); + const nargoBinaryPaths = findNargoBinaries(homeDir); + + if (nargoBinaryPaths.length > 0) { + return nargoBinaryPaths[0]; + } else { + const message = new MarkdownString(); + message.appendText(`Could not locate any of\n`); + for (const nargoBinary of NARGO_BINARIES) { + message.appendMarkdown(`\`${nargoBinary}\``); + message.appendText(`\n`); + } + + message.appendText(`on \`$PATH\`, or one of default installation locations\n`); + for (const postfix of NARGO_INSTALL_LOCATION_POSTFIXES) { + const filePath = path.join(homeDir, postfix); + message.appendMarkdown(`\`${filePath}\``); + message.appendText(`\n`); + } - throw new NargoNotFoundError(message); + throw new NargoNotFoundError(message); + } } diff --git a/src/noir.ts b/src/noir.ts index 7d1c352..bd267d5 100644 --- a/src/noir.ts +++ b/src/noir.ts @@ -16,6 +16,7 @@ export function getNoirStatusBarItem() { // we will show/update it depending on file user is working with noirStatusBarItem = window.createStatusBarItem(StatusBarAlignment.Right, 100); noirStatusBarItem.text = 'Nargo'; + noirStatusBarItem.command = 'nargo.config.path.select'; return noirStatusBarItem; }