@@ -18,11 +18,11 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
1818 private static MIN_RUNTIME_VERSION_WITH_GRADLE = "1.3.0" ;
1919 private static MIN_REQUIRED_NODEJS_VERSION_FOR_STATIC_BINDINGS = "4.2.1" ;
2020 private static REQUIRED_DEV_DEPENDENCIES = [
21- { name : "babel-traverse" , version : "^6.4.5" } ,
22- { name : "babel-types" , version : "^6.4.5" } ,
23- { name : "babylon" , version : "^6.4.5" } ,
24- { name : "filewalker" , version : "^0.1.2" } ,
25- { name : "lazy" , version : "^1.0.11" }
21+ { name : "babel-traverse" , version : "^6.4.5" } ,
22+ { name : "babel-types" , version : "^6.4.5" } ,
23+ { name : "babylon" , version : "^6.4.5" } ,
24+ { name : "filewalker" , version : "^0.1.2" } ,
25+ { name : "lazy" , version : "^1.0.11" }
2626 ] ;
2727
2828 private get sysInfoData ( ) : ISysInfoData {
@@ -50,8 +50,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
5050 private $projectTemplatesService : IProjectTemplatesService ,
5151 private $xmlValidator : IXmlValidator ,
5252 private $npm : INodePackageManager ) {
53- super ( $fs , $projectData , $projectDataService ) ;
54- this . _androidProjectPropertiesManagers = Object . create ( null ) ;
53+ super ( $fs , $projectData , $projectDataService ) ;
54+ this . _androidProjectPropertiesManagers = Object . create ( null ) ;
5555 }
5656
5757 private _platformData : IPlatformData = null ;
@@ -86,7 +86,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
8686
8787 public getAppResourcesDestinationDirectoryPath ( frameworkVersion ?: string ) : IFuture < string > {
8888 return ( ( ) => {
89- if ( this . canUseGradle ( frameworkVersion ) . wait ( ) ) {
89+ if ( this . canUseGradle ( frameworkVersion ) . wait ( ) ) {
9090 return path . join ( this . platformData . projectRoot , "src" , "main" , "res" ) ;
9191 }
9292
@@ -100,30 +100,30 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
100100 this . validateProjectName ( this . $projectData . projectName ) ;
101101
102102 // this call will fail in case `android` is not set correctly.
103- this . $androidToolsInfo . getPathToAndroidExecutable ( { showWarningsAsErrors : true } ) . wait ( ) ;
104- this . $androidToolsInfo . validateJavacVersion ( this . sysInfoData . javacVersion , { showWarningsAsErrors : true } ) . wait ( ) ;
103+ this . $androidToolsInfo . getPathToAndroidExecutable ( { showWarningsAsErrors : true } ) . wait ( ) ;
104+ this . $androidToolsInfo . validateJavacVersion ( this . sysInfoData . javacVersion , { showWarningsAsErrors : true } ) . wait ( ) ;
105105 } ) . future < void > ( ) ( ) ;
106106 }
107107
108108 public createProject ( frameworkDir : string , frameworkVersion : string , pathToTemplate ?: string ) : IFuture < void > {
109109 return ( ( ) => {
110- if ( semver . lt ( frameworkVersion , AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE ) ) {
110+ if ( semver . lt ( frameworkVersion , AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE ) ) {
111111 this . $errors . failWithoutHelp ( `The NativeScript CLI requires Android runtime ${ AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE } or later to work properly.` ) ;
112112 }
113113
114114 this . $fs . ensureDirectoryExists ( this . platformData . projectRoot ) . wait ( ) ;
115- this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) . wait ( ) ;
115+ this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) . wait ( ) ;
116116 let androidToolsInfo = this . $androidToolsInfo . getToolsInfo ( ) . wait ( ) ;
117117 let targetSdkVersion = androidToolsInfo . targetSdkVersion ;
118118 this . $logger . trace ( `Using Android SDK '${ targetSdkVersion } '.` ) ;
119- if ( this . $options . symlink ) {
119+ if ( this . $options . symlink ) {
120120 this . symlinkDirectory ( "libs" , this . platformData . projectRoot , frameworkDir ) . wait ( ) ;
121121 } else {
122122 this . copy ( this . platformData . projectRoot , frameworkDir , "libs" , "-R" ) ;
123123 }
124124
125125 // These files and directories should not be symlinked as CLI is modifying them and we'll change the original values as well.
126- if ( pathToTemplate ) {
126+ if ( pathToTemplate ) {
127127 let mainPath = path . join ( this . platformData . projectRoot , "src" , "main" ) ;
128128 this . $fs . createDirectory ( mainPath ) . wait ( ) ;
129129 shell . cp ( "-R" , path . join ( path . resolve ( pathToTemplate ) , "*" ) , mainPath ) ;
@@ -138,17 +138,25 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
138138 }
139139
140140 this . cleanResValues ( targetSdkVersion , frameworkVersion ) . wait ( ) ;
141- if ( this . canUseStaticBindingGenerator ( ) ) {
141+ if ( this . canUseStaticBindingGenerator ( ) ) {
142142 let npmConfig = {
143143 "save" : true ,
144144 "save-dev" : true ,
145145 "save-exact" : true ,
146146 "silent" : true
147147 } ;
148148
149- _ . each ( AndroidProjectService . REQUIRED_DEV_DEPENDENCIES , ( dependency : any ) =>
150- this . $npm . install ( `${ dependency . name } @${ dependency . version } ` , this . $projectData . projectDir , npmConfig ) . wait ( )
151- ) ;
149+ let projectPackageJson : any = this . $fs . readJson ( this . $projectData . projectFilePath ) . wait ( ) ;
150+
151+ _ . each ( AndroidProjectService . REQUIRED_DEV_DEPENDENCIES , ( dependency : any ) => {
152+ let dependencyVersionInProject = projectPackageJson . dependencies [ dependency . name ] || projectPackageJson . devDependencies [ dependency . name ] ;
153+
154+ if ( ! dependencyVersionInProject ) {
155+ this . $npm . install ( `${ dependency . name } @${ dependency . version } ` , this . $projectData . projectDir , npmConfig ) . wait ( ) ;
156+ } else if ( ! semver . satisfies ( dependencyVersionInProject , dependency . version ) ) {
157+ this . $errors . failWithoutHelp ( `Your project have installed ${ dependency . name } version ${ dependencyVersionInProject } but Android platform requires version ${ dependency . version } .` ) ;
158+ }
159+ } ) ;
152160 } else {
153161 this . $logger . printMarkdown ( ` As you are using Node.js \`${ this . sysInfoData . nodeVer } \` Static Binding Generator will be turned off.` +
154162 `Upgrade your Node.js to ${ AndroidProjectService . MIN_REQUIRED_NODEJS_VERSION_FOR_STATIC_BINDINGS } or later, so you can use this feature.` ) ;
@@ -170,14 +178,15 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
170178 let resDestinationDir = this . getAppResourcesDestinationDirectoryPath ( frameworkVersion ) . wait ( ) ;
171179 let directoriesInResFolder = this . $fs . readDirectory ( resDestinationDir ) . wait ( ) ;
172180 let directoriesToClean = directoriesInResFolder
173- . map ( dir => { return {
181+ . map ( dir => {
182+ return {
174183 dirName : dir ,
175184 sdkNum : parseInt ( dir . substr ( AndroidProjectService . VALUES_VERSION_DIRNAME_PREFIX . length ) )
176185 } ;
177186 } )
178187 . filter ( dir => dir . dirName . match ( AndroidProjectService . VALUES_VERSION_DIRNAME_PREFIX )
179- && dir . sdkNum
180- && ( ! targetSdkVersion || ( targetSdkVersion < dir . sdkNum ) ) )
188+ && dir . sdkNum
189+ && ( ! targetSdkVersion || ( targetSdkVersion < dir . sdkNum ) ) )
181190 . map ( dir => path . join ( resDestinationDir , dir . dirName ) ) ;
182191 this . $logger . trace ( "Directories to clean:" ) ;
183192 this . $logger . trace ( directoriesToClean ) ;
@@ -209,7 +218,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
209218
210219 private getProjectNameFromId ( ) : string {
211220 let id : string ;
212- if ( this . $projectData && this . $projectData . projectId ) {
221+ if ( this . $projectData && this . $projectData . projectId ) {
213222 id = this . $projectData . projectId . split ( "." ) [ 2 ] ;
214223 }
215224
@@ -226,7 +235,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
226235
227236 public updatePlatform ( currentVersion : string , newVersion : string , canUpdate : boolean , addPlatform ?: Function , removePlatforms ?: ( platforms : string [ ] ) => IFuture < void > ) : IFuture < boolean > {
228237 return ( ( ) => {
229- if ( semver . eq ( newVersion , AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE ) ) {
238+ if ( semver . eq ( newVersion , AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE ) ) {
230239 let platformLowercase = this . platformData . normalizedPlatformName . toLowerCase ( ) ;
231240 removePlatforms ( [ platformLowercase . split ( "@" ) [ 0 ] ] ) . wait ( ) ;
232241 addPlatform ( platformLowercase ) . wait ( ) ;
@@ -239,8 +248,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
239248
240249 public buildProject ( projectRoot : string , buildConfig ?: IBuildConfig ) : IFuture < void > {
241250 return ( ( ) => {
242- if ( this . canUseGradle ( ) . wait ( ) ) {
243- this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) . wait ( ) ;
251+ if ( this . canUseGradle ( ) . wait ( ) ) {
252+ this . $androidToolsInfo . validateInfo ( { showWarningsAsErrors : true , validateTargetSdk : true } ) . wait ( ) ;
244253 let androidToolsInfo = this . $androidToolsInfo . getToolsInfo ( ) . wait ( ) ;
245254 let compileSdk = androidToolsInfo . compileSdkVersion ;
246255 let targetSdk = this . getTargetFromAndroidManifest ( ) . wait ( ) || compileSdk ;
@@ -253,15 +262,15 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
253262 `-PsupportVersion=${ appCompatVersion } ` ,
254263 ] ;
255264
256- if ( this . $options . release ) {
265+ if ( this . $options . release ) {
257266 buildOptions . push ( "-Prelease" ) ;
258267 buildOptions . push ( `-PksPath=${ path . resolve ( this . $options . keyStorePath ) } ` ) ;
259268 buildOptions . push ( `-Palias=${ this . $options . keyStoreAlias } ` ) ;
260269 buildOptions . push ( `-Ppassword=${ this . $options . keyStoreAliasPassword } ` ) ;
261270 buildOptions . push ( `-PksPassword=${ this . $options . keyStorePassword } ` ) ;
262271 }
263272
264- if ( ! this . canUseStaticBindingGenerator ( ) ) {
273+ if ( ! this . canUseStaticBindingGenerator ( ) ) {
265274 buildOptions . push ( "-PdontRunSbg" ) ;
266275 }
267276
@@ -296,7 +305,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
296305
297306 // In case the file is not correct, looks like we are still using the default AndroidManifest.xml from runtime and the current file (in res dir)
298307 // should be merged with it.
299- if ( this . isAndroidManifestFileCorrect ( androidManifestPath ) . wait ( ) ) {
308+ if ( this . isAndroidManifestFileCorrect ( androidManifestPath ) . wait ( ) ) {
300309 // Delete the AndroidManifest.xml file from res directory as the runtime will consider it as addition to the one in src/main and will try to merge them.
301310 // However now they are the same file.
302311 this . $fs . deleteFile ( androidManifestPath ) . wait ( ) ;
@@ -312,7 +321,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
312321
313322 // In case we should extract the manifest from default template, but for some reason we cannot, break the execution,
314323 // so the original file from Android runtime will be used.
315- if ( shouldExtractDefaultManifest && ! this . extractAndroidManifestFromDefaultTemplate ( originalAndroidManifestFilePath ) . wait ( ) ) {
324+ if ( shouldExtractDefaultManifest && ! this . extractAndroidManifestFromDefaultTemplate ( originalAndroidManifestFilePath ) . wait ( ) ) {
316325 return ;
317326 }
318327
@@ -366,7 +375,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
366375
367376 // Copy include.gradle file
368377 let includeGradleFilePath = path . join ( pluginPlatformsFolderPath , "include.gradle" ) ;
369- if ( this . $fs . exists ( includeGradleFilePath ) . wait ( ) ) {
378+ if ( this . $fs . exists ( includeGradleFilePath ) . wait ( ) ) {
370379 shell . cp ( "-f" , includeGradleFilePath , pluginConfigurationDirectoryPath ) ;
371380 }
372381 } ) . future < void > ( ) ( ) ;
@@ -377,7 +386,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
377386 try {
378387 this . $fs . deleteDirectory ( path . join ( this . platformData . projectRoot , "configurations" , pluginData . name ) ) . wait ( ) ;
379388 this . $fs . deleteDirectory ( path . join ( this . platformData . projectRoot , "src" , pluginData . name ) ) . wait ( ) ;
380- } catch ( e ) {
389+ } catch ( e ) {
381390 if ( e . code === "ENOENT" ) {
382391 this . $logger . debug ( "No native code jars found: " + e . message ) ;
383392 } else {
@@ -412,8 +421,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
412421 private _canUseGradle : boolean ;
413422 private canUseGradle ( frameworkVersion ?: string ) : IFuture < boolean > {
414423 return ( ( ) => {
415- if ( ! this . _canUseGradle ) {
416- if ( ! frameworkVersion ) {
424+ if ( ! this . _canUseGradle ) {
425+ if ( ! frameworkVersion ) {
417426 this . $projectDataService . initialize ( this . $projectData . projectDir ) ;
418427 frameworkVersion = this . $projectDataService . getValue ( this . platformData . frameworkPackageName ) . wait ( ) . version ;
419428 }
@@ -431,7 +440,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
431440 }
432441
433442 private spawn ( command : string , args : string [ ] , opts ?: any ) : IFuture < void > {
434- return this . $childProcess . spawnFromEvent ( command , args , "close" , opts || { stdio : "inherit" } ) ;
443+ return this . $childProcess . spawnFromEvent ( command , args , "close" , opts || { stdio : "inherit" } ) ;
435444 }
436445
437446 private validatePackageName ( packageName : string ) : void {
@@ -442,7 +451,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
442451 }
443452
444453 //Class is a reserved word
445- if ( / \b [ C c ] l a s s \b / . test ( packageName ) ) {
454+ if ( / \b [ C c ] l a s s \b / . test ( packageName ) ) {
446455 this . $errors . fail ( "class is a reserved word" ) ;
447456 }
448457 }
@@ -463,9 +472,9 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
463472 let versionInManifest : string ;
464473 if ( this . $fs . exists ( this . platformData . configurationFilePath ) . wait ( ) ) {
465474 let targetFromAndroidManifest : string = this . $fs . readText ( this . platformData . configurationFilePath ) . wait ( ) ;
466- if ( targetFromAndroidManifest ) {
475+ if ( targetFromAndroidManifest ) {
467476 let match = targetFromAndroidManifest . match ( / .* ?a n d r o i d : t a r g e t S d k V e r s i o n = \" ( .* ?) \" / ) ;
468- if ( match && match [ 1 ] ) {
477+ if ( match && match [ 1 ] ) {
469478 versionInManifest = match [ 1 ] ;
470479 }
471480 }
@@ -483,7 +492,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
483492 _ . each ( directoryContent , ( file : string ) => {
484493 let sourceFilePath = path . join ( frameworkDir , directoryName , file ) ;
485494 let destinationFilePath = path . join ( projectRoot , directoryName , file ) ;
486- if ( this . $fs . getFsStats ( sourceFilePath ) . wait ( ) . isFile ( ) ) {
495+ if ( this . $fs . getFsStats ( sourceFilePath ) . wait ( ) . isFile ( ) ) {
487496 this . $fs . symlink ( sourceFilePath , destinationFilePath ) . wait ( ) ;
488497 } else {
489498 this . $fs . symlink ( sourceFilePath , destinationFilePath , "dir" ) . wait ( ) ;
@@ -500,15 +509,15 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
500509 // Use a real magic to detect if this is the correct file, by checking some mandatory strings.
501510 let fileContent = this . $fs . readText ( pathToAndroidManifest ) . wait ( ) ,
502511 isFileCorrect = ! ! ( ~ fileContent . indexOf ( "android:minSdkVersion" ) && ~ fileContent . indexOf ( "android:targetSdkVersion" )
503- && ~ fileContent . indexOf ( "uses-permission" ) && ~ fileContent . indexOf ( "<application" )
504- && ~ fileContent . indexOf ( "<activity" ) && ~ fileContent . indexOf ( "<intent-filter>" )
505- && ~ fileContent . indexOf ( "android.intent.action.MAIN" ) && ~ fileContent . indexOf ( "com.tns.ErrorReportActivity" )
506- && ~ fileContent . indexOf ( "android:versionCode" )
507- && ! this . $xmlValidator . getXmlFileErrors ( pathToAndroidManifest ) . wait ( ) ) ;
512+ && ~ fileContent . indexOf ( "uses-permission" ) && ~ fileContent . indexOf ( "<application" )
513+ && ~ fileContent . indexOf ( "<activity" ) && ~ fileContent . indexOf ( "<intent-filter>" )
514+ && ~ fileContent . indexOf ( "android.intent.action.MAIN" ) && ~ fileContent . indexOf ( "com.tns.ErrorReportActivity" )
515+ && ~ fileContent . indexOf ( "android:versionCode" )
516+ && ! this . $xmlValidator . getXmlFileErrors ( pathToAndroidManifest ) . wait ( ) ) ;
508517
509518 this . $logger . trace ( `Existing ${ this . platformData . configurationFileName } is ${ isFileCorrect ? "" : "NOT " } correct.` ) ;
510519 return isFileCorrect ;
511- } catch ( err ) {
520+ } catch ( err ) {
512521 this . $logger . trace ( `Error while checking ${ pathToAndroidManifest } : ` , err ) ;
513522 return false ;
514523 }
@@ -519,9 +528,9 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
519528
520529 private getConfigurationFileBackupName ( originalAndroidManifestFilePath : string ) : IFuture < string > {
521530 return ( ( ) => {
522- if ( ! this . _configurationFileBackupName ) {
531+ if ( ! this . _configurationFileBackupName ) {
523532 let defaultBackupName = this . platformData . configurationFileName + ".backup" ;
524- if ( this . $fs . exists ( path . join ( path . dirname ( originalAndroidManifestFilePath ) , defaultBackupName ) ) . wait ( ) ) {
533+ if ( this . $fs . exists ( path . join ( path . dirname ( originalAndroidManifestFilePath ) , defaultBackupName ) ) . wait ( ) ) {
525534 defaultBackupName += `_${ createGUID ( false ) } ` ;
526535 }
527536 this . _configurationFileBackupName = defaultBackupName ;
@@ -541,7 +550,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
541550 private revertBackupOfOriginalAndroidManifest ( originalAndroidManifestFilePath : string ) : IFuture < void > {
542551 return ( ( ) => {
543552 let pathToBackupFile = path . join ( path . dirname ( originalAndroidManifestFilePath ) , this . getConfigurationFileBackupName ( originalAndroidManifestFilePath ) . wait ( ) ) ;
544- if ( this . $fs . exists ( pathToBackupFile ) . wait ( ) ) {
553+ if ( this . $fs . exists ( pathToBackupFile ) . wait ( ) ) {
545554 this . $logger . trace ( `Could not extract ${ this . platformData . configurationFileName } from default template. Reverting the change of your app/App_Resources/${ this . platformData . configurationFileName } .` ) ;
546555 shell . mv ( pathToBackupFile , originalAndroidManifestFilePath ) ;
547556 }
@@ -556,11 +565,11 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
556565 if ( this . $fs . exists ( templateAndroidManifest ) . wait ( ) ) {
557566 this . $logger . trace ( `${ originalAndroidManifestFilePath } is missing. Upgrading the source of the project with one from the new project template. Copy ${ templateAndroidManifest } to ${ originalAndroidManifestFilePath } ` ) ;
558567 try {
559- if ( alreadyHasAndroidManifest ) {
568+ if ( alreadyHasAndroidManifest ) {
560569 this . backupOriginalAndroidManifest ( originalAndroidManifestFilePath ) . wait ( ) ;
561570 }
562571 this . $fs . copyFile ( templateAndroidManifest , originalAndroidManifestFilePath ) . wait ( ) ;
563- } catch ( e ) {
572+ } catch ( e ) {
564573 this . $logger . trace ( `Copying template's ${ this . platformData . configurationFileName } failed. ` , e ) ;
565574 this . revertBackupOfOriginalAndroidManifest ( originalAndroidManifestFilePath ) . wait ( ) ;
566575 return false ;
@@ -570,7 +579,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
570579 return false ;
571580 }
572581
573- if ( alreadyHasAndroidManifest ) {
582+ if ( alreadyHasAndroidManifest ) {
574583 this . $logger . warn ( `Your ${ this . platformData . configurationFileName } in app/App_Resources/Android will be replaced by the default one from hello-world template.` ) ;
575584 this . $logger . printMarkdown ( `The original file will be moved to \`${ this . getConfigurationFileBackupName ( originalAndroidManifestFilePath ) . wait ( ) } \`. Merge it **manually** with the new \`${ this . platformData . configurationFileName } \` in your app/App_Resources/Android.` ) ;
576585 }
0 commit comments