You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by dp...@apache.org on 2018/09/11 17:07:34 UTC
[cordova-common] branch master updated: CB-14108: fix incorrect
count in config_munge in ios.json and android.json
This is an automated email from the ASF dual-hosted git repository.
dpogue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-common.git
The following commit(s) were added to refs/heads/master by this push:
new ce3801a CB-14108: fix incorrect count in config_munge in ios.json and android.json
ce3801a is described below
commit ce3801a184d34cc4c3ea08aeecd159227c6ae9e9
Author: Ken Naito <fi...@gmail.com>
AuthorDate: Wed Sep 12 02:07:32 2018 +0900
CB-14108: fix incorrect count in config_munge in ios.json and android.json
* Fix to cordova prepare increment count at config_munge in platformJson
* Fix to cordova prepare when remove config-file case
---
spec/ConfigChanges/ConfigChanges.spec.js | 88 ++++++++++++++++
spec/CordovaError/CordovaError.spec.js | 41 ++++++++
spec/fixtures/test-configfile0.xml | 14 +++
spec/fixtures/test-configfile1.xml | 29 ++++++
spec/fixtures/test-configfile2.xml | 34 +++++++
src/ConfigChanges/ConfigChanges.js | 169 +++++++++++++++++++++++--------
src/ConfigChanges/ConfigFile.js | 6 +-
src/ConfigChanges/munge-util.js | 23 +++++
src/ConfigParser/ConfigParser.js | 3 +-
9 files changed, 365 insertions(+), 42 deletions(-)
diff --git a/spec/ConfigChanges/ConfigChanges.spec.js b/spec/ConfigChanges/ConfigChanges.spec.js
index fe83c70..7f792d2 100644
--- a/spec/ConfigChanges/ConfigChanges.spec.js
+++ b/spec/ConfigChanges/ConfigChanges.spec.js
@@ -46,6 +46,9 @@ var ConfigParser = require('../../src/ConfigParser/ConfigParser');
var xml = path.join(__dirname, '../fixtures/test-config.xml');
var editconfig_xml = path.join(__dirname, '../fixtures/test-editconfig.xml');
var configfile_xml = path.join(__dirname, '../fixtures/test-configfile.xml');
+var configfile0_xml = path.join(__dirname, '../fixtures/test-configfile0.xml');
+var configfile1_xml = path.join(__dirname, '../fixtures/test-configfile1.xml');
+var configfile2_xml = path.join(__dirname, '../fixtures/test-configfile2.xml');
var cfg = new ConfigParser(xml);
// TODO: dont do fs so much
@@ -385,6 +388,32 @@ describe('config-changes module', function () {
expect(sdk.attrib['android:minSdkVersion']).toEqual('5');
expect(sdk.attrib['android:maxSdkVersion']).toBeUndefined();
});
+ it('should recover AndroidManifest after removing editconfig', function () {
+ var editconfig_cfg = new ConfigParser(editconfig_xml);
+ var platformJson = PlatformJson.load(plugins_dir, 'android');
+ var munger = new configChanges.PlatformMunger('android', temp, platformJson, pluginInfoProvider);
+
+ // once add editconfig
+ munger.add_config_changes(cfg, true).save_all();
+ munger.add_config_changes(editconfig_cfg, true).save_all();
+
+ var am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ var sdk = am_xml.find('./uses-sdk');
+ expect(sdk).toBeDefined();
+ expect(sdk.attrib['android:targetSdkVersion']).toEqual('23');
+ expect(sdk.attrib['android:minSdkVersion']).toEqual('5');
+ expect(sdk.attrib['android:maxSdkVersion']).toBeUndefined();
+
+ // should recover
+ munger.add_config_changes(cfg, true).save_all();
+ am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ sdk = am_xml.find('./uses-sdk');
+ expect(sdk).toBeDefined();
+ expect(sdk.attrib['android:targetSdkVersion']).toEqual('24');
+ expect(sdk.attrib['android:minSdkVersion']).toEqual('14');
+ expect(sdk.attrib['android:maxSdkVersion']).toBeUndefined();
+
+ });
it('should append new children to XML document tree', function () {
var configfile_cfg = new ConfigParser(configfile_xml);
var platformJson = PlatformJson.load(plugins_dir, 'android');
@@ -404,6 +433,47 @@ describe('config-changes module', function () {
var am_file = fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8');
expect(am_file.indexOf('android:name="zoo"')).toBeLessThan(am_file.indexOf('android:name="com.foo.Bar"'));
});
+ // testing removing <config-file> tag in config.xml
+ it('should recover AndroidManifest after removing config-file tag', function () {
+ // add config-file same as previous
+ var configfile_cfg = new ConfigParser(configfile_xml);
+ var platformJson = PlatformJson.load(plugins_dir, 'android');
+ var munger = new configChanges.PlatformMunger('android', temp, platformJson, pluginInfoProvider);
+ munger.add_config_changes(configfile_cfg, true).save_all();
+ var am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ var activity = am_xml.find('./application/activity[@android:name="com.foo.Bar"]');
+ expect(activity).not.toBeNull();
+ // add removing config-file
+ var configfile0_cfg = new ConfigParser(configfile0_xml); // removing config-file tag
+ munger.add_config_changes(configfile0_cfg, true).save_all();
+ am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ activity = am_xml.find('./application/activity[@android:name="com.foo.Bar"]');
+ expect(activity).toBeNull();
+ });
+ it('should recover AndroidManifest if one of permission tags is removed', function () {
+ fs.copySync(android_two_no_perms_project, temp);
+ var configfile2_cfg = new ConfigParser(configfile2_xml);
+ var platformJson = PlatformJson.load(plugins_dir, 'android');
+ var munger = new configChanges.PlatformMunger('android', temp, platformJson, pluginInfoProvider);
+ munger.add_config_changes(configfile2_cfg, true).save_all();
+ var am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ var permission_vibrate = am_xml.find('./uses-permission[@android:name="android.permission.VIBRATE"]');
+ var permission_write = am_xml.find('./uses-permission[@android:name="android.permission.WRITE_EXTERNAL_STORAGE"]');
+ var permission_contacts = am_xml.find('./uses-permission[@android:name="android.permission.READ_CONTACTS"]');
+ expect(permission_vibrate).not.toBeNull();
+ expect(permission_write).not.toBeNull();
+ expect(permission_contacts).toBeNull();
+ // add removing of of permission tag
+ var configfile1_cfg = new ConfigParser(configfile1_xml); // removing one of permission tag
+ munger.add_config_changes(configfile1_cfg, true).save_all();
+ am_xml = new et.ElementTree(et.XML(fs.readFileSync(path.join(temp, 'AndroidManifest.xml'), 'utf-8')));
+ permission_vibrate = am_xml.find('./uses-permission[@android:name="android.permission.VIBRATE"]');
+ permission_write = am_xml.find('./uses-permission[@android:name="android.permission.WRITE_EXTERNAL_STORAGE"]');
+ permission_contacts = am_xml.find('./uses-permission[@android:name="android.permission.READ_CONTACTS"]');
+ expect(permission_vibrate).not.toBeNull();
+ expect(permission_write).toBeNull();
+ expect(permission_contacts).toBeNull();
+ });
it('should throw error for conflicting plugin config munge with config.xml config munge', function () {
install_plugin(editconfigplugin_two);
@@ -437,6 +507,24 @@ describe('config-changes module', function () {
expect(fs.readFileSync(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'), 'utf-8')).toMatch(/<string>schema-b<\/string>/);
expect(fs.readFileSync(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'), 'utf-8')).not.toMatch(/(<string>schema-a<\/string>[^]*){2,}/);
});
+ it('should recover Info.plist after removing config-file tag', function () {
+ fs.copySync(ios_config_xml, temp);
+ var configfile2_cfg = new ConfigParser(configfile2_xml);
+ var platformJson = PlatformJson.load(plugins_dir, 'ios');
+ var munger = new configChanges.PlatformMunger('ios', temp, platformJson, pluginInfoProvider);
+ munger.add_config_changes(configfile2_cfg, true).save_all();
+ var info_plist = fs.readFileSync(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'), 'utf-8');
+ expect(info_plist).toMatch(/<key>NSCameraUsageDescription<\/key>\s*<string>Please permit Camera<\/string>/);
+ expect(info_plist).toMatch(/<key>NSPhotoLibraryUsageDescription<\/key>\s*<string>Please permit PhotoLibrary<\/string>/);
+ expect(info_plist).toMatch(/<key>LSApplicationQueriesSchemes<\/key>\s*<array>\s*<string>twitter<\/string>\s*<string>fb<\/string>\s*<\/array>/);
+ var configfile1_cfg = new ConfigParser(configfile1_xml);
+ munger.add_config_changes(configfile1_cfg, true).save_all();
+ info_plist = fs.readFileSync(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'), 'utf-8');
+ expect(info_plist).toMatch(/<key>NSCameraUsageDescription<\/key>\s*<string>This app uses Camera<\/string>/);
+ expect(info_plist).not.toMatch(/<key>NSPhotoLibraryUsageDescription<\/key>\s*<string>Please permit PhotoLibrary<\/string>/);
+ expect(info_plist).not.toMatch(/<key>LSApplicationQueriesSchemes<\/key>\s*<array>\s*<string>twitter<\/string>\s*<string>fb<\/string>\s*<\/array>/);
+ expect(info_plist).toMatch(/<key>LSApplicationQueriesSchemes<\/key>\s*<array>\s*<string>twitter<\/string>\s*<\/array>/);
+ });
});
describe('of binary plist config files', function () {
it('should merge dictionaries and arrays, removing duplicates', function () {
diff --git a/spec/CordovaError/CordovaError.spec.js b/spec/CordovaError/CordovaError.spec.js
new file mode 100644
index 0000000..56e3e24
--- /dev/null
+++ b/spec/CordovaError/CordovaError.spec.js
@@ -0,0 +1,41 @@
+/**
+ 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.
+*/
+
+var CordovaError = require('../../src/CordovaError/CordovaError');
+
+describe('CordovaError class', function () {
+ it('Test 001 : should be constructable', function () {
+ expect(new CordovaError('error')).toEqual(jasmine.any(CordovaError));
+ });
+
+ it('Test 002 : getErrorCodeName works', function () {
+ var error002_1 = new CordovaError('error', 0);
+ expect(error002_1.getErrorCodeName()).toEqual('UNKNOWN_ERROR');
+ var error002_2 = new CordovaError('error', 1);
+ expect(error002_2.getErrorCodeName()).toEqual('EXTERNAL_TOOL_ERROR');
+ });
+
+ it('Test 003 : toString works', function () {
+ var error003_1 = new CordovaError('error', 0);
+ expect(error003_1.toString(false)).toEqual('error');
+ expect(error003_1.toString(true).substring(0, 12)).toEqual('CordovaError');
+ var error003_2 = new CordovaError('error', 1);
+ expect(error003_2.toString(false)).toEqual('External tool failed with an error: error');
+ });
+});
diff --git a/spec/fixtures/test-configfile0.xml b/spec/fixtures/test-configfile0.xml
new file mode 100644
index 0000000..680c18c
--- /dev/null
+++ b/spec/fixtures/test-configfile0.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget android-packageName="io.cordova.hellocordova.android" id="io.cordova.hellocordova" ios-CFBundleIdentifier="io.cordova.hellocordova.ios" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+ <name>Hello Cordova</name>
+ <description>
+ A sample Apache Cordova application that responds to the deviceready event.
+ </description>
+ <author email="dev@cordova.apache.org" href="http://cordova.io">
+ Apache Cordova Team
+ </author>
+ <content src="index.html" />
+ <access origin="*" />
+ <platform name="android">
+ </platform>
+</widget>
diff --git a/spec/fixtures/test-configfile1.xml b/spec/fixtures/test-configfile1.xml
new file mode 100644
index 0000000..8c7dee2
--- /dev/null
+++ b/spec/fixtures/test-configfile1.xml
@@ -0,0 +1,29 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget android-packageName="io.cordova.hellocordova.android" id="io.cordova.hellocordova" ios-CFBundleIdentifier="io.cordova.hellocordova.ios" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+ <name>Hello Cordova</name>
+ <description>
+ A sample Apache Cordova application that responds to the deviceready event.
+ </description>
+ <author email="dev@cordova.apache.org" href="http://cordova.io">
+ Apache Cordova Team
+ </author>
+ <content src="index.html" />
+ <access origin="*" />
+ <platform name="android">
+ <config-file parent="/manifest" target="AndroidManifest.xml">
+ <uses-permission android:name="android.permission.VIBRATE" />
+ </config-file>
+ </platform>
+ <platform name="ios">
+ <allow-intent href="itms:*" />
+ <allow-intent href="itms-apps:*" />
+ <config-file parent="NSCameraUsageDescription" target="*-Info.plist">
+ <string>This app uses Camera</string>
+ </config-file>
+ <config-file parent="LSApplicationQueriesSchemes" target="*-Info.plist">
+ <array>
+ <string>twitter</string>
+ </array>
+ </config-file>
+ </platform>
+</widget>
diff --git a/spec/fixtures/test-configfile2.xml b/spec/fixtures/test-configfile2.xml
new file mode 100644
index 0000000..86e503d
--- /dev/null
+++ b/spec/fixtures/test-configfile2.xml
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding='utf-8'?>
+<widget android-packageName="io.cordova.hellocordova.android" id="io.cordova.hellocordova" ios-CFBundleIdentifier="io.cordova.hellocordova.ios" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+ <name>Hello Cordova</name>
+ <description>
+ A sample Apache Cordova application that responds to the deviceready event.
+ </description>
+ <author email="dev@cordova.apache.org" href="http://cordova.io">
+ Apache Cordova Team
+ </author>
+ <content src="index.html" />
+ <access origin="*" />
+ <platform name="android">
+ <config-file parent="/manifest" target="AndroidManifest.xml">
+ <uses-permission android:name="android.permission.VIBRATE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ </config-file>
+ </platform>
+ <platform name="ios">
+ <allow-intent href="itms:*" />
+ <allow-intent href="itms-apps:*" />
+ <config-file parent="NSCameraUsageDescription" target="*-Info.plist">
+ <string>Please permit Camera</string>
+ </config-file>
+ <config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
+ <string>Please permit PhotoLibrary</string>
+ </config-file>
+ <config-file parent="LSApplicationQueriesSchemes" target="*-Info.plist">
+ <array>
+ <string>twitter</string>
+ <string>fb</string>
+ </array>
+ </config-file>
+ </platform>
+</widget>
diff --git a/src/ConfigChanges/ConfigChanges.js b/src/ConfigChanges/ConfigChanges.js
index e7ad0e2..87107e5 100644
--- a/src/ConfigChanges/ConfigChanges.js
+++ b/src/ConfigChanges/ConfigChanges.js
@@ -169,7 +169,6 @@ function add_config_changes (config, should_increment) {
var self = this;
var platform_config = self.platformJson.root;
- var config_munge;
var changes = [];
if (config.getEditConfigs) {
@@ -186,33 +185,48 @@ function add_config_changes (config, should_increment) {
}
}
- if (changes && changes.length > 0) {
- var isConflictingInfo = is_conflicting(changes, platform_config.config_munge, self, true /* always force overwrite other edit-config */);
- if (isConflictingInfo.conflictFound) {
+ var platform_config_munge = platform_config.config_munge;
+
+ var differs = (function (changes) {
+ if (changes && changes.length >= 0) {
+ var isConflictingInfo = is_conflicting(changes, platform_config_munge, self, true /* always force overwrite other edit-config */);
var conflict_munge;
var conflict_file;
-
- if (Object.keys(isConflictingInfo.configxmlMunge.files).length !== 0) {
- // silently remove conflicting config.xml munges so new munges can be added
- conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.configxmlMunge);
+ // remove unused config munge.
+ if (Object.keys(isConflictingInfo.unusedConfigMunge.files).length !== 0) {
+ conflict_munge = mungeutil.decrement_munge(platform_config_munge, isConflictingInfo.unusedConfigMunge);
for (conflict_file in conflict_munge.files) {
self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
}
}
- if (Object.keys(isConflictingInfo.conflictingMunge.files).length !== 0) {
- events.emit('warn', 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');
+ // check override conflicting munge.
+ if (isConflictingInfo.conflictFound) {
+ if (Object.keys(isConflictingInfo.configxmlMunge.files).length !== 0) {
+ // silently remove conflicting config.xml munges so new munges can be added
+ conflict_munge = mungeutil.decrement_munge(platform_config_munge, isConflictingInfo.configxmlMunge);
+ for (conflict_file in conflict_munge.files) {
+ self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ }
+ }
+ if (Object.keys(isConflictingInfo.conflictingMunge.files).length !== 0) {
+ events.emit('warn', 'Conflict found, edit-config changes from config.xml will overwrite plugin.xml changes');
- // remove conflicting plugin.xml munges
- conflict_munge = mungeutil.decrement_munge(platform_config.config_munge, isConflictingInfo.conflictingMunge);
- for (conflict_file in conflict_munge.files) {
- self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ // remove conflicting plugin.xml munges
+ conflict_munge = mungeutil.decrement_munge(platform_config_munge, isConflictingInfo.conflictingMunge);
+ for (conflict_file in conflict_munge.files) {
+ self.apply_file_munge(conflict_file, conflict_munge.files[conflict_file], /* remove = */ true);
+ }
}
+ // skip no chnages
+ return changes.filter(function (x) { return isConflictingInfo.noChanges.indexOf(x) === -1; });
}
+
}
- }
+ return changes;
+ })(changes);
// Add config.xml edit-config and config-file munges
- config_munge = self.generate_config_xml_munge(config, changes, 'config.xml');
+ var config_munge = self.generate_config_xml_munge(config, differs, 'config.xml');
self = munge_helper(should_increment, self, platform_config, config_munge);
// Move to installed/dependent_plugins
@@ -257,7 +271,7 @@ function reapply_global_munge () {
return self;
}
-// generate_plugin_config_munge
+// generate_config_xml_munge
// Generate the munge object from config.xml
PlatformMunger.prototype.generate_config_xml_munge = generate_config_xml_munge;
function generate_config_xml_munge (config, config_changes, type) {
@@ -282,7 +296,7 @@ function generate_config_xml_munge (config, config_changes, type) {
if (change.mode) {
mungeutil.deep_add(munge, change.file, change.target, { xml: stringified, count: 1, mode: change.mode, id: id });
} else {
- mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after });
+ mungeutil.deep_add(munge, change.target, change.parent, { xml: stringified, count: 1, after: change.after, id: id });
}
});
});
@@ -335,43 +349,80 @@ function is_conflicting (editchanges, config_munge, self, force) {
var configxmlMunge = { files: {} };
var conflictingParent;
var conflictingPlugin;
+ var noChanges = [];
+
+ var unusedConfigMunge = mungeutil.filterClone(config_munge, function (x) { return x.id === 'config.xml'; });
editchanges.forEach(function (editchange) {
- if (files[editchange.file]) {
- var parents = files[editchange.file].parents;
- var target = parents[editchange.target];
+ var change_file, change_target, change_id;
+ if (editchange.file) { // for edit_config
+ change_file = editchange.file;
+ change_target = editchange.target;
+ change_id = editchange.id;
+ } else { // for config_file
+ change_file = editchange.target;
+ change_target = editchange.parent;
+ change_id = editchange.id;
+ }
+
+ if (files[change_file]) {
+ var parents = files[change_file].parents;
+ var target = parents[change_target];
// Check if the edit target will resolve to an existing target
if (!target || target.length === 0) {
- var file_xml = self.config_keeper.get(self.project_dir, self.platform, editchange.file).data;
- var resolveEditTarget = xml_helpers.resolveParent(file_xml, editchange.target);
- var resolveTarget;
-
- if (resolveEditTarget) {
- for (var parent in parents) {
- resolveTarget = xml_helpers.resolveParent(file_xml, parent);
- if (resolveEditTarget === resolveTarget) {
- conflictingParent = parent;
- target = parents[parent];
- break;
+ var configFile = self.config_keeper.get(self.project_dir, self.platform, change_file);
+ var file_type = configFile.type;
+ if (file_type === 'xml') {
+ var file_xml = configFile.data;
+ var resolveEditTarget = xml_helpers.resolveParent(file_xml, change_target);
+ var resolveTarget;
+
+ if (resolveEditTarget) {
+ for (var parent in parents) {
+ resolveTarget = xml_helpers.resolveParent(file_xml, parent);
+ if (resolveEditTarget === resolveTarget) {
+ conflictingParent = parent;
+ target = parents[parent];
+ break;
+ }
}
}
+ } else {
+ conflictingParent = change_target;
}
} else {
- conflictingParent = editchange.target;
+ conflictingParent = change_target;
}
if (target && target.length !== 0) {
// conflict has been found
conflictFound = true;
- if (editchange.id === 'config.xml') {
+ if (change_id === 'config.xml') {
+ target.forEach(function (target_elem) {
+ mungeutil.deep_remove(unusedConfigMunge, change_file, conflictingParent, target_elem);
+ });
+ }
+
+ var xmlStrList, isSameAll;
+ if (change_id === 'config.xml') {
if (target[0].id === 'config.xml') {
- // Keep track of config.xml/config.xml edit-config conflicts
- mungeutil.deep_add(configxmlMunge, editchange.file, conflictingParent, target[0]);
+ xmlStrList = changedXmlStrList(editchange);
+ isSameAll = compareChangedXmlsAndTarget(xmlStrList, target);
+ if (isSameAll) {
+ noChanges.push(editchange);
+ } else {
+ // Keep track of config.xml/config.xml edit-config conflicts
+ target.forEach(function (target_elem) {
+ mungeutil.deep_add(configxmlMunge, change_file, conflictingParent, target_elem);
+ });
+ }
} else {
// Keep track of config.xml x plugin.xml edit-config conflicts
- mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
+ target.forEach(function (target_elem) {
+ mungeutil.deep_add(conflictingMunge, change_file, conflictingParent, target_elem);
+ });
}
} else {
if (target[0].id === 'config.xml') {
@@ -381,8 +432,18 @@ function is_conflicting (editchanges, config_munge, self, force) {
}
if (force) {
- // Need to find all conflicts when --force is used, track conflicting munges
- mungeutil.deep_add(conflictingMunge, editchange.file, conflictingParent, target[0]);
+ xmlStrList = changedXmlStrList(editchange);
+ isSameAll = compareChangedXmlsAndTarget(xmlStrList, target);
+
+ if (isSameAll) {
+ noChanges.push(editchange);
+ } else {
+ // Need to find all conflicts when --force is used, track conflicting munges
+ target.forEach(function (target_elem) {
+ mungeutil.deep_add(conflictingMunge, change_file, conflictingParent, target_elem);
+ });
+ }
+
} else {
// plugin cannot overwrite other plugin changes without --force
conflictingPlugin = target[0].plugin;
@@ -397,7 +458,35 @@ function is_conflicting (editchanges, config_munge, self, force) {
conflictingPlugin: conflictingPlugin,
conflictingMunge: conflictingMunge,
configxmlMunge: configxmlMunge,
- conflictWithConfigxml: conflictWithConfigxml};
+ conflictWithConfigxml: conflictWithConfigxml,
+ noChanges: noChanges,
+ unusedConfigMunge: unusedConfigMunge };
+}
+
+function changedXmlStrList (editchange) {
+ var xmlStrList = [];
+ editchange.xmls.forEach(function (xml) {
+ var stringified = (new et.ElementTree(xml)).write({xml_declaration: false});
+ xmlStrList.push(stringified);
+ });
+ return xmlStrList;
+}
+
+// if all elements of target are same as xmlStrList, return true;
+// otherwise return false;
+function compareChangedXmlsAndTarget (xmlStrList, target) {
+ if (xmlStrList.length !== target.length) {
+ return false;
+ }
+ var isSame = target.reduce(function (acc, elem) {
+ var found1 = xmlStrList.find(function (x) { return x === elem.xml && elem.id === 'config.xml'; });
+ if (found1) {
+ return acc;
+ } else {
+ return false;
+ }
+ }, true);
+ return isSame;
}
// Go over the prepare queue and apply the config munges for each plugin
diff --git a/src/ConfigChanges/ConfigFile.js b/src/ConfigChanges/ConfigFile.js
index a42c06b..1dd86d8 100644
--- a/src/ConfigChanges/ConfigFile.js
+++ b/src/ConfigChanges/ConfigFile.js
@@ -190,6 +190,7 @@ function resolveConfigFilePath (project_dir, platform, file) {
// only if none of the options above are satisfied does this get called
// TODO: Move this out of cordova-common and into the platforms somehow
if (platform === 'android' && !fs.existsSync(filepath)) {
+ var config_file;
if (file === 'AndroidManifest.xml') {
filepath = path.join(project_dir, 'app', 'src', 'main', 'AndroidManifest.xml');
} else if (file.endsWith('config.xml')) {
@@ -197,9 +198,12 @@ function resolveConfigFilePath (project_dir, platform, file) {
} else if (file.endsWith('strings.xml')) {
// Plugins really shouldn't mess with strings.xml, since it's able to be localized
filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'values', 'strings.xml');
+ } else if (file.includes(path.join('res', 'values'))) {
+ config_file = path.basename(file);
+ filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'values', config_file);
} else if (file.includes(path.join('res', 'xml'))) {
// Catch-all for all other stored XML configuration in legacy plugins
- var config_file = path.basename(file);
+ config_file = path.basename(file);
filepath = path.join(project_dir, 'app', 'src', 'main', 'res', 'xml', config_file);
}
return filepath;
diff --git a/src/ConfigChanges/munge-util.js b/src/ConfigChanges/munge-util.js
index 62648d8..3c3854e 100644
--- a/src/ConfigChanges/munge-util.js
+++ b/src/ConfigChanges/munge-util.js
@@ -86,6 +86,29 @@ exports.deep_find = function deep_find (obj, keys /* or key1, key2 .... */) {
// When createParents is true, add the file and parent items they are missing
// When createParents is false, stop and return undefined if the file and/or parent items are missing
+exports.filterClone = function filterClone (obj, func) {
+ var result = { files: {} };
+ for (var file in obj.files) {
+ var parents = {};
+ // result.files[file] = { parents:{} };
+ for (var target in obj.files[file].parents) {
+ var list = [];
+ obj.files[file].parents[target].forEach(function (target_elem) {
+ if (func(target_elem)) {
+ list.push(_.clone(target_elem, true));
+ }
+ });
+ if (list.length > 0) {
+ parents[target] = list;
+ }
+ }
+ if (Object.keys(parents).length > 0) {
+ result.files[file] = { parents: parents };
+ }
+ }
+ return result;
+};
+
exports.process_munge = function process_munge (obj, createParents, func, keys /* or key1, key2 .... */) {
if (!Array.isArray(keys)) {
keys = Array.prototype.slice.call(arguments, 1);
diff --git a/src/ConfigParser/ConfigParser.js b/src/ConfigParser/ConfigParser.js
index f0d26b5..9d6aeec 100644
--- a/src/ConfigParser/ConfigParser.js
+++ b/src/ConfigParser/ConfigParser.js
@@ -562,7 +562,8 @@ ConfigParser.prototype = {
xmls: tag.getchildren(),
// To support demuxing via versions
versions: tag.attrib['versions'],
- deviceTarget: tag.attrib['device-target']
+ deviceTarget: tag.attrib['device-target'],
+ id: 'config.xml'
};
return configFile;
});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org