@@ -5,7 +5,6 @@ import * as semver from "semver";
5
5
import * as projectServiceBaseLib from "./platform-project-service-base" ;
6
6
import { DeviceAndroidDebugBridge } from "../common/mobile/android/device-android-debug-bridge" ;
7
7
import { attachAwaitDetach } from "../common/helpers" ;
8
- import { EOL } from "os" ;
9
8
import { Configurations } from "../common/constants" ;
10
9
import { SpawnOptions } from "child_process" ;
11
10
@@ -36,7 +35,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
36
35
private $injector : IInjector ,
37
36
private $pluginVariablesService : IPluginVariablesService ,
38
37
private $devicePlatformsConstants : Mobile . IDevicePlatformsConstants ,
39
- private $npm : INodePackageManager ) {
38
+ private $npm : INodePackageManager ,
39
+ private $projectV4MigrationService : IProjectV4MigrationService ) {
40
40
super ( $fs , $projectDataService ) ;
41
41
this . _androidProjectPropertiesManagers = Object . create ( null ) ;
42
42
this . isAndroidStudioTemplate = false ;
@@ -116,18 +116,32 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
116
116
return Promise . resolve ( true ) ;
117
117
}
118
118
119
- public getAppResourcesDestinationDirectoryPath ( projectData : IProjectData , frameworkVersion ?: string ) : string {
120
- if ( this . canUseGradle ( projectData , frameworkVersion ) ) {
121
- const resourcePath : string [ ] = [ constants . SRC_DIR , constants . MAIN_DIR , constants . RESOURCES_DIR ] ;
122
- if ( this . isAndroidStudioTemplate ) {
123
- resourcePath . unshift ( constants . APP_FOLDER_NAME ) ;
124
- }
119
+ public getAppResourcesDestinationDirectoryPath ( projectData : IProjectData ) : string {
120
+ const appResourcesDirStructureHasMigrated = this . $projectV4MigrationService . hasMigrated ( projectData . getAppResourcesDirectoryPath ( ) ) ;
121
+
122
+ if ( appResourcesDirStructureHasMigrated ) {
123
+ return this . getAppResourcesDestinationDirectoryPathUpdatedAppResourcesDirStructure ( projectData ) ;
124
+ } else {
125
+ return this . getAppResourcesDestinationDirectoryPathOldAppResourcesDirStructure ( projectData ) ;
126
+ }
127
+ }
128
+
129
+ private getAppResourcesDestinationDirectoryPathOldAppResourcesDirStructure ( projectData : IProjectData ) : string {
130
+ const resourcePath : string [ ] = [ constants . SRC_DIR , constants . MAIN_DIR , constants . RESOURCES_DIR ] ;
131
+ if ( this . isAndroidStudioTemplate ) {
132
+ resourcePath . unshift ( constants . APP_FOLDER_NAME ) ;
133
+ }
125
134
126
- return path . join ( this . getPlatformData ( projectData ) . projectRoot , ...resourcePath ) ;
135
+ return path . join ( this . getPlatformData ( projectData ) . projectRoot , ...resourcePath ) ;
136
+ }
127
137
138
+ private getAppResourcesDestinationDirectoryPathUpdatedAppResourcesDirStructure ( projectData : IProjectData ) : string {
139
+ const resourcePath : string [ ] = [ constants . SRC_DIR ] ;
140
+ if ( this . isAndroidStudioTemplate ) {
141
+ resourcePath . unshift ( constants . APP_FOLDER_NAME ) ;
128
142
}
129
143
130
- return path . join ( this . getPlatformData ( projectData ) . projectRoot , constants . RESOURCES_DIR ) ;
144
+ return path . join ( this . getPlatformData ( projectData ) . projectRoot , ... resourcePath ) ;
131
145
}
132
146
133
147
public async validate ( projectData : IProjectData ) : Promise < void > {
@@ -182,7 +196,7 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
182
196
this . copy ( this . getPlatformData ( projectData ) . projectRoot , frameworkDir , "gradlew gradlew.bat" , "-f" ) ;
183
197
}
184
198
185
- this . cleanResValues ( targetSdkVersion , projectData , frameworkVersion ) ;
199
+ this . cleanResValues ( targetSdkVersion , projectData ) ;
186
200
187
201
const npmConfig : INodePackageManagerInstallOptions = {
188
202
save : true ,
@@ -218,8 +232,8 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
218
232
}
219
233
}
220
234
221
- private cleanResValues ( targetSdkVersion : number , projectData : IProjectData , frameworkVersion : string ) : void {
222
- const resDestinationDir = this . getAppResourcesDestinationDirectoryPath ( projectData , frameworkVersion ) ;
235
+ private cleanResValues ( targetSdkVersion : number , projectData : IProjectData ) : void {
236
+ const resDestinationDir = this . getAppResourcesDestinationDirectoryPath ( projectData ) ;
223
237
const directoriesInResFolder = this . $fs . readDirectory ( resDestinationDir ) ;
224
238
const directoriesToClean = directoriesInResFolder
225
239
. map ( dir => {
@@ -243,16 +257,24 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
243
257
public async interpolateData ( projectData : IProjectData , platformSpecificData : IPlatformSpecificData ) : Promise < void > {
244
258
// Interpolate the apilevel and package
245
259
this . interpolateConfigurationFile ( projectData , platformSpecificData ) ;
260
+ const appResourcesDirectoryPath = projectData . getAppResourcesDirectoryPath ( ) ;
261
+
262
+ let stringsFilePath : string ;
263
+
264
+ if ( ! this . $projectV4MigrationService . hasMigrated ( appResourcesDirectoryPath ) ) {
265
+ stringsFilePath = path . join ( this . getAppResourcesDestinationDirectoryPath ( projectData ) , 'values' , 'strings.xml' ) ;
266
+ } else {
267
+ stringsFilePath = path . join ( this . getAppResourcesDestinationDirectoryPath ( projectData ) , "main" , "res" , 'values' , 'strings.xml' ) ;
268
+ }
246
269
247
- const stringsFilePath = path . join ( this . getAppResourcesDestinationDirectoryPath ( projectData ) , 'values' , 'strings.xml' ) ;
248
270
shell . sed ( '-i' , / _ _ N A M E _ _ / , projectData . projectName , stringsFilePath ) ;
249
271
shell . sed ( '-i' , / _ _ T I T L E _ A C T I V I T Y _ _ / , projectData . projectName , stringsFilePath ) ;
250
272
251
273
const gradleSettingsFilePath = path . join ( this . getPlatformData ( projectData ) . projectRoot , "settings.gradle" ) ;
252
274
shell . sed ( '-i' , / _ _ P R O J E C T _ N A M E _ _ / , this . getProjectNameFromId ( projectData ) , gradleSettingsFilePath ) ;
253
275
254
276
// will replace applicationId in app/App_Resources/Android/app.gradle if it has not been edited by the user
255
- const userAppGradleFilePath = path . join ( projectData . getAppResourcesDirectoryPath ( ) , this . $devicePlatformsConstants . Android , "app.gradle" ) ;
277
+ const userAppGradleFilePath = path . join ( appResourcesDirectoryPath , this . $devicePlatformsConstants . Android , "app.gradle" ) ;
256
278
257
279
try {
258
280
shell . sed ( '-i' , / _ _ P A C K A G E _ _ / , projectData . projectId , userAppGradleFilePath ) ;
@@ -300,33 +322,28 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
300
322
}
301
323
302
324
public async buildProject ( projectRoot : string , projectData : IProjectData , buildConfig : IBuildConfig ) : Promise < void > {
303
- if ( this . canUseGradle ( projectData ) ) {
304
- const buildOptions = this . getBuildOptions ( buildConfig , projectData ) ;
305
- if ( this . $logger . getLevel ( ) === "TRACE" ) {
306
- buildOptions . unshift ( "--stacktrace" ) ;
307
- buildOptions . unshift ( "--debug" ) ;
308
- }
309
- if ( buildConfig . release ) {
310
- buildOptions . unshift ( "assembleRelease" ) ;
311
- } else {
312
- buildOptions . unshift ( "assembleDebug" ) ;
313
- }
314
-
315
- const handler = ( data : any ) => {
316
- this . emit ( constants . BUILD_OUTPUT_EVENT_NAME , data ) ;
317
- } ;
318
-
319
- await attachAwaitDetach ( constants . BUILD_OUTPUT_EVENT_NAME ,
320
- this . $childProcess ,
321
- handler ,
322
- this . executeGradleCommand ( this . getPlatformData ( projectData ) . projectRoot ,
323
- buildOptions ,
324
- { stdio : buildConfig . buildOutputStdio || "inherit" } ,
325
- { emitOptions : { eventName : constants . BUILD_OUTPUT_EVENT_NAME } , throwError : true } ) ) ;
325
+ const buildOptions = this . getBuildOptions ( buildConfig , projectData ) ;
326
+ if ( this . $logger . getLevel ( ) === "TRACE" ) {
327
+ buildOptions . unshift ( "--stacktrace" ) ;
328
+ buildOptions . unshift ( "--debug" ) ;
329
+ }
330
+ if ( buildConfig . release ) {
331
+ buildOptions . unshift ( "assembleRelease" ) ;
326
332
} else {
327
- this . $errors . failWithoutHelp ( "Cannot complete build because this project is ANT-based." + EOL +
328
- "Run `tns platform remove android && tns platform add android` to switch to Gradle and try again." ) ;
333
+ buildOptions . unshift ( "assembleDebug" ) ;
329
334
}
335
+
336
+ const handler = ( data : any ) => {
337
+ this . emit ( constants . BUILD_OUTPUT_EVENT_NAME , data ) ;
338
+ } ;
339
+
340
+ await attachAwaitDetach ( constants . BUILD_OUTPUT_EVENT_NAME ,
341
+ this . $childProcess ,
342
+ handler ,
343
+ this . executeGradleCommand ( this . getPlatformData ( projectData ) . projectRoot ,
344
+ buildOptions ,
345
+ { stdio : buildConfig . buildOutputStdio || "inherit" } ,
346
+ { emitOptions : { eventName : constants . BUILD_OUTPUT_EVENT_NAME } , throwError : true } ) ) ;
330
347
}
331
348
332
349
private getBuildOptions ( settings : IAndroidBuildOptionsSettings , projectData : IProjectData ) : Array < string > {
@@ -374,7 +391,15 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
374
391
}
375
392
376
393
public ensureConfigurationFileInAppResources ( projectData : IProjectData ) : void {
377
- const originalAndroidManifestFilePath = path . join ( projectData . getAppResourcesDirectoryPath ( ) , this . $devicePlatformsConstants . Android , this . getPlatformData ( projectData ) . configurationFileName ) ;
394
+ const appResourcesDirectoryPath = projectData . getAppResourcesDirectoryPath ( ) ;
395
+ const appResourcesDirStructureHasMigrated = this . $projectV4MigrationService . hasMigrated ( appResourcesDirectoryPath ) ;
396
+ let originalAndroidManifestFilePath ;
397
+
398
+ if ( appResourcesDirStructureHasMigrated ) {
399
+ originalAndroidManifestFilePath = path . join ( appResourcesDirectoryPath , this . $devicePlatformsConstants . Android , "src" , "main" , this . getPlatformData ( projectData ) . configurationFileName ) ;
400
+ } else {
401
+ originalAndroidManifestFilePath = path . join ( appResourcesDirectoryPath , this . $devicePlatformsConstants . Android , this . getPlatformData ( projectData ) . configurationFileName ) ;
402
+ }
378
403
379
404
const manifestExists = this . $fs . exists ( originalAndroidManifestFilePath ) ;
380
405
@@ -383,16 +408,13 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
383
408
return ;
384
409
}
385
410
// Overwrite the AndroidManifest from runtime.
386
- this . $fs . copyFile ( originalAndroidManifestFilePath , this . getPlatformData ( projectData ) . configurationFilePath ) ;
411
+ if ( ! appResourcesDirStructureHasMigrated ) {
412
+ this . $fs . copyFile ( originalAndroidManifestFilePath , this . getPlatformData ( projectData ) . configurationFilePath ) ;
413
+ }
387
414
}
388
415
389
416
public prepareAppResources ( appResourcesDirectoryPath : string , projectData : IProjectData ) : void {
390
- const resourcesDirPath = path . join ( appResourcesDirectoryPath , this . getPlatformData ( projectData ) . normalizedPlatformName ) ;
391
- const valuesDirRegExp = / ^ v a l u e s / ;
392
- const resourcesDirs = this . $fs . readDirectory ( resourcesDirPath ) . filter ( resDir => ! resDir . match ( valuesDirRegExp ) ) ;
393
- _ . each ( resourcesDirs , resourceDir => {
394
- this . $fs . deleteDirectory ( path . join ( this . getAppResourcesDestinationDirectoryPath ( projectData ) , resourceDir ) ) ;
395
- } ) ;
417
+ // Intentionally left empty
396
418
}
397
419
398
420
public async preparePluginNativeCode ( pluginData : IPluginData , projectData : IProjectData ) : Promise < void > {
@@ -542,20 +564,6 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject
542
564
// Nothing android specific to check yet.
543
565
}
544
566
545
- private _canUseGradle : boolean ;
546
- private canUseGradle ( projectData : IProjectData , frameworkVersion ?: string ) : boolean {
547
- if ( ! this . _canUseGradle ) {
548
- if ( ! frameworkVersion ) {
549
- const frameworkInfoInProjectFile = this . $projectDataService . getNSValue ( projectData . projectDir , this . getPlatformData ( projectData ) . frameworkPackageName ) ;
550
- frameworkVersion = frameworkInfoInProjectFile && frameworkInfoInProjectFile . version ;
551
- }
552
-
553
- this . _canUseGradle = ! frameworkVersion || semver . gte ( frameworkVersion , AndroidProjectService . MIN_RUNTIME_VERSION_WITH_GRADLE ) ;
554
- }
555
-
556
- return this . _canUseGradle ;
557
- }
558
-
559
567
private copy ( projectRoot : string , frameworkDir : string , files : string , cpArg : string ) : void {
560
568
const paths = files . split ( ' ' ) . map ( p => path . join ( frameworkDir , p ) ) ;
561
569
shell . cp ( cpArg , paths , projectRoot ) ;
0 commit comments