You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2014/08/19 18:03:09 UTC

[03/19] android commit: CB-7044, CB-7299 Fix up PATH problems when possible.

CB-7044, CB-7299 Fix up PATH problems when possible.

Uses heuristics:
- Adds javac to PATH based on default install paths on Windows
- Adds javac to PATH based on JAVA_HOME
- Adds android and adb to PATH based on ANDROID_HOME
- Sets ANDROID_HOME based on location of "android"


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

Branch: refs/heads/4.0.x
Commit: 4319447cb5157e5137465bcdc16bd6e3dcd99570
Parents: 50ea162
Author: Andrew Grieve <ag...@chromium.org>
Authored: Fri Aug 15 13:42:43 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Fri Aug 15 13:46:20 2014 -0400

----------------------------------------------------------------------
 bin/lib/check_reqs.js       | 100 +++++++++++++++++++++++++--------------
 bin/lib/create.js           |   2 +-
 bin/templates/cordova/build |   4 +-
 3 files changed, 67 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4319447c/bin/lib/check_reqs.js
----------------------------------------------------------------------
diff --git a/bin/lib/check_reqs.js b/bin/lib/check_reqs.js
index a4ad3ad..17a3bd4 100644
--- a/bin/lib/check_reqs.js
+++ b/bin/lib/check_reqs.js
@@ -19,26 +19,37 @@
        under the License.
 */
 
-var shell = require('shelljs'),
+var shelljs = require('shelljs'),
     child_process = require('child_process'),
     Q     = require('q'),
     path  = require('path'),
     fs    = require('fs'),
     ROOT  = path.join(__dirname, '..', '..');
 
