2018-07-11 11:14:04 +08:00
/ * *
Licensed to the Apache Software Foundation ( ASF ) under one
or more contributor license agreements . See the NOTICE file
distributed with this work for additional information
regarding copyright ownership . The ASF licenses this file
to you under the Apache License , Version 2.0 ( the
"License" ) ; you may not use this file except in compliance
with the License . You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing ,
software distributed under the License is distributed on an
"AS IS" BASIS , WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND , either express or implied . See the License for the
specific language governing permissions and limitations
under the License .
* /
2020-01-31 21:02:48 +08:00
const fs = require ( 'fs' ) ;
const path = require ( 'path' ) ;
const propertiesParser = require ( 'properties-parser' ) ;
const events = require ( 'cordova-common' ) . events ;
2018-07-11 11:14:04 +08:00
class GradlePropertiesParser {
/ * *
* Loads and Edits Gradle Properties File .
*
* @ param { String } platformDir is the path of the Android platform directory
* /
constructor ( platformDir ) {
this . _defaults = {
// 10 seconds -> 6 seconds
'org.gradle.daemon' : 'true' ,
// to allow dex in process
2020-01-27 14:52:08 +08:00
'org.gradle.jvmargs' : '-Xmx2048m' ,
// Android X
2021-04-16 05:52:14 +08:00
'android.useAndroidX' : 'true' ,
'android.enableJetifier' : 'true'
2018-07-11 11:14:04 +08:00
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
// 'org.gradle.parallel': 'true'
} ;
this . gradleFilePath = path . join ( platformDir , 'gradle.properties' ) ;
}
2019-02-13 09:11:32 +08:00
configure ( userConfigs ) {
2018-07-11 11:14:04 +08:00
events . emit ( 'verbose' , '[Gradle Properties] Preparing Configuration' ) ;
this . _initializeEditor ( ) ;
2019-02-13 09:11:32 +08:00
events . emit ( 'verbose' , '[Gradle Properties] Appending default configuration properties' ) ;
this . _configureProperties ( this . _defaults ) ;
events . emit ( 'verbose' , '[Gradle Properties] Appending custom configuration properties' ) ;
this . _configureProperties ( userConfigs ) ;
2018-07-11 11:14:04 +08:00
this . _save ( ) ;
}
/ * *
* Initialize the properties editor for parsing , setting , etc .
* /
_initializeEditor ( ) {
// Touch empty gradle.properties file if missing.
if ( ! fs . existsSync ( this . gradleFilePath ) ) {
events . emit ( 'verbose' , '[Gradle Properties] File missing, creating file with Cordova defaults.' ) ;
fs . writeFileSync ( this . gradleFilePath , '' , 'utf-8' ) ;
}
// Create an editor for parsing, getting, and setting configurations.
this . gradleFile = propertiesParser . createEditor ( this . gradleFilePath ) ;
}
/ * *
2019-02-13 09:11:32 +08:00
* Validate that defaults or user configuration properties are set and
* set the missing items .
2018-07-11 11:14:04 +08:00
* /
2019-02-13 09:11:32 +08:00
_configureProperties ( properties ) {
// Iterate though the properties and set only if missing.
Object . keys ( properties ) . forEach ( key => {
2020-01-31 21:02:48 +08:00
const value = this . gradleFile . get ( key ) ;
2018-07-11 11:14:04 +08:00
if ( ! value ) {
2019-04-06 12:28:25 +08:00
// Handles the case of adding missing defaults or new properties that are missing.
2019-02-13 09:11:32 +08:00
events . emit ( 'verbose' , ` [Gradle Properties] Appending configuration item: ${ key } = ${ properties [ key ] } ` ) ;
this . gradleFile . set ( key , properties [ key ] ) ;
} else if ( value !== properties [ key ] ) {
2019-04-06 12:28:25 +08:00
if ( this . _defaults [ key ] && this . _defaults [ key ] !== properties [ key ] ) {
2020-04-16 20:39:22 +08:00
let shouldEmit = true ;
if ( key === 'org.gradle.jvmargs' ) {
shouldEmit = this . _isJVMMemoryLessThanRecommended ( properties [ key ] , this . _defaults [ key ] ) ;
}
if ( shouldEmit ) {
// Since the value does not match default, we will notify the discrepancy with Cordova's recommended value.
events . emit ( 'info' , ` [Gradle Properties] Detected Gradle property " ${ key } " with the value of " ${ properties [ key ] } ", Cordova's recommended value is " ${ this . _defaults [ key ] } " ` ) ;
}
2019-04-06 12:28:25 +08:00
} else {
// When the current value exists but does not match the new value or does matches the default key value, the new value it set.
events . emit ( 'verbose' , ` [Gradle Properties] Updating Gradle property " ${ key } " with the value of " ${ properties [ key ] } " ` ) ;
}
// We will set the new value in either case.
this . gradleFile . set ( key , properties [ key ] ) ;
2018-07-11 11:14:04 +08:00
}
} ) ;
}
2020-04-16 20:39:22 +08:00
_isJVMMemoryLessThanRecommended ( memoryValue , recommendedMemoryValue ) {
const UNIT = 2 ;
const SIZE = 1 ;
const regex = /-Xmx+([0-9]+)+([mMgGkK])/ ;
const recommendedCapture = regex . exec ( recommendedMemoryValue ) ;
const recommendedBase = this . _getBaseJVMSize ( recommendedCapture [ SIZE ] , recommendedCapture [ UNIT ] ) ;
const memoryCapture = regex . exec ( memoryValue ) ;
const memoryBase = this . _getBaseJVMSize ( memoryCapture [ SIZE ] , memoryCapture [ UNIT ] ) ;
return memoryBase < recommendedBase ;
}
_getBaseJVMSize ( size , unit ) {
const KILOBYTE = 1024 ;
const MEGABYTE = 1048576 ;
const GIGABYTE = 1073741824 ;
switch ( unit . toLowerCase ( ) ) {
case 'k' : return size * KILOBYTE ;
case 'm' : return size * MEGABYTE ;
case 'g' : return size * GIGABYTE ;
}
events . emit ( 'warn' , ` [Gradle Properties] Unknown memory size unit ( ${ unit } ) ` ) ;
return null ;
}
2018-07-11 11:14:04 +08:00
/ * *
* Saves any changes that has been made to the properties file .
* /
_save ( ) {
events . emit ( 'verbose' , '[Gradle Properties] Updating and Saving File' ) ;
this . gradleFile . save ( ) ;
}
}
module . exports = GradlePropertiesParser ;