diff --git a/bin/templates/cordova/lib/pluginHandlers.js b/bin/templates/cordova/lib/pluginHandlers.js
index 25890ba2..6d1a7336 100644
--- a/bin/templates/cordova/lib/pluginHandlers.js
+++ b/bin/templates/cordova/lib/pluginHandlers.js
@@ -294,27 +294,41 @@ function generateAttributeError (attribute, element, id) {
function getInstallDestination (obj) {
var APP_MAIN_PREFIX = 'app/src/main';
+ var PATH_SEPARATOR = '/';
- if (obj.targetDir.startsWith('app')) {
+ var PATH_SEP_MATCH = '\\' + PATH_SEPARATOR;
+ var PATH_SEP_OR_EOL_MATCH = '(\\' + PATH_SEPARATOR + '|$)';
+
+ var appReg = new RegExp('^app' + PATH_SEP_OR_EOL_MATCH);
+ var libsReg = new RegExp('^libs' + PATH_SEP_OR_EOL_MATCH);
+ var srcReg = new RegExp('^src' + PATH_SEP_OR_EOL_MATCH);
+ var srcMainReg = new RegExp('^src' + PATH_SEP_MATCH + 'main' + PATH_SEP_OR_EOL_MATCH);
+
+ if (appReg.test(obj.targetDir)) {
// If any source file is using the new app directory structure,
// don't penalize it
return path.join(obj.targetDir, path.basename(obj.src));
- } else if (obj.src.endsWith('.java')) {
- return path.join(APP_MAIN_PREFIX, 'java', obj.targetDir.substring(4), path.basename(obj.src));
- } else if (obj.src.endsWith('.aidl')) {
- return path.join(APP_MAIN_PREFIX, 'aidl', obj.targetDir.substring(4), path.basename(obj.src));
- } else if (obj.targetDir.includes('libs')) {
- if (obj.src.endsWith('.so')) {
- return path.join(APP_MAIN_PREFIX, 'jniLibs', obj.targetDir.substring(5), path.basename(obj.src));
- } else {
+ } else {
+ // Plugin using deprecated target directory structure (GH-580)
+ if (obj.src.endsWith('.java')) {
+ return path.join(APP_MAIN_PREFIX, 'java', obj.targetDir.replace(srcReg, ''),
+ path.basename(obj.src));
+ } else if (obj.src.endsWith('.aidl')) {
+ return path.join(APP_MAIN_PREFIX, 'aidl', obj.targetDir.replace(srcReg, ''),
+ path.basename(obj.src));
+ } else if (libsReg.test(obj.targetDir)) {
+ if (obj.src.endsWith('.so')) {
+ return path.join(APP_MAIN_PREFIX, 'jniLibs', obj.targetDir.replace(libsReg, ''),
+ path.basename(obj.src));
+ } else {
+ return path.join('app', obj.targetDir, path.basename(obj.src));
+ }
+ } else if (srcMainReg.test(obj.targetDir)) {
return path.join('app', obj.targetDir, path.basename(obj.src));
}
- } else if (obj.targetDir.includes('src/main')) {
- return path.join('app', obj.targetDir, path.basename(obj.src));
- } else {
+
// For all other source files not using the new app directory structure,
// add 'app/src/main' to the targetDir
return path.join(APP_MAIN_PREFIX, obj.targetDir, path.basename(obj.src));
}
-
}
diff --git a/spec/fixtures/org.test.plugins.dummyplugin/plugin.xml b/spec/fixtures/org.test.plugins.dummyplugin/plugin.xml
index 9bc99d21..f7a82ba5 100644
--- a/spec/fixtures/org.test.plugins.dummyplugin/plugin.xml
+++ b/spec/fixtures/org.test.plugins.dummyplugin/plugin.xml
@@ -84,6 +84,8 @@
+
diff --git a/spec/unit/pluginHandlers/handlers.spec.js b/spec/unit/pluginHandlers/handlers.spec.js
index 31e7b453..a44b8cf0 100644
--- a/spec/unit/pluginHandlers/handlers.spec.js
+++ b/spec/unit/pluginHandlers/handlers.spec.js
@@ -169,6 +169,12 @@ describe('android project handler', function () {
expect(copyFileSpy)
.toHaveBeenCalledWith(dummyplugin, 'src/android/DummyPlugin2.java', temp, path.join('app/src/main/java/com/appco/DummyPlugin2.java'), false);
});
+
+ it('Test#006k : should allow installing sources with target-dir that includes "app" in its first directory', function () {
+ android['source-file'].install(valid_source[11], dummyPluginInfo, dummyProject, {android_studio: true});
+ expect(copyFileSpy)
+ .toHaveBeenCalledWith(dummyplugin, 'src/android/DummyPlugin2.java', temp, path.join('app/src/main/java/appco/src/DummyPlugin2.java'), false);
+ });
});
describe('of elements', function () {