1+ const fs = require ( 'fs' ) ;
2+ const logger = require ( './logger' ) ;
3+ const {
4+ exec
5+ } = require ( './exec' ) ;
6+ const loggerLabel = 'cordova-cli-requirements' ;
7+ const semver = require ( 'semver' ) ;
8+ const prompt = require ( 'prompt' ) ;
9+ const VERSIONS = {
10+ 'NODE' : '12.0.0' ,
11+ 'JAVA' : '1.8.0' ,
12+ 'GRADLE' : '6.0.1'
13+ }
14+
15+ async function checkAvailability ( cmd ) {
16+ try {
17+ let version = ( await exec ( cmd , [ '--version' ] ) ) . join ( '' ) ;
18+
19+ // to just return version in x.x.x format
20+ version = version . match ( / [ 0 - 9 \. ] + / ) [ 0 ] ;
21+
22+ logger . info ( {
23+ 'label' : loggerLabel ,
24+ 'message' : cmd + ' version available is ' + version
25+ } )
26+ const requiredVersion = VERSIONS [ cmd . toUpperCase ( ) ] ;
27+ if ( requiredVersion && semver . lt ( version , requiredVersion ) ) {
28+ logger . error ( 'Minimum ' + cmd + ' version required is ' + requiredVersion + '. Please update the version.' ) ;
29+ return false ;
30+ }
31+ return version ;
32+ } catch ( e ) {
33+ console . error ( e ) ;
34+ return false ;
35+ }
36+ }
37+
38+ module . exports = {
39+ showConfirmation : async ( message ) => {
40+ return new Promise ( ( resolve , reject ) => {
41+ prompt . get ( {
42+ properties : {
43+ confirm : {
44+ pattern : / ^ ( y e s | n o | y | n ) $ / gi,
45+ description : message ,
46+ message : 'Type yes/no' ,
47+ required : true ,
48+ default : 'no'
49+ }
50+ }
51+ } , function ( err , result ) {
52+ if ( err ) {
53+ reject ( ) ;
54+ }
55+ resolve ( result . confirm . toLowerCase ( ) ) ;
56+ } ) ;
57+ } ) ;
58+ } ,
59+ checkForGradleAvailability : async ( ) => {
60+ return await checkAvailability ( 'gradle' ) ;
61+ } ,
62+ checkForAndroidStudioAvailability : async ( ) => {
63+ // ANDROID_HOME environment variable is set or not. If it is set checking if its a valid path or no.
64+ const ANDROID_HOME = process . env [ 'ANDROID_HOME' ] ;
65+ const ANDROID_SDK_ROOT = process . env [ 'ANDROID_SDK_ROOT' ]
66+ if ( ANDROID_HOME && ! ANDROID_SDK_ROOT ) {
67+ logger . warn ( {
68+ 'label' : loggerLabel ,
69+ 'message' : 'ANDROID_HOME is deprecated. Recommended to set ANDROID_SDK_ROOT'
70+ } ) ;
71+ }
72+ envVariable = ANDROID_SDK_ROOT || ANDROID_HOME ;
73+ if ( ! envVariable ) {
74+ logger . error ( {
75+ 'label' : loggerLabel ,
76+ 'message' : 'Failed to find \'ANDROID_SDK_ROOT\' environment variable. Try setting it manually.\n' +
77+ 'Try update your \'PATH\' to include path to valid SDK directory.' } ) ;
78+ return false ;
79+ }
80+ if ( ! fs . existsSync ( envVariable ) ) {
81+ logger . error ( {
82+ 'label' : loggerLabel ,
83+ 'message' : '\'ANDROID_HOME\' environment variable is set to non-existent path: ' + process . env [ 'ANDROID_HOME' ] +
84+ '\nTry update it manually to point to valid SDK directory.' } ) ;
85+ return false ;
86+ }
87+ const sdkPath = envVariable + '/tools/bin/sdkmanager' ;
88+
89+ if ( ! fs . existsSync ( sdkPath ) ) {
90+ logger . error ( {
91+ 'label' : loggerLabel ,
92+ 'message' : 'Failed to find \'android-sdk\' in your \'PATH\'. Install Android-Studio before proceeding to build.' } ) ;
93+ return false ;
94+ }
95+ logger . info ( {
96+ 'label' : loggerLabel ,
97+ 'message' : 'Found Android SDK manager at ' + sdkPath
98+ } )
99+
100+ try {
101+ await exec ( 'sdkmanager' , [ '--list' ] ) ;
102+ } catch ( e ) {
103+ console . error ( e ) ;
104+ return false ;
105+ }
106+ return true ;
107+ } ,
108+ hasValidJavaVersion : async ( ) => {
109+ const javaVersion = ( await exec ( 'java' , [ '-version' ] ) ) . join ( '' ) . match ( / [ 0 - 9 \. ] + / ) [ 0 ] ;
110+
111+ if ( semver . lt ( javaVersion , VERSIONS . JAVA ) ) {
112+ logger . error ( 'Minimum java version required is' + VERSIONS . JAVA + '. Please update the java version.' ) ;
113+ return false ;
114+ }
115+
116+ const envVariable = process . env [ 'JAVA_HOME' ] ;
117+
118+ if ( ! envVariable ) {
119+ logger . error ( {
120+ 'label' : loggerLabel ,
121+ 'message' : 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.\n' +
122+ 'Try update your \'PATH\' to include path to valid directory.' } ) ;
123+ return false ;
124+ }
125+ return true ;
126+ } ,
127+ hasValidNodeVersion : async ( ) => {
128+ return await checkAvailability ( 'node' ) ;
129+ } ,
130+ isGitInstalled : async ( ) => {
131+ return await checkAvailability ( 'git' ) ;
132+ } ,
133+
134+ // TODO: cocoapod for ios
135+
136+ validate : ( keyStore , storePassword , keyAlias , keyPassword ) => {
137+ let errors = [ ] ;
138+ if ( ! ( keyStore && fs . existsSync ( keyStore ) ) ) {
139+ errors . push ( `keystore is required (valid file): ${ keyStore } ` ) ;
140+ }
141+ if ( ! keyAlias ) {
142+ errors . push ( 'keyAlias is required.' ) ;
143+ }
144+ if ( ! keyPassword ) {
145+ errors . push ( 'keyPassword is required.' ) ;
146+ }
147+ if ( ! storePassword ) {
148+ errors . push ( 'storePassword is required.' ) ;
149+ }
150+ return errors ;
151+ }
152+ }
0 commit comments