You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by no...@apache.org on 2020/04/16 12:39:35 UTC

[cordova-android] branch master updated: Feature: JVM Args flag (#948)

This is an automated email from the ASF dual-hosted git repository.

normanbreau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-android.git


The following commit(s) were added to refs/heads/master by this push:
     new 4d0d60c  Feature: JVM Args flag (#948)
4d0d60c is described below

commit 4d0d60c294ddb377400cc9846f3ed9754153fa35
Author: Norman Breau <no...@normanbreau.com>
AuthorDate: Thu Apr 16 09:39:22 2020 -0300

    Feature: JVM Args flag (#948)
    
    * feat: JVM args flag
    
    * test: JVM args flag
    
    * feat: Do not display recommended memory warning unless if memory is less than cordova default
---
 bin/templates/cordova/Api.js                       |  3 +-
 .../cordova/lib/config/GradlePropertiesParser.js   | 39 ++++++++++-
 bin/templates/cordova/lib/prepare.js               | 14 ++++
 spec/unit/config/GradlePropertiesParser.spec.js    | 60 ++++++++++++++++
 spec/unit/prepare.spec.js                          | 81 ++++++++++++++++++++++
 5 files changed, 194 insertions(+), 3 deletions(-)

diff --git a/bin/templates/cordova/Api.js b/bin/templates/cordova/Api.js
index 3d80ddc..6de476a 100644
--- a/bin/templates/cordova/Api.js
+++ b/bin/templates/cordova/Api.js
@@ -34,6 +34,7 @@ var PluginManager = require('cordova-common').PluginManager;
 var CordovaLogger = require('cordova-common').CordovaLogger;
 var selfEvents = require('cordova-common').events;
 var ConfigParser = require('cordova-common').ConfigParser;
+const prepare = require('./lib/prepare').prepare;
 
 var PLATFORM = 'android';
 
@@ -120,7 +121,7 @@ class Api {
     prepare (cordovaProject, prepareOptions) {
         cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
 
-        return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
+        return prepare.call(this, cordovaProject, prepareOptions);
     }
 
     /**
diff --git a/bin/templates/cordova/lib/config/GradlePropertiesParser.js b/bin/templates/cordova/lib/config/GradlePropertiesParser.js
index 14302d3..2c8aaa8 100644
--- a/bin/templates/cordova/lib/config/GradlePropertiesParser.js
+++ b/bin/templates/cordova/lib/config/GradlePropertiesParser.js
@@ -90,8 +90,15 @@ class GradlePropertiesParser {
                 this.gradleFile.set(key, properties[key]);
             } else if (value !== properties[key]) {
                 if (this._defaults[key] && this._defaults[key] !== properties[key]) {
-                    // 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]}"`);
+                    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]}"`);
+                    }
                 } 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]}"`);
@@ -103,6 +110,34 @@ class GradlePropertiesParser {
         });
     }
 
+    _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;
+    }
+
     /**
      * Saves any changes that has been made to the properties file.
      */
diff --git a/bin/templates/cordova/lib/prepare.js b/bin/templates/cordova/lib/prepare.js
index 7ed4704..098cab8 100644
--- a/bin/templates/cordova/lib/prepare.js
+++ b/bin/templates/cordova/lib/prepare.js
@@ -19,6 +19,7 @@
 
 var fs = require('fs-extra');
 var path = require('path');
+const nopt = require('nopt');
 var events = require('cordova-common').events;
 var AndroidManifest = require('./AndroidManifest');
 var checkReqs = require('./check_reqs');
@@ -33,9 +34,21 @@ const utils = require('./utils');
 
 const GradlePropertiesParser = require('./config/GradlePropertiesParser');
 
+function parseArguments (argv) {
+    return nopt({
+        // `jvmargs` is a valid option however, we don't actually want to parse it because we want the entire string as is.
+        // jvmargs: String
+    }, {}, argv || [], 0);
+}
+
 module.exports.prepare = function (cordovaProject, options) {
     var self = this;
 
+    let args = {};
+    if (options && options.options) {
+        args = parseArguments(options.options.argv);
+    }
+
     var platformJson = PlatformJson.load(this.locations.root, this.platform);
     var munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider());
 
@@ -53,6 +66,7 @@ module.exports.prepare = function (cordovaProject, options) {
     if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
     if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
     if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
+    if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
     if (isGradlePluginKotlinEnabled) {
         gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
     }
diff --git a/spec/unit/config/GradlePropertiesParser.spec.js b/spec/unit/config/GradlePropertiesParser.spec.js
index 4c05da2..3dcc1ff 100644
--- a/spec/unit/config/GradlePropertiesParser.spec.js
+++ b/spec/unit/config/GradlePropertiesParser.spec.js
@@ -180,4 +180,64 @@ describe('Gradle Builder', () => {
             expect(emitSpy.calls.argsFor(0)[1]).toContain('Updating and Saving File');
         });
     });
+
+    describe('JVM Settings detection', () => {
+        const parser = new GradlePropertiesParser('/root');
+
+        describe('_getBaseJVMSize', () => {
+            it('1024k = 1048576', () => {
+                expect(parser._getBaseJVMSize(1024, 'k')).toBe(1048576);
+                expect(parser._getBaseJVMSize(1024, 'K')).toBe(1048576);
+            });
+
+            it('1024m = 1073741824', () => {
+                expect(parser._getBaseJVMSize(1024, 'm')).toBe(1073741824);
+                expect(parser._getBaseJVMSize(1024, 'M')).toBe(1073741824);
+            });
+
+            it('2g = 2097152', () => {
+                expect(parser._getBaseJVMSize(2, 'g')).toBe(2147483648);
+                expect(parser._getBaseJVMSize(2, 'G')).toBe(2147483648);
+            });
+
+            it('unknown units should warn', () => {
+                const emitSpy = jasmine.createSpy('emit');
+                GradlePropertiesParser.__set__('events', {
+                    emit: emitSpy
+                });
+
+                parser._getBaseJVMSize(1024, 'bad unit');
+                expect(emitSpy.calls.argsFor(0)[1]).toContain('Unknown memory size unit');
+            });
+        });
+
+        describe('JVM recommended tests', () => {
+            const recommended = '-Xmx2048m';
+
+            const tests = {
+                // kb
+                '1024k': true,
+                '2097152k': false,
+                '2097151k': true,
+                '2097153k': false,
+
+                // mb
+                '1024m': true,
+                '2048m': false,
+                '2047m': true,
+                '2049m': false,
+
+                // gb
+                '1g': true,
+                '3g': false,
+                '2g': false
+            };
+
+            for (const i in tests) {
+                it(i + ' should return ' + tests[i], () => {
+                    expect(parser._isJVMMemoryLessThanRecommended('-Xmx' + i, recommended)).toBe(tests[i]);
+                });
+            }
+        });
+    });
 });
diff --git a/spec/unit/prepare.spec.js b/spec/unit/prepare.spec.js
index da6fcca..e10c319 100644
--- a/spec/unit/prepare.spec.js
+++ b/spec/unit/prepare.spec.js
@@ -20,6 +20,7 @@
 var rewire = require('rewire');
 var path = require('path');
 var CordovaError = require('cordova-common').CordovaError;
+const GradlePropertiesParser = require('../../bin/templates/cordova/lib/config/GradlePropertiesParser');
 
 const PATH_RESOURCE = path.join('platforms', 'android', 'app', 'src', 'main', 'res');
 
@@ -751,3 +752,83 @@ describe('cleanIcons method', function () {
         expect(actualResourceMap).toEqual(expectedResourceMap);
     });
 });
