@@ -27,8 +27,10 @@ const os = require('os');
2727const git = require ( 'simple-git' ) ( ) ;
2828const source = require ( 'vinyl-source-stream' ) ;
2929const stream = require ( 'stream' ) ;
30+ const prompt = require ( 'gulp-prompt' ) ;
3031
3132const cordova = require ( "cordova-lib" ) . cordova ;
33+
3234const browserify = require ( 'browserify' ) ;
3335const glob = require ( 'glob' ) ;
3436
@@ -45,7 +47,6 @@ const NODE_ENV = process.env.NODE_ENV || 'production';
4547
4648const NAME_REGEX = / - / g;
4749
48-
4950const nwBuilderOptions = {
5051 version : '0.54.1' ,
5152 files : `${ DIST_DIR } **/*` ,
@@ -110,18 +111,18 @@ const debugDistBuild = gulp.series(process_package_debug, dist_src, dist_changel
110111const distRebuild = gulp . series ( clean_dist , distBuild ) ;
111112gulp . task ( 'dist' , distRebuild ) ;
112113
113- const appsBuild = gulp . series ( gulp . parallel ( clean_apps , distRebuild ) , apps , gulp . series ( cordova_apps ( ) ) , gulp . parallel ( listPostBuildTasks ( APPS_DIR ) ) ) ;
114+ const appsBuild = gulp . series ( gulp . parallel ( clean_apps , distRebuild ) , apps , gulp . series ( cordova_apps ( true ) ) , gulp . parallel ( listPostBuildTasks ( APPS_DIR ) ) ) ;
114115gulp . task ( 'apps' , appsBuild ) ;
115116
116- const debugAppsBuild = gulp . series ( gulp . parallel ( clean_debug , gulp . series ( clean_dist , debugDistBuild ) ) , debug , gulp . series ( cordova_apps ( ) ) , gulp . parallel ( listPostBuildTasks ( DEBUG_DIR ) ) ) ;
117+ const debugAppsBuild = gulp . series ( gulp . parallel ( clean_debug , gulp . series ( clean_dist , debugDistBuild ) ) , debug , gulp . series ( cordova_apps ( false ) ) , gulp . parallel ( listPostBuildTasks ( DEBUG_DIR ) ) ) ;
117118
118119const debugBuild = gulp . series ( debugDistBuild , debug , gulp . parallel ( listPostBuildTasks ( DEBUG_DIR ) ) , start_debug ) ;
119120gulp . task ( 'debug' , debugBuild ) ;
120121
121- const releaseBuild = gulp . series ( gulp . parallel ( clean_release , appsBuild ) , gulp . parallel ( listReleaseTasks ( APPS_DIR ) ) ) ;
122+ const releaseBuild = gulp . series ( gulp . parallel ( clean_release , appsBuild ) , gulp . parallel ( listReleaseTasks ( true , APPS_DIR ) ) ) ;
122123gulp . task ( 'release' , releaseBuild ) ;
123124
124- const debugReleaseBuild = gulp . series ( gulp . parallel ( clean_release , debugAppsBuild ) , gulp . parallel ( listReleaseTasks ( DEBUG_DIR ) ) ) ;
125+ const debugReleaseBuild = gulp . series ( gulp . parallel ( clean_release , debugAppsBuild ) , gulp . parallel ( listReleaseTasks ( false , DEBUG_DIR ) ) ) ;
125126gulp . task ( 'debug-release' , debugReleaseBuild ) ;
126127
127128gulp . task ( 'default' , debugBuild ) ;
@@ -292,21 +293,48 @@ function processPackage(done, gitRevision, isReleaseBuild) {
292293 metadata . packageId = pkg . name ;
293294 }
294295
295- const packageJson = new stream . Readable ;
296- packageJson . push ( JSON . stringify ( pkg , undefined , 2 ) ) ;
297- packageJson . push ( null ) ;
296+ function version_prompt ( ) {
297+ return gulp . src ( '.' )
298+ . pipe ( prompt . prompt ( [ {
299+ type : 'input' ,
300+ name : 'version' ,
301+ message : `Package version (default: ${ pkg . version } ):` ,
302+ } , {
303+ type : 'input' ,
304+ name : 'storeVersion' ,
305+ message : 'Google Play store version (<x.y.z>, default: package version):' ,
306+ } ] , function ( res ) {
307+ if ( res . version ) {
308+ pkg . version = res . version ;
309+ }
310+ if ( res . storeVersion ) {
311+ metadata . storeVersion = res . storeVersion ;
312+ }
313+ } ) ) ;
314+ }
298315
299- Object . keys ( pkg )
300- . filter ( key => metadataKeys . includes ( key ) )
301- . forEach ( ( key ) => {
302- metadata [ key ] = pkg [ key ] ;
303- } ) ;
316+ function write_package_file ( ) {
317+ Object . keys ( pkg )
318+ . filter ( key => metadataKeys . includes ( key ) )
319+ . forEach ( ( key ) => {
320+ metadata [ key ] = pkg [ key ] ;
321+ } ) ;
304322
305- packageJson
306- . pipe ( source ( 'package.json' ) )
307- . pipe ( gulp . dest ( DIST_DIR ) ) ;
323+ const packageJson = new stream . Readable ;
324+ packageJson . push ( JSON . stringify ( pkg , undefined , 2 ) ) ;
325+ packageJson . push ( null ) ;
308326
309- done ( ) ;
327+ return packageJson
328+ . pipe ( source ( 'package.json' ) )
329+ . pipe ( gulp . dest ( DIST_DIR ) ) ;
330+ }
331+
332+ const platforms = getPlatforms ( ) ;
333+ if ( platforms . indexOf ( 'android' ) !== - 1 && isReleaseBuild ) {
334+ gulp . series ( version_prompt , write_package_file ) ( done ) ;
335+ } else {
336+ gulp . series ( write_package_file ) ( done ) ;
337+ }
310338}
311339
312340function dist_src ( ) {
@@ -465,7 +493,7 @@ function debug(done) {
465493 buildNWAppsWrapper ( platforms , 'sdk' , DEBUG_DIR , done ) ;
466494}
467495
468- function injectARMCache ( flavor , callback ) {
496+ function injectARMCache ( flavor , done ) {
469497 const flavorPostfix = `-${ flavor } ` ;
470498 const flavorDownloadPostfix = flavor !== 'normal' ? `-${ flavor } ` : '' ;
471499 clean_cache ( ) . then ( function ( ) {
@@ -528,7 +556,7 @@ function injectARMCache(flavor, callback) {
528556 clean_debug ( ) ;
529557 process . exit ( 1 ) ;
530558 }
531- callback ( ) ;
559+ done ( ) ;
532560 }
533561 ) ;
534562 }
@@ -592,10 +620,10 @@ function buildNWApps(platforms, flavor, dir, done) {
592620
593621function getGitRevision ( done , callback , isReleaseBuild ) {
594622 let gitRevision = 'norevision' ;
595- git . diff ( [ '--shortstat' ] , function ( err , diff ) {
596- if ( ! err && ! diff ) {
597- git . log ( [ '-1' , '--pretty=format:%h' ] , function ( err , rev ) {
598- if ( ! err ) {
623+ git . diff ( [ '--shortstat' ] , function ( err1 , diff ) {
624+ if ( ! err1 && ! diff ) {
625+ git . log ( [ '-1' , '--pretty=format:%h' ] , function ( err2 , rev ) {
626+ if ( ! err2 ) {
599627 gitRevision = rev . latest . hash ;
600628 }
601629
@@ -608,7 +636,6 @@ function getGitRevision(done, callback, isReleaseBuild) {
608636}
609637
610638function start_debug ( done ) {
611-
612639 const platforms = getPlatforms ( ) ;
613640
614641 if ( platforms . length === 1 ) {
@@ -813,7 +840,7 @@ function createDirIfNotExists(dir) {
813840}
814841
815842// Create a list of the gulp tasks to execute for release
816- function listReleaseTasks ( appDirectory ) {
843+ function listReleaseTasks ( isReleaseBuild , appDirectory ) {
817844
818845 const platforms = getPlatforms ( ) ;
819846
@@ -869,7 +896,11 @@ function listReleaseTasks(appDirectory) {
869896
870897 if ( platforms . indexOf ( 'android' ) !== - 1 ) {
871898 releaseTasks . push ( function release_android ( ) {
872- return cordova_release ( ) ;
899+ if ( isReleaseBuild ) {
900+ return cordova_release ( ) ;
901+ } else {
902+ return cordova_debug_release ( ) ;
903+ }
873904 } ) ;
874905 }
875906
@@ -891,6 +922,7 @@ function cordova_dist() {
891922 distTasks . push ( cordova_packagejson ) ;
892923 distTasks . push ( cordova_manifestjson ) ;
893924 distTasks . push ( cordova_configxml ) ;
925+ distTasks . push ( cordova_rename_build_json ) ;
894926 distTasks . push ( cordova_browserify ) ;
895927 distTasks . push ( cordova_depedencies ) ;
896928 if ( cordovaDependencies ) {
@@ -903,11 +935,16 @@ function cordova_dist() {
903935 }
904936 return distTasks ;
905937}
906- function cordova_apps ( ) {
938+
939+ function cordova_apps ( isReleaseBuild ) {
907940 const appsTasks = [ ] ;
908941 const platforms = getPlatforms ( ) ;
909942 if ( platforms . indexOf ( 'android' ) !== - 1 ) {
910- appsTasks . push ( cordova_build ) ;
943+ if ( isReleaseBuild ) {
944+ appsTasks . push ( cordova_build ) ;
945+ } else {
946+ appsTasks . push ( cordova_debug_build ) ;
947+ }
911948 } else {
912949 appsTasks . push ( function cordova_dist_none ( done ) {
913950 done ( ) ;
@@ -933,7 +970,6 @@ function cordova_copy_www() {
933970}
934971
935972function cordova_resources ( ) {
936-
937973 return gulp . src ( 'assets/android/**' )
938974 . pipe ( gulp . dest ( `${ CORDOVA_DIST_DIR } resources/android/` ) ) ;
939975}
@@ -947,7 +983,7 @@ function cordova_include_www() {
947983}
948984
949985function cordova_copy_src ( ) {
950- return gulp . src ( [ `${ CORDOVA_DIR } **` , `!${ CORDOVA_DIR } config_template.xml` , `!${ CORDOVA_DIR } package_template.json` ] )
986+ return gulp . src ( [ `${ CORDOVA_DIR } **` , `!${ CORDOVA_DIR } config_template.xml` , `!${ CORDOVA_DIR } package_template.json` , `! ${ CORDOVA_DIR } build_template.json` ] )
951987 . pipe ( gulp . dest ( `${ CORDOVA_DIST_DIR } ` ) ) ;
952988}
953989
@@ -972,6 +1008,8 @@ function cordova_packagejson() {
9721008 'author' : metadata . author ,
9731009 'license' : metadata . license ,
9741010 } ) )
1011+ . pipe ( gulp . dest ( CORDOVA_DIST_DIR ) )
1012+ . pipe ( rename ( 'manifest.json' ) )
9751013 . pipe ( gulp . dest ( CORDOVA_DIST_DIR ) ) ;
9761014}
9771015
@@ -984,7 +1022,7 @@ function cordova_manifestjson() {
9841022}
9851023
9861024function cordova_configxml ( ) {
987- let androidName = metadata . packageId . replace ( NAME_REGEX , '_' ) ;
1025+ const androidName = metadata . packageId . replace ( NAME_REGEX , '_' ) ;
9881026
9891027 return gulp . src ( [ `${ CORDOVA_DIST_DIR } config.xml` ] )
9901028 . pipe ( xmlTransformer ( [
@@ -994,12 +1032,18 @@ function cordova_configxml() {
9941032 ] , 'http://www.w3.org/ns/widgets' ) )
9951033 . pipe ( xmlTransformer ( [
9961034 { path : '.' , attr : { 'id' : `com.betaflight.${ androidName } ` } } ,
997- { path : '.' , attr : { 'version' : metadata . version } } ,
1035+ { path : '.' , attr : { 'version' : metadata . storeVersion ? metadata . storeVersion : metadata . version } } ,
9981036 ] ) )
9991037 . pipe ( gulp . dest ( CORDOVA_DIST_DIR ) ) ;
10001038}
10011039
1002- function cordova_browserify ( callback ) {
1040+ function cordova_rename_build_json ( ) {
1041+ return gulp . src ( `${ CORDOVA_DIR } build_template.json` )
1042+ . pipe ( rename ( 'build.json' ) )
1043+ . pipe ( gulp . dest ( CORDOVA_DIST_DIR ) ) ;
1044+ }
1045+
1046+ function cordova_browserify ( done ) {
10031047 const readFile = function ( file ) {
10041048 return new Promise ( function ( resolve ) {
10051049 if ( ! file . includes ( "node_modules" ) ) {
@@ -1017,7 +1061,7 @@ function cordova_browserify(callback) {
10171061 glob ( `${ CORDOVA_DIST_DIR } www/**/*.js` , { } , function ( err , files ) {
10181062 const readLoop = function ( ) {
10191063 if ( files . length === 0 ) {
1020- callback ( ) ;
1064+ done ( ) ;
10211065 } else {
10221066 const file = files . pop ( ) ;
10231067 readFile ( file ) . then ( function ( ) {
@@ -1056,24 +1100,77 @@ function cordova_debug() {
10561100 cordova . run ( ) ;
10571101}
10581102
1059- function cordova_build ( cb ) {
1103+ function cordova_debug_build ( done ) {
10601104 cordova . build ( {
10611105 'platforms' : [ 'android' ] ,
10621106 'options' : {
1063- release : true ,
1107+ release : false ,
10641108 buildConfig : 'build.json' ,
10651109 } ,
10661110 } ) . then ( function ( ) {
10671111 process . chdir ( '../' ) ;
1068- cb ( ) ;
1112+
1113+ console . log ( `APK has been generated at ${ CORDOVA_DIST_DIR } platforms/android/app/build/outputs/apk/release/app-release.apk` ) ;
1114+
1115+ done ( ) ;
10691116 } ) ;
1070- console . log ( `APK will be generated at ${ CORDOVA_DIST_DIR } platforms/android/app/build/outputs/apk/release/app-release.apk` ) ;
10711117}
10721118
1073- async function cordova_release ( ) {
1074- const filename = await getReleaseFilename ( 'android' , 'apk' ) ;
1119+ function cordova_build ( done ) {
1120+ let storePassword = '' ;
1121+ return gulp . series ( function password_prompt ( ) {
1122+ return gulp . src ( '.' )
1123+ . pipe ( prompt . prompt ( {
1124+ type : 'password' ,
1125+ name : 'storePassword' ,
1126+ message : 'Please enter the keystore password:' ,
1127+ } , function ( res ) {
1128+ storePassword = res . storePassword ;
1129+ } ) ) ;
1130+ } , function set_password ( ) {
1131+ return gulp . src ( `build.json` )
1132+ . pipe ( jeditor ( {
1133+ 'android' : {
1134+ 'release' : {
1135+ 'storePassword' : storePassword ,
1136+ } ,
1137+ } ,
1138+ } ) )
1139+ . pipe ( gulp . dest ( './' ) ) ;
1140+ } , function build ( done2 ) {
1141+ return cordova . build ( {
1142+ 'platforms' : [ 'android' ] ,
1143+ 'options' : {
1144+ release : true ,
1145+ buildConfig : 'build.json' ,
1146+ } ,
1147+ } ) . then ( function ( ) {
1148+ // Delete the file containing the store password
1149+ del ( [ 'build.json' ] , { force : true } ) ;
1150+ process . chdir ( '../' ) ;
1151+
1152+ console . log ( 'AAB has been generated at dist_cordova/platforms/android/app/build/outputs/bundle/release/app.aab' ) ;
1153+ done2 ( ) ;
1154+ } ) ;
1155+ } ) ( done ) ;
1156+ }
1157+
1158+ async function cordova_debug_release ( ) {
1159+ const filename = getReleaseFilename ( 'android' , 'apk' ) ;
1160+
10751161 console . log ( `Release APK : release/${ filename } ` ) ;
1076- return gulp . src ( `${ CORDOVA_DIST_DIR } platforms/android/app/build/outputs/apk/release/app-release.apk` )
1162+
1163+ return gulp . src ( `${ CORDOVA_DIST_DIR } platforms/android/app/build/outputs/apk/debug/app-debug.apk` )
1164+ . pipe ( rename ( filename ) )
1165+ . pipe ( gulp . dest ( RELEASE_DIR ) ) ;
1166+ }
1167+
1168+ async function cordova_release ( ) {
1169+ const filename = getReleaseFilename ( 'android' , 'aab' ) ;
1170+
1171+ console . log ( `Release AAB : release/${ filename } ` ) ;
1172+
1173+ return gulp . src ( `${ CORDOVA_DIST_DIR } platforms/android/app/build/outputs/bundle/release/app.aab` )
10771174 . pipe ( rename ( filename ) )
10781175 . pipe ( gulp . dest ( RELEASE_DIR ) ) ;
10791176}
0 commit comments