+var isWindows = process.platform == 'win32';
+
+function tryCommand(cmd, errMsg) {
+    var d = Q.defer();
+    child_process.exec(cmd, function(err, stdout, stderr) {
+        if (err) d.reject(new Error(errMsg));
+        else d.resolve(stdout);
+    });
+    return d.promise;
+}
+
 // Get valid target from framework/project.properties
 module.exports.get_target = function() {
     if(fs.existsSync(path.join(ROOT, 'framework', 'project.properties'))) {
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
+        var target = shelljs.grep(/target=android-[\d+]/, path.join(ROOT, 'framework', 'project.properties'));
         return target.split('=')[1].replace('\n', '').replace('\r', '').replace(' ', '');
     } else if (fs.existsSync(path.join(ROOT, 'project.properties'))) {
         // if no target found, we're probably in a project and project.properties is in ROOT.
         // this is called on the project itself, and can support Google APIs AND Vanilla Android
-        var target = shell.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties')) ||
-          shell.grep(/target=Google Inc.:Google APIs:[\d+]/, path.join(ROOT, 'project.properties'));
+        var target = shelljs.grep(/target=android-[\d+]/, path.join(ROOT, 'project.properties')) ||
+          shelljs.grep(/target=Google Inc.:Google APIs:[\d+]/, path.join(ROOT, 'project.properties'));
         if(target == "" || !target) {
           // Try Google Glass APIs
-          target = shell.grep(/target=Google Inc.:Glass Development Kit Preview:[\d+]/, path.join(ROOT, 'project.properties'));
+          target = shelljs.grep(/target=Google Inc.:Glass Development Kit Preview:[\d+]/, path.join(ROOT, 'project.properties'));
         }
         return target.split('=')[1].replace('\n', '').replace('\r', '');
     }
@@ -46,49 +57,66 @@ module.exports.get_target = function() {
 
 // Returns a promise.
 module.exports.check_ant = function() {
-    var d = Q.defer();
-    child_process.exec('ant -version', function(err, stdout, stderr) {
-        if (err) d.reject(new Error('ERROR : executing command \'ant\', make sure you have ant installed and added to your path.'));
-        else d.resolve();
-    });
-    return d.promise;
+    return tryCommand('ant -version', 'Failed to run "ant -version", make sure you have ant installed and added to your PATH.');
 }
 
 // Returns a promise.
 module.exports.check_java = function() {
-    var d = Q.defer();
-    child_process.exec('java -version', function(err, stdout, stderr) {
-        if(err) {
-            var msg =
-                'Failed to run \'java -version\', make sure your java environment is set up\n' +
-                'including JDK and JRE.\n' +
-                'Your JAVA_HOME variable is ' + process.env.JAVA_HOME + '\n';
-            d.reject(new Error(msg + err));
+    var javacInPath = !!shelljs.which('javac');
+    var hasJavaHome = !!process.env.JAVA_HOME;
+    // Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
+    if (hasJavaHome && !javacInPath) {
+        process.env.PATH += path.delimiter + path.join(process.env.JAVA_HOME, 'bin');
+    } else if (isWindows && (!hasJavaHome || !javacInPath)) {
+        // Try to auto-detect java in the default install paths.
+        var firstJdkDir =
+            shelljs.ls(process.env.ProgramFiles + '\\java\\jdk*')[0] ||
+            shelljs.ls('C:\\Program Files\\java\\jdk*')[0] ||
+            shelljs.ls('C:\\Program Files (x86)\\java\\jdk*')[0];
+        if (firstJdkDir) {
+            // shelljs always uses / in paths.
+            firstJdkDir = firstJdkDir.replace(/\//g, path.sep);
+            if (!javacInPath) {
+                process.env.PATH += path.delimiter + path.join(firstJdkDir, 'bin');
+            }
+            process.env.JAVA_HOME = firstJdkDir;
         }
-        else d.resolve();
+    }
+    var msg =
+        'Failed to run "java -version", make sure your java environment is set up\n' +
+        'including JDK and JRE.\n' +
+        'Your JAVA_HOME variable is: ' + process.env.JAVA_HOME;
+    return tryCommand('java -version', msg)
+    .then(function() {
+        msg = 'Failed to run "javac -version", make sure you have a Java JDK (not just a JRE) installed.';
+        return tryCommand('javac -version', msg)
     });
-    return d.promise;
 }
 
 // Returns a promise.
 module.exports.check_android = function() {
-    var valid_target = this.get_target();
-    var d = Q.defer();
-    child_process.exec('android list targets', function(err, stdout, stderr) {
-        if (err) d.reject(stderr);
-        else d.resolve(stdout);
-    });
+    var androidCmdPath = !!shelljs.which('android');
+    var adbInPath = !!shelljs.which('adb');
+    var hasAndroidHome = !!process.env.ANDROID_HOME;
+    if (hasAndroidHome && !androidCmdPath) {
+        process.env.PATH += path.delimiter + path.join(process.env.ANDROID_HOME, 'tools');
+    }
+    if (androidCmdPath && !hasAndroidHome) {
+        process.env.ANDROID_HOME = path.dirname(path.dirname(androidCmdPath));
+        hasAndroidHome = true;
+    }
+    if (hasAndroidHome && !adbInPath) {
+        process.env.PATH += path.delimiter + path.join(process.env.ANDROID_HOME, 'platform-tools');
+    }
 
-    return d.promise.then(function(output) {
+    var valid_target = this.get_target();
+    var msg = 'Failed to run "android". Make sure you have the latest Android SDK installed, and that the "android" command (inside the tools/ folder) is added to your PATH.';
+    return tryCommand('android list targets', msg)
+    .then(function(output) {
         if (!output.match(valid_target)) {
-            return Q.reject(new Error('Please install Android target ' + valid_target.split('-')[1] + ' (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools.'));
-        }
-        return Q();
-    }, function(stderr) {
-        if (stderr.match(/command\snot\sfound/) || stderr.match(/is not recognized as an internal or external command/)) {
-            return Q.reject(new Error('The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) is added to your path.'));
-        } else {
-            return Q.reject(new Error('An error occurred while listing Android targets. Error: ' + stderr ));
+            return Q.reject(new Error('Please install Android target ' + valid_target.split('-')[1] +
+                ' (the Android newest SDK). Make sure you have the latest Android tools installed as well.' +
+                ' Run "android" from your command-line to install/update any missing SDKs or tools.'));
         }
     });
 }

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4319447c/bin/lib/create.js
----------------------------------------------------------------------
diff --git a/bin/lib/create.js b/bin/lib/create.js
index b2490f2..7834581 100755
--- a/bin/lib/create.js
+++ b/bin/lib/create.js
@@ -196,7 +196,7 @@ exports.createProject = function(project_path, package_name, project_name, proje
     })
     // Check that requirements are met and proper targets are installed
     .then(function() {
-        check_reqs.run();
+        return check_reqs.run();
     }).then(function() {
         // Log the given values for the project
         console.log('Creating Cordova project for the Android platform:');

http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4319447c/bin/templates/cordova/build
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/build b/bin/templates/cordova/build
index a38f3b6..2d58901 100755
--- a/bin/templates/cordova/build
+++ b/bin/templates/cordova/build
@@ -28,9 +28,9 @@ if(args[2] == '--help' || args[2] == '/?' || args[2] == '-h' ||
                     args[2] == 'help' || args[2] == '-help' || args[2] == '/help') {
     build.help();
 } else {
-    reqs.run().then(function() {
+    reqs.run().done(function() {
         return build.run(args[2]);
-    }).done(null, function(err) {
+    }, function(err) {
         console.error(err);
         process.exit(2);
     });