mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-07 23:03:11 +08:00
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
This commit is contained in:
parent
16a88ec631
commit
4d0d60c294
3
bin/templates/cordova/Api.js
vendored
3
bin/templates/cordova/Api.js
vendored
@ -34,6 +34,7 @@ var PluginManager = require('cordova-common').PluginManager;
|
|||||||
var CordovaLogger = require('cordova-common').CordovaLogger;
|
var CordovaLogger = require('cordova-common').CordovaLogger;
|
||||||
var selfEvents = require('cordova-common').events;
|
var selfEvents = require('cordova-common').events;
|
||||||
var ConfigParser = require('cordova-common').ConfigParser;
|
var ConfigParser = require('cordova-common').ConfigParser;
|
||||||
|
const prepare = require('./lib/prepare').prepare;
|
||||||
|
|
||||||
var PLATFORM = 'android';
|
var PLATFORM = 'android';
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ class Api {
|
|||||||
prepare (cordovaProject, prepareOptions) {
|
prepare (cordovaProject, prepareOptions) {
|
||||||
cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,8 +90,15 @@ class GradlePropertiesParser {
|
|||||||
this.gradleFile.set(key, properties[key]);
|
this.gradleFile.set(key, properties[key]);
|
||||||
} else if (value !== properties[key]) {
|
} else if (value !== properties[key]) {
|
||||||
if (this._defaults[key] && this._defaults[key] !== 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.
|
let shouldEmit = true;
|
||||||
events.emit('info', `[Gradle Properties] Detected Gradle property "${key}" with the value of "${properties[key]}", Cordova's recommended value is "${this._defaults[key]}"`);
|
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 {
|
} 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.
|
// 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]}"`);
|
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.
|
* Saves any changes that has been made to the properties file.
|
||||||
*/
|
*/
|
||||||
|
14
bin/templates/cordova/lib/prepare.js
vendored
14
bin/templates/cordova/lib/prepare.js
vendored
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
var fs = require('fs-extra');
|
var fs = require('fs-extra');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
const nopt = require('nopt');
|
||||||
var events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
var AndroidManifest = require('./AndroidManifest');
|
||||||
var checkReqs = require('./check_reqs');
|
var checkReqs = require('./check_reqs');
|
||||||
@ -33,9 +34,21 @@ const utils = require('./utils');
|
|||||||
|
|
||||||
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
|
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) {
|
module.exports.prepare = function (cordovaProject, options) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
let args = {};
|
||||||
|
if (options && options.options) {
|
||||||
|
args = parseArguments(options.options.argv);
|
||||||
|
}
|
||||||
|
|
||||||
var platformJson = PlatformJson.load(this.locations.root, this.platform);
|
var platformJson = PlatformJson.load(this.locations.root, this.platform);
|
||||||
var munger = new PlatformMunger(this.platform, this.locations.root, platformJson, new PluginInfoProvider());
|
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 (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
|
||||||
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
|
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
|
||||||
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
|
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
|
||||||
|
if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
|
||||||
if (isGradlePluginKotlinEnabled) {
|
if (isGradlePluginKotlinEnabled) {
|
||||||
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
|
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
|
||||||
}
|
}
|
||||||
|
@ -180,4 +180,64 @@ describe('Gradle Builder', () => {
|
|||||||
expect(emitSpy.calls.argsFor(0)[1]).toContain('Updating and Saving File');
|
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]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
var rewire = require('rewire');
|
var rewire = require('rewire');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
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');
|
const PATH_RESOURCE = path.join('platforms', 'android', 'app', 'src', 'main', 'res');
|
||||||
|
|
||||||
@ -751,3 +752,83 @@ describe('cleanIcons method', function () {
|
|||||||
expect(actualResourceMap).toEqual(expectedResourceMap);
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user