+
+describe('prepare arguments', () => {
+    // Rewire
+    let Api;
+    let api;
+    let prepare;
+
+    // Spies
+    let gradlePropertiesParserSpy;
+
+    // Mock Data
+    let cordovaProject;
+    let options;
+
+    beforeEach(function () {
+        Api = rewire('../../bin/templates/cordova/Api');
+        prepare = rewire('../../bin/templates/cordova/lib/prepare');
+
+        cordovaProject = {
+            root: '/mock',
+            projectConfig: {
+                path: '/mock/config.xml',
+                cdvNamespacePrefix: 'cdv'
+            },
+            locations: {
+                plugins: '/mock/plugins',
+                www: '/mock/www'
+            }
+        };
+
+        options = {
+            options: {}
+        };
+
+        Api.__set__('ConfigParser',
+            jasmine.createSpy('ConfigParser')
+                .and.returnValue(cordovaProject.projectConfig)
+        );
+
+        Api.__set__('prepare', prepare.prepare);
+
+        prepare.__set__('events', {
+            emit: jasmine.createSpy('emit')
+        });
+        prepare.__set__('updateWww', jasmine.createSpy());
+        prepare.__set__('updateProjectAccordingTo', jasmine.createSpy('updateProjectAccordingTo')
+            .and.returnValue(Promise.resolve()));
+        prepare.__set__('updateIcons', jasmine.createSpy('updateIcons').and.returnValue(Promise.resolve()));
+        prepare.__set__('updateSplashes', jasmine.createSpy('updateSplashes').and.returnValue(Promise.resolve()));
+        prepare.__set__('updateFileResources', jasmine.createSpy('updateFileResources').and.returnValue(Promise.resolve()));
+        prepare.__set__('updateConfigFilesFrom',
+            jasmine.createSpy('updateConfigFilesFrom')
+                .and.returnValue({
+                    getPreference: jasmine.createSpy('getPreference')
+                }));
+
+        gradlePropertiesParserSpy = spyOn(GradlePropertiesParser.prototype, 'configure');
+
+        api = new Api();
+    });
+
+    it('runs without arguments', () => {
+        expectAsync(
+            api.prepare(cordovaProject, options).then(() => {
+                expect(gradlePropertiesParserSpy).toHaveBeenCalledWith({});
+            })
+        ).toBeResolved();
+    });
+
+    it('runs with jvmargs', () => {
+        options.options.argv = ['--jvmargs=-Xmx=4096m'];
+        expectAsync(
+            api.prepare(cordovaProject, options).then(() => {
+                expect(gradlePropertiesParserSpy).toHaveBeenCalledWith({
+                    'org.gradle.jvmargs': '-Xmx=4096m'
+                });
+            })
+        ).toBeResolved();
+    });
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org