You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2013/06/07 03:31:27 UTC

[20/22] git commit: start of serializing events/hooks

start of serializing events/hooks


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

Branch: refs/heads/2.8.x
Commit: 6d81b4d92f4dba4a453f3f513a5eca15eeb4a0f3
Parents: b7fc9df
Author: Fil Maj <ma...@gmail.com>
Authored: Thu Jun 6 10:09:57 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Thu Jun 6 18:30:24 2013 -0700

----------------------------------------------------------------------
 src/compile.js |   38 ++++++++++++++--------------
 src/hooker.js  |   70 +++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 73 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6d81b4d9/src/compile.js
----------------------------------------------------------------------
diff --git a/src/compile.js b/src/compile.js
index 8d9d217..f969624 100644
--- a/src/compile.js
+++ b/src/compile.js
@@ -26,7 +26,6 @@ var cordova_util      = require('./util'),
     events            = require('./events'),
     n                 = require('ncallbacks');
 
-
 function shell_out_to_build(projectRoot, platform, callback) {
     var cmd = '"' + path.join(projectRoot, 'platforms', platform, 'cordova', 'build') + '"';
     events.emit('log', 'Compiling platform "' + platform + '" with command "' + cmd + '" (output to follow)...');
@@ -70,25 +69,26 @@ module.exports = function compile(platformList, callback) {
     }
 
     var hooks = new hooker(projectRoot);
-    if (!(hooks.fire('before_compile'))) {
-        var err = new Error('before_compile hooks exited with non-zero code. Aborting.');
-        if (callback) callback(err);
-        else throw err;
-        return;
-    }
+    hooks.fire('before_compile', function(err) {
+        if (err) {
+            var error = new Error('before_compile hooks exited with non-zero code or caused an error: ' + err.message);
+            if (callback) callback(error);
+            else throw error;
+        } else {
+            var end = n(platformList.length, function() {
+                hooks.fire('after_compile', function(error) {
+                    if (error) {
+                        var arr = new Error('after_compile hooks exited with non-zero code. Aborting.');
+                        if (callback) callback(arr);
+                        else throw arr;
+                    } else if (callback) callback();
+                });
+            });
 
-    var end = n(platformList.length, function() {
-        if (!(hooks.fire('after_compile'))) {
-            var err = new Error('after_compile hooks exited with non-zero code. Aborting.');
-            if (callback) callback(err);
-            else throw err;
-            return;
+            // Iterate over each added platform
+            platformList.forEach(function(platform) {
+                shell_out_to_build(projectRoot, platform, end);
+            });
         }
-        if (callback) callback();
-    });
-
-    // Iterate over each added platform
-    platformList.forEach(function(platform) {
-        shell_out_to_build(projectRoot, platform, end);
     });
 };

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/6d81b4d9/src/hooker.js
----------------------------------------------------------------------
diff --git a/src/hooker.js b/src/hooker.js
index 0d51304..15c9a6c 100644
--- a/src/hooker.js
+++ b/src/hooker.js
@@ -29,25 +29,63 @@ module.exports = function hooker(root) {
 }
 
 module.exports.prototype = {
-    fire:function fire(hook) {
+    fire:function fire(hook, callback) {
+        var self = this;
         var dir = path.join(this.root, '.cordova', 'hooks', hook);
         if (!(fs.existsSync(dir))) return true; // hooks directory got axed post-create; ignore.
 
-        // Fire JS hook/event
-        events.emit(hook, this.root);
-
-        // Fire script-based hooks
-        var contents = fs.readdirSync(dir);
-        var self = this;
-        contents.forEach(function(script) {
-            var fullpath = path.join(dir, script);
-            if (fs.statSync(fullpath).isDirectory()) return; // skip directories if they're in there.
-            var command = fullpath + ' "' + self.root + '"';
-            events.emit('log', 'Executing hook "' + hook + '" (output to follow)...');
-            var status = shell.exec(command);
-            events.emit('log', status.output);
-            if (status.code !== 0) throw new Error('Script "' + path.basename(script) + '"' + 'in the ' + hook + ' hook exited with non-zero status code. Aborting.');
+        // Fire JS hook for the event
+        // These ones need to "serialize" events, that is, each handler attached to the event needs to finish processing (if it "opted in" to the callback) before the next one will fire.
+        var handlers = events.listeners(hook);
+        execute_handlers_serially(handlers, this.root, function() {
+            // Fire script-based hooks
+            var scripts = fs.readdirSync(dir);
+            execute_scripts_serially(scripts, self.root, dir, function(err) {
+                if (err) {
+                    callback(err);
+                } else {
+                    callback();
+                }
+            });
         });
-        return true;
+    }
+}
+
+function execute_scripts_serially(scripts, root, dir, callback) {
+    if (scripts.length) {
+        var s = scripts.shift();
+        var fullpath = path.join(dir, s);
+        if (fs.statSync(fullpath).isDirectory()) {
+            execute_scripts_serially(scripts, root, dir, callback); // skip directories if they're in there.
+        } else {
+            var command = fullpath + ' "' + root + '"';
+            events.emit('log', 'Executing hook "' + command + '" (output to follow)...');
+            shell.exec(command, {silent:true, async:true}, function(code, output) {
+                events.emit('log', output);
+                if (code !== 0) {
+                    callback(new Error('Script "' + fullpath + '" exited with non-zero status code. Aborting. Output: ' + output));
+                } else {
+                    execute_scripts_serially(scripts, root, dir, callback);
+                }
+            });
+        }
+    } else {
+        callback();
+    }
+}
+
+function execute_handlers_serially(handlers, root, callback) {
+    if (handlers.length) {
+        var h = handlers.shift();
+        if (h.length > 1) {
+            h(root, function() {
+                execute_handlers_serially(handlers, root, callback);
+            });
+        } else {
+            h(root);
+            execute_handlers_serially(handlers, root, callback);
+        }
+    } else {
+        callback();
     }
 }