'use strict' ; import * as vscode from 'vscode' ; import * as ejs from 'ejs' ; import * as path from 'path' ; import { ExtensionUtil } from '../util/ExtensionUtil' ; import { View } from './View' ; import { Reporter } from '../util/Reporter' ; import { DependencyManager } from '../dependencies/DependencyManager' ; import { ExtensionCommands } from '../../ExtensionCommands' ; import { SettingConfigurations } from '../configurations' ; import { GlobalState , ExtensionData } from '../util/GlobalState' ; import { VSCodeBlockchainOutputAdapter } from '../logging/VSCodeBlockchainOutputAdapter' ; import { LogType } from 'ibm-blockchain-platform-common' ; import { Dependencies , Dependency , DependencyWithVersion } from '../dependencies/Dependencies' ; export class PreReqView extends View { public dependencies : Dependencies ; public restoreCommandHijack : boolean = false ; constructor ( context , d ? ) { super ( context , 'preReq' , 'Prerequisites' ) ; this . dependencies = d ; } async openPanelInner ( panel ) { let outputAdapter ; Reporter . instance ( ) . sendTelemetryEvent ( 'openedView' , { name : panel . title } ) ; const extensionPath = ExtensionUtil . getExtensionPath ( ) ; const panelIcon = vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'logo.svg' ) ) ; panel . iconPath = panelIcon ; panel . onDidDispose ( async ( ) => { let isComplete = true ; if ( ! this . restoreCommandHijack ) { const dependencyManager = DependencyManager . instance ( ) ; isComplete = await dependencyManager . hasPreReqsInstalled ( this . dependencies ) ; } const bypassPreReqs = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_BYPASS_PREREQS ) ; if ( isComplete || bypassPreReqs ) { await ExtensionUtil . setupCommands ( ) ; await ExtensionUtil . completeActivation ( ) ; await vscode . commands . executeCommand ( ExtensionCommands . OPEN_HOME_PAGE ) ; } else { outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . WARNING , `Required prerequisites are missing. They must be installed before the extension can be used.` ) ; } } ) ; panel . webview . onDidReceiveMessage ( async ( message ) => { if ( message . command === 'finish' ) { this . restoreCommandHijack = true ; const localFabricFunctionality = message . localFabricFunctionality ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_LOCAL_FABRIC , localFabricFunctionality , vscode . ConfigurationTarget . Global ) ; await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , localFabricFunctionality ) ; panel . dispose ( ) ; } else if ( message . command === 'check' ) { await vscode . window . withProgress ( { location : vscode . ProgressLocation . Notification , title : 'IBM Blockchain Platform Extension' , cancellable : false } , async ( progress ) => { progress . report ( { message : `Checking installed dependencies` } ) ; const localFabricFunctionality = message . localFabricFunctionality ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_LOCAL_FABRIC , localFabricFunctionality , vscode . ConfigurationTarget . Global ) ; if ( message . toggle ) { outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . INFO , `Local Fabric functionality set to '${ localFabricFunctionality . toString ( ) }'.` ) ; } await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , localFabricFunctionality ) ; const dependencyManager = DependencyManager . instance ( ) ; const dependencies = await dependencyManager . getPreReqVersions ( ) ; if ( message . dockerForWindows || message . systemRequirements ) { const extensionData = GlobalState . get ( ) ; if ( message . dockerForWindows ) { extensionData . dockerForWindows = true ; dependencies . dockerForWindows . complete = true ; } if ( message . systemRequirements ) { dependencies . systemRequirements . complete = true ; } await GlobalState . update ( extensionData ) ; } const isComplete = await dependencyManager . hasPreReqsInstalled ( dependencies ) ; panel . webview . html = await this . getHTMLString ( panel . webview , dependencies , isComplete , localFabricFunctionality ) ; outputAdapter = VSCodeBlockchainOutputAdapter . instance ( ) ; outputAdapter . log ( LogType . SUCCESS , undefined , 'Finished checking installed dependencies' ) ; } ) ; } else if ( message . command === 'skip' ) { const dependencyManager = DependencyManager . instance ( ) ; const dependencies = this . dependencies || await dependencyManager . getPreReqVersions ( ) ; const dependenciesMissingObject = { } ; for ( const dependency of Object . keys ( dependencies ) ) { const isInstalled = dependencyManager . isValidDependency ( dependencies [ dependency ] ) ; if ( ! isInstalled ) { dependenciesMissingObject [ dependency ] = 'missing' ; } } if ( Object . keys ( dependenciesMissingObject ) . length > 0 ) { Reporter . instance ( ) . sendTelemetryEvent ( 'skipPreReqs' , dependenciesMissingObject ) ; } await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_BYPASS_PREREQS , true , vscode . ConfigurationTarget . Global ) ; const localFabricFunctionality = message . localFabricFunctionality ; await vscode . workspace . getConfiguration ( ) . update ( SettingConfigurations . EXTENSION_LOCAL_FABRIC , localFabricFunctionality , vscode . ConfigurationTarget . Global ) ; await vscode . commands . executeCommand ( 'setContext' , 'local-fabric-enabled' , localFabricFunctionality ) ; this . restoreCommandHijack = true ; panel . dispose ( ) ; } } ) ; } loadComponent ( _panel ) { return ; } async getHTMLString ( webview , _dependencies ? , isComplete ? , localFabricFunctionality ? ) { const packageJson = await ExtensionUtil . getPackageJSON ( ) ; const extensionPath = ExtensionUtil . getExtensionPath ( ) ; const extensionVersion = packageJson . version ; const dependencyManager = DependencyManager . instance ( ) ; const dependencies = _dependencies || this . dependencies || await dependencyManager . getPreReqVersions ( ) ; if ( isComplete === undefined ) { isComplete = await dependencyManager . hasPreReqsInstalled ( dependencies ) ; } const installedDependencies = { } ; const missingDependencies = { } ; let missingPrerequisitesLength = 0 ; for ( const _dependency of Object . keys ( dependencies ) ) { let dependency = dependencies [ _dependency ] ; if ( _dependency === 'node' ) { const modified = { ... dependencies [ _dependency ] , requiredVersion : dependencies [ _dependency ] . requiredVersion . replace ( /<.*\|\|/ , '||' ) . replace ( /<.*/ , '' ) , } ; dependency = modified ; } const isInstalled = dependencyManager . isValidDependency ( dependency ) ; if ( isInstalled ) { installedDependencies [ _dependency ] = dependency ; } else { missingDependencies [ _dependency ] = dependency ; if ( missingDependencies [ _dependency ] . required === true ) { missingPrerequisitesLength = missingPrerequisitesLength + 1 ; } } } const launchDark = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'light' , 'launch.svg' ) ) ) ; const launchLight = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'dark' , 'launch.svg' ) ) ) ; const chevronDark = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'dark' , 'chevron.svg' ) ) ) ; const chevronLight = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'light' , 'chevron.svg' ) ) ) ; const infoIconDark = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'dark' , 'info.svg' ) ) ) ; const infoIconLight = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'light' , 'info.svg' ) ) ) ; const celebrateImage = webview . asWebviewUri ( vscode . Uri . file ( path . join ( extensionPath , 'resources' , 'celebrate.svg' ) ) ) ; const images = { launchDark , launchLight , chevronDark , chevronLight , infoIconDark , infoIconLight , celebrateImage } ; if ( localFabricFunctionality === undefined ) { localFabricFunctionality = vscode . workspace . getConfiguration ( ) . get ( SettingConfigurations . EXTENSION_LOCAL_FABRIC ) ; } const options = { extensionVersion , installedDependencies , missingDependencies , missingPrerequisitesLength , images , commands : { OPEN_HOME_PAGE : ExtensionCommands . OPEN_HOME_PAGE } , isComplete , localFabricFunctionality } ; const templatePath = path . join ( __dirname , '..' , '..' , '..' , 'templates' , 'PreReqView.ejs' ) ; return await new Promise ( ( resolve , reject ) : any => { ejs . renderFile ( templatePath , options , { async : true } , ( error , data ) => { if ( error ) { reject ( error ) ; } else { resolve ( data ) ; } } ) ; } ) ; } }