You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2013/07/11 23:50:08 UTC

[08/43] git commit: Most console.logs should be removed in favour of events now. Hooked it up properly to cli shim.

Most console.logs should be removed in favour of events now. Hooked it up properly to cli shim.


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

Branch: refs/heads/plugman-registry
Commit: ab34d898066052f42402a433097acc3379b884cd
Parents: ce7a21e
Author: Fil Maj <ma...@gmail.com>
Authored: Wed Jul 3 10:12:34 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Wed Jul 3 10:13:40 2013 -0700

----------------------------------------------------------------------
 doc/help.txt               |  5 ++++
 main.js                    |  3 ++
 spec/install.spec.js       |  5 ++--
 spec/util/plugins.spec.js  | 38 ++++++++++--------------
 src/install.js             | 15 ++++++----
 src/prepare.js             |  5 ++++
 src/uninstall.js           | 14 ++++-----
 src/util/action-stack.js   | 14 +++++++--
 src/util/config-changes.js |  1 +
 src/util/plugins.js        | 66 ++++++++++++++++++++++-------------------
 10 files changed, 94 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/doc/help.txt
----------------------------------------------------------------------
diff --git a/doc/help.txt b/doc/help.txt
index 3a45a73..412b3ba 100644
--- a/doc/help.txt
+++ b/doc/help.txt
@@ -28,3 +28,8 @@ Optional parameters
 
  - www <directory>: www assets for the plugin will be installed into this directory. Default is to install into the standard www directory for the platform specified
  - plugins_dir <directory>: a copy of the plugin will be stored in this directory. Default is to install into the <project directory>/plugins folder
+
+Optional flags
+--------------
+
+ --debug : Verbose mode

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/main.js
----------------------------------------------------------------------
diff --git a/main.js b/main.js
index 159f97e..262c264 100755
--- a/main.js
+++ b/main.js
@@ -60,9 +60,12 @@ process.on('uncaughtException', function(error){
     process.exit(1);
 });
 
+// Set up appropriate logging based on events
 if (cli_opts.debug) {
     plugman.on('log', console.log);
 }
