import * as fs from "fs" ; import * as path from "path" ; import * as nls from "vscode-nls" ; import { ICordovaAttachRequestArgs , ICordovaLaunchRequestArgs } from "../debugger/requestArgs" ; nls . config ( { messageFormat : nls . MessageFormat . bundle , bundleFormat : nls . BundleFormat . standalone } ) ( ) ; const localize = nls . loadMessageBundle ( ) ; export class NodeVersionHelper { private static nvsStandardArchName ( arch ) { switch ( arch ) { case "32" : case "x86" : case "ia32" : return "x86" ; case "64" : case "x64" : case "amd64" : return "x64" ; case "arm" : const arm_version = ( process . config . variables as any ) . arm_version ; return arm_version ? "armv" + arm_version + "l" : "arm" ; default : return arch ; } } /**
     * Parses a node version string into remote name, semantic version, and architecture
     * components. Infers some unspecified components based on configuration.
     */ private static parseVersionString ( versionString ) { const versionRegex = /^(([\w-]+)\/)?(v?(\d+(\.\d+(\.\d+)?)?))(\/((x86)|(32)|((x)?64)|(arm\w*)|(ppc\w*)))?$/i ; const match = versionRegex . exec ( versionString ) ; if ( ! match ) { throw new Error ( "Invalid version string: " + versionString ) ; } const nvsFormat = ! ! ( match [ 2 ] || match [ 8 ] ) ; const remoteName = match [ 2 ] || "node" ; const semanticVersion = match [ 4 ] || "" ; const arch = NodeVersionHelper . nvsStandardArchName ( match [ 8 ] || process . arch ) ; return { nvsFormat , remoteName , semanticVersion , arch } ; } /**
     * if a runtime version is specified we prepend env.PATH with the folder that corresponds to the version.
     * Returns false on error
     */ public static nvmSupport ( config ) { let bin = undefined ; let versionManagerName = undefined ; let nvsHome = process . env [ "NVS_HOME" ] ; if ( ! nvsHome ) { const nvsDir = process . platform === "win32" ? path . join ( process . env [ "LOCALAPPDATA" ] || "" , "nvs" ) : path . join ( process . env [ "HOME" ] || "" , ".nvs" ) ; if ( fs . existsSync ( nvsDir ) ) { nvsHome = nvsDir ; } } const { nvsFormat , remoteName , semanticVersion , arch } = NodeVersionHelper . parseVersionString ( config . runtimeVersion ) ; if ( nvsFormat || nvsHome ) { if ( nvsHome ) { bin = path . join ( nvsHome , remoteName , semanticVersion , arch ) ; if ( process . platform !== "win32" ) { bin = path . join ( bin , "bin" ) ; } versionManagerName = "nvs" ; } else { throw new Error ( localize ( "nvsHomeNotFoundMessage" , "Attribute 'runtimeVersion' requires Node.js version manager 'nvs'." ) ) ; } } if ( ! bin ) { if ( process . platform === "win32" ) { const nvmHome = process . env [ "NVM_HOME" ] ; if ( ! nvmHome ) { throw new Error ( localize ( "nvmWindowsNotFoundMessage" , "Attribute 'runtimeVersion' requires Node.js version manager 'nvm-windows' or 'nvs'." ) ) ; } bin = path . join ( nvmHome , `v${ config . runtimeVersion }` ) ; versionManagerName = "nvm-windows" ; } else { let nvmHome = process . env [ "NVM_DIR" ] ; if ( ! nvmHome ) { const nvmDir = path . join ( process . env [ "HOME" ] || "" , ".nvm" ) ; if ( fs . existsSync ( nvmDir ) ) { nvmHome = nvmDir ; } } if ( ! nvmHome ) { throw new Error ( localize ( "nvmHomeNotFoundMessage" , "Attribute 'runtimeVersion' requires Node.js version manager 'nvm' or 'nvs'." ) ) ; } bin = path . join ( nvmHome , "versions" , "node" , `v${ config . runtimeVersion }` , "bin" ) ; versionManagerName = "nvm" ; } } if ( fs . existsSync ( bin ) ) { if ( ! config . env ) { config . env = { } ; } if ( process . platform === "win32" ) { process . env [ "Path" ] = `${ bin };${ process . env [ "Path" ] }` ; } else { process . env [ "PATH" ] = `${ bin }:${ process . env [ "PATH" ] }` ; } } else { throw new Error ( localize ( "runtimeVersionNotFoundMessage" , "Node.js version '{0}' not installed for '{1}'." , config . runtimeVersion , versionManagerName ) ) ; } } }