You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sg...@apache.org on 2014/09/29 10:24:47 UTC

[1/2] android commit: CB-6511 Fixes build for android when app name contains unicode characters.

Repository: cordova-android
Updated Branches:
  refs/heads/3.6.x e2e38ad2b -> 1c3f7e6f9


CB-6511 Fixes build for android when app name contains unicode characters.


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/e65bfa41
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/e65bfa41
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/e65bfa41

Branch: refs/heads/3.6.x
Commit: e65bfa41a5185dd0ce726081e1fef68c258f906b
Parents: e2e38ad
Author: Vladimir Kotikov <v-...@microsoft.com>
Authored: Tue Sep 23 13:21:17 2014 +0400
Committer: Vladimir Kotikov <v-...@microsoft.com>
Committed: Fri Sep 26 11:59:05 2014 +0400

----------------------------------------------------------------------
 bin/lib/create.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e65bfa41/bin/lib/create.js
----------------------------------------------------------------------
diff --git a/bin/lib/create.js b/bin/lib/create.js
index c4c6f1b..e38acc5 100755
--- a/bin/lib/create.js
+++ b/bin/lib/create.js
@@ -210,9 +210,11 @@ exports.createProject = function(project_path, package_name, project_name, proje
                            project_template_dir : 
                            path.join(ROOT, 'bin', 'templates', 'project');
 
-    var safe_activity_name = project_name.replace(/\W/g, '');
     var package_as_path = package_name.replace(/\./g, path.sep);
     var activity_dir    = path.join(project_path, 'src', package_as_path);
+    // safe_activity_name is being hardcoded to avoid issues with unicode app name (https://issues.apache.org/jira/browse/CB-6511)
+    // TODO: provide option to specify activity name via CLI (proposal: https://issues.apache.org/jira/browse/CB-7231)
+    var safe_activity_name = "CordovaApp";
     var activity_path   = path.join(activity_dir, safe_activity_name + '.java');
     var target_api      = check_reqs.get_target();
     var manifest_path   = path.join(project_path, 'AndroidManifest.xml');


[2/2] android commit: CB-7579 Fix run script's ability to use non-arch-specific APKs

Posted by sg...@apache.org.
CB-7579 Fix run script's ability to use non-arch-specific APKs


Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/1c3f7e6f
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/1c3f7e6f
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/1c3f7e6f

Branch: refs/heads/3.6.x
Commit: 1c3f7e6f93e83da1c6bc477dceff05bd979a6eac
Parents: e65bfa4
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Sep 22 14:23:30 2014 -0400
Committer: Vladimir Kotikov <v-...@microsoft.com>
Committed: Fri Sep 26 15:04:21 2014 +0400

----------------------------------------------------------------------
 bin/templates/cordova/lib/build.js    | 157 ++++++++++++++++-------------
 bin/templates/cordova/lib/device.js   |  23 ++---
 bin/templates/cordova/lib/emulator.js |  14 ++-
 bin/templates/cordova/lib/run.js      |  26 ++---
 4 files changed, 121 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1c3f7e6f/bin/templates/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/build.js b/bin/templates/cordova/lib/build.js
index 30056f4..9e1353b 100644
--- a/bin/templates/cordova/lib/build.js
+++ b/bin/templates/cordova/lib/build.js
@@ -20,6 +20,7 @@
 */
 
 var shell   = require('shelljs'),
+    exec    = require('./exec'),
     spawn   = require('./spawn'),
     Q       = require('q'),
     path    = require('path'),
@@ -31,20 +32,46 @@ var LOCAL_PROPERTIES_TEMPLATE =
     '# This file is automatically generated.\n' +
     '# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n';
 
-function find_files(directory, predicate) {
+function findApks(directory) {
+    var ret = [];
     if (fs.existsSync(directory)) {
-        var candidates = fs.readdirSync(directory).filter(predicate).map(function(p) {
-            p = path.join(directory, p);
-            return { p: p, t: fs.statSync(p).mtime };
-        }).sort(function(a,b) {
-            return a.t > b.t ? -1 :
-                   a.t < b.t ? 1 : 0;
-        }).map(function(p) { return p.p; });
-        return candidates;
-    } else {
-        console.error('ERROR : unable to find project ' + directory + ' directory, could not locate .apk');
-        process.exit(2);
+        fs.readdirSync(directory).forEach(function(p) {
+            if (path.extname(p) == '.apk') {
+                ret.push(path.join(directory, p));
+            }
+        });
     }
+    return ret;
+}
+
+function sortFilesByDate(files) {
+    return files.map(function(p) {
+        return { p: p, t: fs.statSync(p).mtime };
+    }).sort(function(a, b) {
+        var timeDiff = b.t - a.t;
+        return timeDiff === 0 ? a.p.length - b.p.length : timeDiff;
+    }).map(function(p) { return p.p; });
+}
+
+function findOutputApksHelper(dir, build_type) {
+    var ret = findApks(dir).filter(function(candidate) {
+        // Need to choose between release and debug .apk.
+        if (build_type === 'debug') {
+            return /-debug/.exec(candidate) && !/-unaligned|-unsigned/.exec(candidate);
+        }
+        if (build_type === 'release') {
+            return /-release/.exec(candidate) && !/-unaligned/.exec(candidate);
+        }
+        return true;
+    });
+    ret = sortFilesByDate(ret);
+    if (ret.length === 0) {
+        return ret;
+    }
+    var archSpecific = !!/-x86|-arm/.exec(ret[0]);
+    return ret.filter(function(p) {
+        return !!/-x86|-arm/.exec(p) == archSpecific;
+    });
 }
 
 function hasCustomRules() {
@@ -123,8 +150,6 @@ var builders = {
             return check_reqs.check_ant()
             .then(function() {
                 return spawn('ant', args);
-            }).then(function() {
-                return builder.getOutputFiles();
             });
         },
 
@@ -136,22 +161,9 @@ var builders = {
             });
         },
 
-        // Find the recently-generated output APK files
-        // Ant only generates one output file; return it.
-        getOutputFiles: function() {
-            var binDir;
-            if(hasCustomRules()) {
-                binDir = path.join(ROOT, 'ant-build');
-            } else {
-                binDir = path.join(ROOT, 'bin');
-            }
-            var candidates = find_files(binDir, function(candidate) { return path.extname(candidate) == '.apk'; });
-            if (candidates.length === 0) {
-                console.error('ERROR : No .apk found in ' + binDir + ' directory');
-                process.exit(2);
-            }
-            console.log('Using apk: ' + candidates[0]);
-            return [candidates[0]];
+        findOutputApks: function(build_type) {
+            var binDir = path.join(ROOT, hasCustomRules() ? 'ant-build' : 'bin');
+            return findOutputApksHelper(binDir, build_type);
         }
     },
     gradle: {
@@ -218,8 +230,6 @@ var builders = {
             var args = builder.getArgs('build');
             return Q().then(function() {
                 return spawn(wrapper, args);
-            }).then(function() {
-                return builder.getOutputFiles(build_type);
             });
         },
 
@@ -232,21 +242,9 @@ var builders = {
             });
         },
 