+plugman.on('warn', console.warn);
+plugman.on('error', console.error);
 
 if (cli_opts.v) {
     console.log(package.name + ' version ' + package.version);

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/spec/install.spec.js
----------------------------------------------------------------------
diff --git a/spec/install.spec.js b/spec/install.spec.js
index 644834a..f51d92a 100644
--- a/spec/install.spec.js
+++ b/spec/install.spec.js
@@ -8,6 +8,7 @@ var install = require('../src/install'),
     path    = require('path'),
     shell   = require('shelljs'),
     semver  = require('semver'),
+    events = require('../src/events'),
     temp    = __dirname,
     dummyplugin = 'DummyPlugin',
     dummy_id = 'com.phonegap.plugins.dummyplugin',
@@ -50,7 +51,7 @@ describe('install', function() {
             expect(add_to_queue).toHaveBeenCalledWith(plugins_dir, 'DummyPlugin', 'android', {}, true);
         });
         it('should notify if plugin is already installed into project', function() {
-            var spy = spyOn(console, 'log');
+            var spy = spyOn(events, 'emit');
             get_json.andReturn({
                 installed_plugins:{
                     'com.phonegap.plugins.dummyplugin':{}
@@ -58,7 +59,7 @@ describe('install', function() {
                 dependent_plugins:{}
             });
             install('android', temp, dummyplugin, plugins_dir, {});
-            expect(spy).toHaveBeenCalledWith('Plugin "'+dummy_id+'" already installed, \'sall good.');
+            expect(spy).toHaveBeenCalledWith('log', 'Plugin "'+dummy_id+'" already installed, \'sall good.');
         });
         it('should check version if plugin has engine tag', function(){
             var spy = spyOn(semver, 'satisfies').andReturn(true);

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/spec/util/plugins.spec.js
----------------------------------------------------------------------
diff --git a/spec/util/plugins.spec.js b/spec/util/plugins.spec.js
index 8f217cf..6653819 100644
--- a/spec/util/plugins.spec.js
+++ b/spec/util/plugins.spec.js
@@ -28,22 +28,24 @@ var http   = require('http'),
 
 describe('plugins utility module', function(){
     describe('clonePluginGitRepo', function(){
-        it('should shell out to git clone with correct arguments', function(){
-            var execSpy = spyOn(shell, 'exec').andReturn({
-                code: 0,
-                output: 'git output'
+        var fake_id = 'VillageDrunkard';
+        var execSpy, cp_spy, xml_spy;
+        beforeEach(function() {
+            execSpy = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
+                cb(0, 'git output');
             });
-            var fake_id = 'fake.plugin.id';
-            var xml = {
-                getroot: function() {
-                    return { attrib: { id: fake_id } };
+            spyOn(shell, 'which').andReturn(true);
+            cp_spy = spyOn(shell, 'cp');
+            xml_spy = spyOn(xml_helpers, 'parseElementtreeSync').andReturn({
+                getroot:function() {
+                    return {
+                        attrib:{id:fake_id}
+                    };
                 }
-            };
-
-            spyOn(xml_helpers, 'parseElementtreeSync').andReturn(xml);
-            spyOn(shell, 'cp');
+            });
+        });
+        it('should shell out to git clone with correct arguments', function(){
             var plugin_git_url = 'https://github.com/imhotep/ChildBrowser'
-
             var callback = jasmine.createSpy();
 
             plugins.clonePluginGitRepo(plugin_git_url, temp, '.', undefined, callback);
@@ -57,16 +59,6 @@ describe('plugins utility module', function(){
             expect(callback.mostRecentCall.args[1]).toMatch(new RegExp('/' + fake_id + '$'));
         });
         it('should take into account subdirectory argument when copying over final repository into plugins+plugin_id directory', function() {
-            var exec_spy = spyOn(shell, 'exec').andReturn({ code: 0, output: 'git clone output' });
-            var cp_spy = spyOn(shell, 'cp');
-            var fake_id = 'VillageDrunkard';
-            var xml_spy = spyOn(xml_helpers, 'parseElementtreeSync').andReturn({
-                getroot:function() {
-                    return {
-                        attrib:{id:fake_id}
-                    };
-                }
-            });
             var plugin_git_url = 'https://github.com/imhotep/ChildBrowser'
             
             var fake_subdir = 'TheBrainRecoilsInHorror';

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/install.js
----------------------------------------------------------------------
diff --git a/src/install.js b/src/install.js
index 179d228..e07b973 100644
--- a/src/install.js
+++ b/src/install.js
@@ -2,6 +2,7 @@ var path = require('path'),
     fs   = require('fs'),
     et   = require('elementtree'),
     n    = require('ncallbacks'),
+    events = require('./events'),
     action_stack = require('./util/action-stack'),
     shell = require('shelljs'),
     semver = require('semver'),
@@ -71,6 +72,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
       , filtered_variables = {};
     var name         = plugin_et.findall('name').text;
     var plugin_id    = plugin_et.getroot().attrib['id'];
+    events.emit('log', 'Starting installation of "' + plugin_id + '"...');
 
     // check if platform has plugin installed already.
     var platform_config = config_changes.get_platform_json(plugins_dir, platform);
@@ -87,7 +89,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
         }
     });
     if (is_installed) {
-        console.log('Plugin "' + plugin_id + '" already installed, \'sall good.');
+        events.emit('log', 'Plugin "' + plugin_id + '" already installed, \'sall good.');
         if (callback) callback();
         return;
     }
@@ -121,7 +123,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
             });
         }
     } else {
-        console.log('Warning: cordova version not detected. installing anyway.');
+        events.emit('log', 'Cordova project version not detected (lacks a ./cordova/version script), continuing.');
     }
 
     // checking preferences, if certain variables are not provided, we should throw.
@@ -146,6 +148,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
     // Check for dependencies, (co)recurse to install each one
     var dependencies = plugin_et.findall('dependency');
     if (dependencies && dependencies.length) {
+        events.emit('log', 'Dependencies detected, iterating through them...');
         var end = n(dependencies.length, function() {
             handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, options.www_dir, options.is_top_level, callback);
         });
@@ -201,7 +204,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
 
             var dep_plugin_dir = path.join(plugins_dir, dep_plugin_id);
             if (fs.existsSync(dep_plugin_dir)) {
-                console.log('Dependent plugin ' + dep_plugin_id + ' already fetched, using that version.');
+                events.emit('log', 'Dependent plugin "' + dep_plugin_id + '" already fetched, using that version.');
                 var opts = {
                     cli_variables: filtered_variables,
                     www_dir: options.www_dir,
@@ -209,7 +212,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
                 };
                 runInstall(actions, platform, project_dir, dep_plugin_dir, plugins_dir, opts, end);
             } else {
-                console.log('Dependent plugin ' + dep_plugin_id + ' not fetched, retrieving then installing.');
+                events.emit('log', 'Dependent plugin "' + dep_plugin_id + '" not fetched, retrieving then installing.');
                 var opts = {
                     cli_variables: filtered_variables,
                     www_dir: options.www_dir,
@@ -232,7 +235,7 @@ function runInstall(actions, platform, project_dir, plugin_dir, plugins_dir, opt
 }
 
 function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, plugin_basename, plugin_dir, filtered_variables, www_dir, is_top_level, callback) {
-    console.log('Installing plugin ' + plugin_id + '...');
+    events.emit('log', 'Installing plugin ' + plugin_id + '...');
     var handler = platform_modules[platform];
     www_dir = www_dir || handler.www_dir(project_dir);
 
@@ -292,7 +295,7 @@ function handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plu
             // call prepare after a successful install
             require('./../plugman').prepare(project_dir, platform, plugins_dir);
 
-            console.log(plugin_id + ' installed.');
+            events.emit('log', plugin_id + ' installed.');
             if (callback) callback();
         }
     });

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/prepare.js
----------------------------------------------------------------------
diff --git a/src/prepare.js b/src/prepare.js
index 969c73e..a608dcc 100644
--- a/src/prepare.js
+++ b/src/prepare.js
@@ -18,6 +18,7 @@
 */
 
 var platform_modules = require('./platforms'),
+    events          = require('./events'),
     path            = require('path'),
     config_changes  = require('./util/config-changes'),
     xml_helpers     = require('./util/xml-helpers'),
@@ -42,6 +43,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir) {
     // - Write this object into www/cordova_plugins.json.
     // - Cordova.js contains code to load them at runtime from that file.
 
+    events.emit('log', 'Preparing ' + platform + ' project, starting with processing of config changes...');
     config_changes.process(plugins_dir, project_dir, platform);
 
     var wwwDir = platform_modules[platform].www_dir(project_dir);
@@ -52,6 +54,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir) {
 
     // This array holds all the metadata for each module and ends up in cordova_plugins.json
     var moduleObjects = [];
+    events.emit('log', 'Iterating over installed plugins...');
 
     plugins && plugins.forEach(function(plugin) {
         var pluginDir = path.join(plugins_dir, plugin);
@@ -121,6 +124,7 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir) {
         }
     });
 
+    events.emit('log', 'Writing out cordova_plugins.json...');
     // Write out moduleObjects as JSON to cordova_plugins.json
     fs.writeFileSync(path.join(wwwDir, 'cordova_plugins.json'), JSON.stringify(moduleObjects), 'utf-8');
     // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
@@ -128,5 +132,6 @@ module.exports = function handlePrepare(project_dir, platform, plugins_dir) {
     var final_contents = "cordova.define('cordova/plugin_list', function(require, exports, module) {\n";
     final_contents += 'module.exports = ' + JSON.stringify(moduleObjects) + '\n';
     final_contents += '});';
+    events.emit('log', 'Writing out cordova_plugins.js...');
     fs.writeFileSync(path.join(wwwDir, 'cordova_plugins.js'), final_contents, 'utf-8');
 };

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/uninstall.js
----------------------------------------------------------------------
diff --git a/src/uninstall.js b/src/uninstall.js
index 575012d..5cb807b 100644
--- a/src/uninstall.js
+++ b/src/uninstall.js
@@ -6,6 +6,7 @@ var path = require('path'),
     xml_helpers = require('./util/xml-helpers'),
     action_stack = require('./util/action-stack'),
     n = require('ncallbacks'),
+    events = require('./events'),
     dependencies = require('./util/dependencies'),
     underscore = require('underscore'),
     platform_modules = require('./platforms');
@@ -14,18 +15,16 @@ var path = require('path'),
 module.exports = function uninstallPlugin(platform, project_dir, id, plugins_dir, options, callback) {
     if (!platform_modules[platform]) {
         var err = new Error(platform + " not supported.");
-        if (callback) callback(err);
+        if (callback) return callback(err);
         else throw err;
-        return;
     }
 
     var plugin_dir = path.join(plugins_dir, id);
 
     if (!fs.existsSync(plugin_dir)) {
         var err = new Error('Plugin "' + id + '" not found. Already uninstalled?');
-        if (callback) callback(err);
+        if (callback) return callback(err);
         else throw err;
-        return;
     }
 
     var current_stack = new action_stack();
@@ -53,9 +52,8 @@ function runUninstall(actions, platform, project_dir, plugin_dir, plugins_dir, o
             var ds = graph.getChain(tlp);
             if (options.is_top_level && ds.indexOf(plugin_id) > -1) {
                 var err = new Error('Another top-level plugin (' + tlp + ') relies on plugin ' + plugin_id + ', therefore aborting uninstallation.');
-                if (callback) callback(err);
+                if (callback) return callback(err);
                 else throw err;
-                return;
             }
             diff_arr.push(ds);
         }
@@ -65,6 +63,7 @@ function runUninstall(actions, platform, project_dir, plugin_dir, plugins_dir, o
     diff_arr.unshift(dependents);
     var danglers = underscore.difference.apply(null, diff_arr);
     if (dependents.length && danglers && danglers.length) {
+        events.emit('log', 'Uninstalling ' + danglers.length + ' dangling dependent plugins...');
         var end = n(danglers.length, function() {
             handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, options.www_dir, plugins_dir, plugin_dir, options.is_top_level, callback);
         });
@@ -88,6 +87,7 @@ function handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, w
     var handler = platform_modules[platform];
     var platformTag = plugin_et.find('./platform[@name="'+platform+'"]');
     www_dir = www_dir || handler.www_dir(project_dir);
+    events.emit('log', 'Uninstalling ' + plugin_id + '...');
 
     var assets = plugin_et.findall('./asset');
     if (platformTag) {
@@ -134,7 +134,7 @@ function handleUninstall(actions, platform, plugin_id, plugin_et, project_dir, w
             require('./../plugman').prepare(project_dir, platform, plugins_dir);
             // axe the directory
             shell.rm('-rf', plugin_dir);
-            console.log(plugin_id + ' uninstalled.');
+            events.emit('log', plugin_id + ' uninstalled.');
             if (callback) callback();
         }
     });

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/util/action-stack.js
----------------------------------------------------------------------
diff --git a/src/util/action-stack.js b/src/util/action-stack.js
index 4643e8d..19602fb 100644
--- a/src/util/action-stack.js
+++ b/src/util/action-stack.js
@@ -1,6 +1,7 @@
 var ios = require('../platforms/ios'),
     wp7 = require('../platforms/wp7'),
     wp8 = require('../platforms/wp8'),
+    events = require('../events'),
     fs = require('fs');
 
 function ActionStack() {
@@ -25,15 +26,19 @@ ActionStack.prototype = {
         this.stack.push(tx);
     },
     process:function(platform, project_dir, callback) {
+        events.emit('log', 'Beginning processing of action stack for ' + platform + ' project...');
         var project_files;
         // parse platform-specific project files once
         if (platform == 'ios') {
+            events.emit('log', 'Parsing iOS project files...');
             project_files = ios.parseIOSProjectFiles(project_dir);
         }
         if (platform == 'wp7') {
+            events.emit('log', 'Parsing WP7 project files...');
             project_files = wp7.parseWP7ProjectFile(project_dir);
         }
         if (platform == 'wp8') {
+            events.emit('log', 'Parsing WP8 project files...');
             project_files = wp8.parseWP8ProjectFile(project_dir);
         } 
         while(this.stack.length) {
@@ -44,6 +49,7 @@ ActionStack.prototype = {
             try {
                 handler.apply(null, action_params);
             } catch(e) {
+                events.emit('warn', 'Error during processing of action! Attempting to revert...');
                 var incomplete = this.stack.unshift(action);
                 var issue = 'Uh oh!\n';
                 // revert completed tasks
@@ -55,22 +61,24 @@ ActionStack.prototype = {
                     try {
                         revert.apply(null, revert_params);
                     } catch(err) {
+                        events.emit('warn', 'Error during reversion of action! We probably really messed up your project now, sorry! D:');
                         issue += 'A reversion action failed: ' + err.message + '\n';
                     }
                 }
-                console.log(e.stack);
                 e.message = issue + e.message;
-                if (callback) callback(e);
+                if (callback) return callback(e);
                 else throw e;
-                return;
             }
             this.completed.push(action);
         }
+        events.emit('log', 'Action stack processing complete.');
         if (platform == 'ios') {
             // write out xcodeproj file
+            events.emit('log', 'Writing out iOS pbxproj file...');
             fs.writeFileSync(project_files.pbx, project_files.xcode.writeSync());
         }
         if (platform == 'wp7') {
+            events.emit('log', 'Writing out WP7 project files...');
             project_files.write();
         }
         if (callback) callback();

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/util/config-changes.js
----------------------------------------------------------------------
diff --git a/src/util/config-changes.js b/src/util/config-changes.js
index 4a4d7ac..c49c705 100644
--- a/src/util/config-changes.js
+++ b/src/util/config-changes.js
@@ -23,6 +23,7 @@ var fs   = require('fs'),
     plist = require('plist'),
     bplist = require('bplist-parser'),
     et   = require('elementtree'),
+    events = require('../events'),
     xml_helpers = require('./../util/xml-helpers'),
     plist_helpers = require('./../util/plist-helpers');
 

http://git-wip-us.apache.org/repos/asf/cordova-plugman/blob/ab34d898/src/util/plugins.js
----------------------------------------------------------------------
diff --git a/src/util/plugins.js b/src/util/plugins.js
index 07c5d95..706d352 100644
--- a/src/util/plugins.js
+++ b/src/util/plugins.js
@@ -1,4 +1,3 @@
-#!/usr/bin/env node
 /*
  *
  * Copyright 2013 Anis Kadri
@@ -25,6 +24,7 @@ var http = require('http'),
     util = require('util'),
     shell = require('shelljs'),
     xml_helpers = require('./xml-helpers'),
+    events = require('../events'),
     tmp_dir = path.join(os.tmpdir(), 'plugman-tmp');
 
 module.exports = {
@@ -33,7 +33,7 @@ module.exports = {
     clonePluginGitRepo:function(plugin_git_url, plugins_dir, subdir, git_ref, callback) {
         if(!shell.which('git')) {
             var err = new Error('git command line is not installed');
-            if (callback) callback(err);
+            if (callback) return callback(err);
             else throw err;
         }
 
@@ -41,39 +41,43 @@ module.exports = {
 
         shell.cd(path.dirname(tmp_dir));
         var cmd = util.format('git clone "%s" "%s"', plugin_git_url, path.basename(tmp_dir));
-        var result = shell.exec(cmd, {silent: true, async:false});
-        if (result.code > 0) {
-            var err = new Error('failed to get the plugin via git from URL '+ plugin_git_url + ', output: ' + result.output);
-            if (callback) callback(err)
-            else throw err;
-        } else {
-            console.log('Plugin "' + plugin_git_url + '" fetched.');
-            // Check out the specified revision, if provided.
-            if (git_ref) {
-                var cmd = util.format('cd "%s" && git checkout "%s"', tmp_dir, git_ref);
-                var result = shell.exec(cmd, { silent: true, async:false });
-                if (result.code > 0) {
-                    var err = new Error('failed to checkout git ref "' + git_ref + '" for plugin at git url "' + plugin_git_url + '", output: ' + result.output);
-                    if (callback) callback(err);
-                    else throw err;
+        events.emit('log', 'Fetching plugin via git-clone command: ' + cmd);
+        shell.exec(cmd, {silent: true, async:true}, function(code, output) {
+            if (code > 0) {
+                var err = new Error('failed to get the plugin via git from URL '+ plugin_git_url + ', output: ' + output);
+                if (callback) return callback(err)
+                else throw err;
+            } else {
+                events.emit('log', 'Plugin "' + plugin_git_url + '" fetched.');
+                // Check out the specified revision, if provided.
+                if (git_ref) {
+                    var cmd = util.format('cd "%s" && git checkout "%s"', tmp_dir, git_ref);
+                    var result = shell.exec(cmd, { silent: true, async:false });
+                    if (result.code > 0) {
+                        var err = new Error('failed to checkout git ref "' + git_ref + '" for plugin at git url "' + plugin_git_url + '", output: ' + result.output);
+                        if (callback) return callback(err);
+                        else throw err;
+                    }
+                    events.emit('log', 'Plugin "' + plugin_git_url + '" checked out to git ref "' + git_ref + '".');
                 }
-                console.log('Checked out ' + git_ref);
-            }
 
-            // Read the plugin.xml file and extract the plugin's ID.
-            tmp_dir = path.join(tmp_dir, subdir);
-            // TODO: what if plugin.xml does not exist?
-            var xml_file = path.join(tmp_dir, 'plugin.xml');
-            var xml = xml_helpers.parseElementtreeSync(xml_file);
-            var plugin_id = xml.getroot().attrib.id;
+                // Read the plugin.xml file and extract the plugin's ID.
+                tmp_dir = path.join(tmp_dir, subdir);
+                // TODO: what if plugin.xml does not exist?
+                var xml_file = path.join(tmp_dir, 'plugin.xml');
+                var xml = xml_helpers.parseElementtreeSync(xml_file);
+                var plugin_id = xml.getroot().attrib.id;
 
-            // TODO: what if a plugin dependended on different subdirectories of the same plugin? this would fail.
-            // should probably copy over entire plugin git repo contents into plugins_dir and handle subdir seperately during install.
-            var plugin_dir = path.join(plugins_dir, plugin_id);
-            shell.cp('-R', path.join(tmp_dir, '*'), plugin_dir);
+                // TODO: what if a plugin dependended on different subdirectories of the same plugin? this would fail.
+                // should probably copy over entire plugin git repo contents into plugins_dir and handle subdir seperately during install.
+                events.emit('log', 'Copying fetched plugin over "' + plugin_dir + '"...');
+                var plugin_dir = path.join(plugins_dir, plugin_id);
+                shell.cp('-R', path.join(tmp_dir, '*'), plugin_dir);
 
-            if (callback) callback(null, plugin_dir);
-        }
+                events.emit('log', 'Plugin "' + plugin_id + '" fetched.');
+                if (callback) callback(null, plugin_dir);
+            }
+        });
     }
 };