import { EXTENSION_NS } from "./constants" ; import * as fs from "fs" ; import * as os from "os" ; import * as path from "path" ; import * as process from "process" ; import * as vscode from "vscode" ; /** Assert that the condition is "truthy", otherwise throw. */ export function assert ( cond , msg = "Assertion failed." ) { if ( ! cond ) { throw new Error ( msg ) ; } } export async function getDenoCommand ( ) { let command = getWorkspaceConfigDenoExePath ( ) ; const workspaceFolders = vscode . workspace . workspaceFolders ; const defaultCommand = await getDefaultDenoCommand ( ) ; if ( ! command || ! workspaceFolders ) { command = command ?? defaultCommand ; } else if ( ! path . isAbsolute ( command ) ) { const list = [ ] ; for ( const workspace of workspaceFolders ) { const dir = path . resolve ( workspace . uri . fsPath , command ) ; try { const stat = await fs . promises . stat ( dir ) ; if ( stat . isFile ( ) ) { list . push ( dir ) ; } } catch { } } command = list . shift ( ) ?? defaultCommand ; } return command ; } function getWorkspaceConfigDenoExePath ( ) { const exePath = vscode . workspace . getConfiguration ( EXTENSION_NS ) . get < string > ( "path" ) ; if ( typeof exePath === "string" && exePath . trim ( ) . length === 0 ) { return undefined ; } else { return exePath ; } } function getDefaultDenoCommand ( ) { switch ( os . platform ( ) ) { case "win32" : return getDenoWindowsPath ( ) ; default : return Promise . resolve ( "deno" ) ; } async function getDenoWindowsPath ( ) { const denoCmd = "deno" ; const pathExtValue = process . env . PATHEXT ?? ".EXE;.CMD;.BAT;.COM" ; const pathValue = process . env . PATH ?? "" ; const pathExtItems = splitEnvValue ( pathExtValue ) ; const pathFolderPaths = splitEnvValue ( pathValue ) ; for ( const pathFolderPath of pathFolderPaths ) { for ( const pathExtItem of pathExtItems ) { const cmdFilePath = path . join ( pathFolderPath , denoCmd + pathExtItem ) ; if ( await fileExists ( cmdFilePath ) ) { return cmdFilePath ; } } } return denoCmd ; function splitEnvValue ( value ) { return value . split ( ";" ) . map ( ( item ) => item . trim ( ) ) . filter ( ( item ) => item . length > 0 ) ; } } function fileExists ( executableFilePath ) { return new Promise < boolean > ( ( resolve ) => { fs . stat ( executableFilePath , ( err , stat ) => { resolve ( err == null && stat . isFile ( ) ) ; } ) ; } ) . catch ( ( ) => { return false ; } ) ; } }