-        // Find the recently-generated output APK files
-        // Gradle can generate multiple output files; return all of them.
-        getOutputFiles: function(build_type) {
+        findOutputApks: function(build_type) {
             var binDir = path.join(ROOT, 'build', 'apk');
-            var candidates = find_files(binDir, function(candidate) {
-                // Need to choose between release and debug .apk.
-                if (build_type === 'debug') {
-                    return (path.extname(candidate) == '.apk' && candidate.indexOf('-debug-') >= 0);
-                }
-                if (build_type === 'release') {
-                    return (path.extname(candidate) == '.apk' && candidate.indexOf('-release-') >= 0);
-                }
-                return path.extname(candidate) == '.apk';
-            });
-            return candidates;
+            return findOutputApksHelper(binDir, build_type);
         }
     },
 
@@ -256,11 +254,14 @@ var builders = {
         },
         build: function() {
             console.log('Skipping build...');
-            return Q();
+            return Q(null);
         },
         clean: function() {
             return Q();
         },
+        findOutputApks: function(build_type) {
+            return sortFilesByDate(builders.ant.findOutputApks(build_type).concat(builders.gradle.findOutputApks(build_type)));
+        }
     }
 };
 
@@ -275,7 +276,7 @@ function parseOpts(options) {
 
     // Iterate through command line options
     for (var i=0; options && (i < options.length); ++i) {
-        if (options[i].substring && options[i].substring(0,2) == "--") {
+        if (/^--/.exec(options[i])) {
             var option = options[i].substring(2);
             switch(option) {
                 case 'debug':
@@ -325,33 +326,51 @@ module.exports.run = function(options) {
     return builder.prepEnv()
     .then(function() {
         return builder.build(opts.buildType);
-    }).then(function(apkFiles) {
-        // TODO: Rather than copy apks to out, it might be better to
-        // just write out what the last .apk build was. These files
-        // are used by get_apk().
-        var outputDir = path.join(ROOT, 'out');
-        shell.mkdir('-p', outputDir);
-        for (var i=0; i < apkFiles.length; ++i) {
-            shell.cp('-f', apkFiles[i], path.join(outputDir, path.basename(apkFiles[i])));
-        }
+    }).then(function() {
+        var apkPaths = builder.findOutputApks(opts.buildType);
+        console.log('Built the following apk(s):');
+        console.log('    ' + apkPaths.join('\n    '));
+        return {
+            apkPaths: apkPaths,
+            buildType: opts.buildType,
+            buildMethod: opts.buildMethod
+        };
     });
 };
 
 /*
- * Gets the path to the apk file, if not such file exists then
- * the script will error out. (should we error or just return undefined?)
- * This is called by the run script to install the apk to the device
+ * Detects the architecture of a device/emulator
+ * Returns "arm" or "x86".
  */
-module.exports.get_apk = function(build_type, architecture) {
-    var outputDir = path.join(ROOT, 'out');
-    var candidates = find_files(outputDir, function(filename) { return (!architecture) || filename.indexOf(architecture) >= 0; });
-    if (candidates.length === 0) {
-        console.error('ERROR : No .apk found in ' + outputDir + ' directory');
-        process.exit(2);
+module.exports.detectArchitecture = function(target) {
+    return exec('adb -s ' + target + ' shell cat /proc/cpuinfo')
+    .then(function(output) {
+        if (/intel/i.exec(output)) {
+            return 'x86';
+        }
+        return 'arm';
+    });
+};
+
+module.exports.findBestApkForArchitecture = function(buildResults, arch) {
+    var paths = buildResults.apkPaths.filter(function(p) {
+        if (buildResults.buildType == 'debug') {
+            return /-debug/.exec(p);
+        }
+        return !/-debug/.exec(p);
+    });
+    var archPattern = new RegExp('-' + arch);
+    var hasArchPattern = /-x86|-arm/;
+    for (var i = 0; i < paths.length; ++i) {
+        if (hasArchPattern.exec(paths[i])) {
+            if (archPattern.exec(paths[i])) {
+                return paths[i];
+            }
+        } else {
+            return paths[i];
+        }
     }
-    // TODO: Use build_type here.
-    console.log('Using apk: ' + candidates[0]);
-    return candidates[0];
+    throw new Error('Could not find apk architecture: ' + arch + ' build-type: ' + buildResults.buildType);
 };
 
 module.exports.help = function() {

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1c3f7e6f/bin/templates/cordova/lib/device.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/device.js b/bin/templates/cordova/lib/device.js
index df21287..c3bd9a2 100644
--- a/bin/templates/cordova/lib/device.js
+++ b/bin/templates/cordova/lib/device.js
@@ -48,7 +48,7 @@ module.exports.list = function() {
  * and launches it.
  * Returns a promise.
  */
-module.exports.install = function(target) {
+module.exports.install = function(target, buildResults) {
     var launchName;
     return this.list()
     .then(function(device_list) {
@@ -56,21 +56,20 @@ module.exports.install = function(target) {
             return Q.reject('ERROR: Failed to deploy to device, no devices found.');
 
         // default device
-        target = typeof target !== 'undefined' ? target : device_list[0];
+        target = target || device_list[0];
 
         if (device_list.indexOf(target) < 0)
             return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
 
-        var apk_path;
-        if (typeof process.env.DEPLOY_APK_ARCH == 'undefined') {
-            apk_path = build.get_apk();
-        } else {
-            apk_path = build.get_apk(null, process.env.DEPLOY_APK_ARCH);
-        }
-        launchName = appinfo.getActivityName();
-        console.log('Installing app on device...');
-        var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
-        return exec(cmd);
+        return build.detectArchitecture(target)
+        .then(function(arch) {
+            var apk_path = build.findBestApkForArchitecture(buildResults, arch);
+            launchName = appinfo.getActivityName();
+            console.log('Using apk: ' + apk_path);
+            console.log('Installing app on device...');
+            var cmd = 'adb -s ' + target + ' install -r "' + apk_path + '"';
+            return exec(cmd);
+        });
     }).then(function(output) {
         if (output.match(/Failure/)) return Q.reject('ERROR: Failed to install apk to device: ' + output);
 

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1c3f7e6f/bin/templates/cordova/lib/emulator.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/emulator.js b/bin/templates/cordova/lib/emulator.js
index 69f0e1b..b46db6e 100644
--- a/bin/templates/cordova/lib/emulator.js
+++ b/bin/templates/cordova/lib/emulator.js
@@ -283,7 +283,7 @@ module.exports.create_image = function(name, target) {
  * If no started emulators are found, error out.
  * Returns a promise.
  */
-module.exports.install = function(target) {
+module.exports.install = function(target, buildResults) {
     var self = this;
     return this.list_started()
     .then(function(emulator_list) {
@@ -292,14 +292,18 @@ module.exports.install = function(target) {
         }
 
         // default emulator
-        target = typeof target !== 'undefined' ? target : emulator_list[0];
+        target = target || emulator_list[0];
         if (emulator_list.indexOf(target) < 0) {
             return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
         }
 
-        console.log('Installing app on emulator...');
-        var apk_path = build.get_apk();
-        return exec('adb -s ' + target + ' install -r "' + apk_path + '"');
+        return build.detectArchitecture(target)
+        .then(function(arch) {
+            var apk_path = build.findBestApkForArchitecture(buildResults, arch);
+            console.log('Installing app on emulator...');
+            console.log('Using apk: ' + apk_path);
+            return exec('adb -s ' + target + ' install -r "' + apk_path + '"');
+        });
     }).then(function(output) {
         if (output.match(/Failure/)) {
             return Q.reject('Failed to install apk to emulator: ' + output);

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/1c3f7e6f/bin/templates/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/run.js b/bin/templates/cordova/lib/run.js
index da8fc60..f22f32e 100644
--- a/bin/templates/cordova/lib/run.js
+++ b/bin/templates/cordova/lib/run.js
@@ -33,16 +33,16 @@ var path  = require('path'),
  * Returns a promise.
  */
  module.exports.run = function(args) {
-    var build_type;
+    var buildFlags = [];
     var install_target;
 
     for (var i=2; i<args.length; i++) {
         if (args[i] == '--debug') {
-            build_type = '--debug';
+            buildFlags.push('--debug');
         } else if (args[i] == '--release') {
-            build_type = '--release';
+            buildFlags.push('--release');
         } else if (args[i] == '--nobuild') {
-            build_type = '--nobuild';
+            buildFlags.push('--nobuild');
         } else if (args[i] == '--device') {
             install_target = '--device';
         } else if (args[i] == '--emulator') {
@@ -55,13 +55,13 @@ var path  = require('path'),
         }
     }
 
-    return build.run(build_type).then(function() {
+    return build.run(buildFlags).then(function(buildResults) {
         if (install_target == '--device') {
-            return device.install();
+            return device.install(null, buildResults);
         } else if (install_target == '--emulator') {
             return emulator.list_started().then(function(started) {
                 var p = started && started.length > 0 ? Q() : emulator.start();
-                return p.then(function() { emulator.install(); });
+                return p.then(function() { return emulator.install(null, buildResults); });
             });
         } else if (install_target) {
             var devices, started_emulators, avds;
@@ -75,16 +75,16 @@ var path  = require('path'),
             }).then(function(res) {
                 avds = res;
                 if (devices.indexOf(install_target) > -1) {
-                    return device.install(install_target);
+                    return device.install(install_target, buildResults);
                 } else if (started_emulators.indexOf(install_target) > -1) {
-                    return emulator.install(install_target);
+                    return emulator.install(install_target, buildResults);
                 } else {
                     // if target emulator isn't started, then start it.
                     var emulator_ID;
                     for(avd in avds) {
                         if(avds[avd].name == install_target) {
                             return emulator.start(install_target)
-                            .then(function() { emulator.install(emulator_ID); });
+                            .then(function() { emulator.install(emulator_ID, buildResults); });
                         }
                     }
                     return Q.reject('Target \'' + install_target + '\' not found, unable to run project');
@@ -96,13 +96,13 @@ var path  = require('path'),
             .then(function(device_list) {
                 if (device_list.length > 0) {
                     console.log('WARNING : No target specified, deploying to device \'' + device_list[0] + '\'.');
-                    return device.install(device_list[0]);
+                    return device.install(device_list[0], buildResults);
                 } else {
                     return emulator.list_started()
                     .then(function(emulator_list) {
                         if (emulator_list.length > 0) {
                             console.log('WARNING : No target specified, deploying to emulator \'' + emulator_list[0] + '\'.');
-                            return emulator.install(emulator_list[0]);
+                            return emulator.install(emulator_list[0], buildResults);
                         } else {
                             console.log('WARNING : No started emulators found, starting an emulator.');
                             return emulator.best_image()
@@ -111,7 +111,7 @@ var path  = require('path'),
                                     return emulator.start(best_avd.name)
                                     .then(function(emulator_ID) {
                                         console.log('WARNING : No target specified, deploying to emulator \'' + emulator_ID + '\'.');
-                                        return emulator.install(emulator_ID);
+                                        return emulator.install(emulator_ID, buildResults);
                                     });
                                 } else {
                                     return emulator.start();