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/05/10 01:00:32 UTC

[30/43] git commit: CB-3183 handle missing plugins directory

CB-3183 handle missing plugins directory


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

Branch: refs/heads/master
Commit: d27766874ac653fdf90a102a6314520135ecb395
Parents: ee26ee9
Author: Don Coleman <dc...@chariotsolutions.com>
Authored: Thu Apr 18 23:44:19 2013 -0400
Committer: Anis Kadri <an...@gmail.com>
Committed: Thu May 9 15:03:56 2013 -0700

----------------------------------------------------------------------
 spec/plugin.spec.js |   26 ++++++++++++
 src/plugin.js       |   95 ++++++++++++++++++++++++++++------------------
 src/util.js         |   21 ++++++----
 3 files changed, 97 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d2776687/spec/plugin.spec.js
----------------------------------------------------------------------
diff --git a/spec/plugin.spec.js b/spec/plugin.spec.js
index 12d893c..a23f9f9 100644
--- a/spec/plugin.spec.js
+++ b/spec/plugin.spec.js
@@ -61,6 +61,32 @@ describe('plugin command', function() {
         }).toThrow();
     });
 
+    describe('edge cases', function() {
+       beforeEach(function() {
+           cordova.create(tempDir);
+           process.chdir(tempDir);
+       });
+
+       afterEach(function() {
+           process.chdir(cwd);
+       });
+
+       it('should not fail when the plugins directory is missing', function() {
+           fs.rmdirSync('plugins');
+
+           expect(function() {
+               cordova.plugin();
+           }).not.toThrow();
+       });
+
+       it('should ignore files, like .gitignore, in the plugins directory', function() {
+           var someFile = path.join(tempDir, 'plugins', '.gitignore');
+           fs.writeFileSync(someFile, 'not a plugin');
+
+           expect(cordova.plugin('list')).toEqual('No plugins added. Use `cordova plugin add <plugin>`.');
+       });
+    });
+
     describe('`ls`', function() {
         beforeEach(function() {
             cordova.create(tempDir);

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d2776687/src/plugin.js
----------------------------------------------------------------------
diff --git a/src/plugin.js b/src/plugin.js
index 355157d..8997f97 100644
--- a/src/plugin.js
+++ b/src/plugin.js
@@ -24,15 +24,10 @@ var cordova_util  = require('./util'),
     shell         = require('shelljs'),
     config_parser = require('./config_parser'),
     hooker        = require('./hooker'),
+    core_platforms= require('../platforms'),
+    platform      = require('./platform'),
     plugin_parser = require('./plugin_parser'),
-    ls            = fs.readdirSync,
-    plugman       = require('plugman');
-
-var parsers = {
-    "android": require('./metadata/android_parser'),
-    "ios": require('./metadata/ios_parser'),
-    "blackberry": require('./metadata/blackberry_parser')
-};
+    ls            = fs.readdirSync;
 
 module.exports = function plugin(command, targets, callback) {
     var projectRoot = cordova_util.isCordova(process.cwd());
@@ -44,23 +39,22 @@ module.exports = function plugin(command, targets, callback) {
 
     var hooks = new hooker(projectRoot);
 
+    var projectWww = path.join(projectRoot, 'www');
+
     // Grab config info for the project
-    var xml = cordova_util.projectConfig(projectRoot);
+    var xml = path.join(projectWww, 'config.xml');
     var cfg = new config_parser(xml);
     var platforms = cordova_util.listPlatforms(projectRoot);
 
     // Massage plugin name(s) / path(s)
     var pluginPath, plugins, names = [];
     pluginPath = path.join(projectRoot, 'plugins');
-    plugins = ls(pluginPath);
-    if (targets) {
+    plugins = cordova_util.findPlugins(pluginPath);
+    if (targets) { 
         if (!(targets instanceof Array)) targets = [targets];
         targets.forEach(function(target) {
-            if (target[target.length - 1] == path.sep) {
-                target = target.substring(0, target.length - 1);
-            }
-
-            var targetName = target.substr(target.lastIndexOf(path.sep) + 1);
+            var targetName = target.substr(target.lastIndexOf('/') + 1);
+            if (targetName[targetName.length-1] == '/') targetName = targetName.substr(0, targetName.length-1);
             names.push(targetName);
         });
     }
@@ -76,25 +70,52 @@ module.exports = function plugin(command, targets, callback) {
             } else return 'No plugins added. Use `cordova plugin add <plugin>`.';
             break;
         case 'add':
+            if (platforms.length === 0) {
+                throw new Error('You need at least one platform added to your app. Use `cordova platform add <platform>`.');
+            }
             targets.forEach(function(target, index) {
-                hooks.fire('before_plugin_add');
-                var pluginsDir = path.join(projectRoot, 'plugins');
+                var pluginContents = ls(target);
+                var targetName = names[index];
+                // Check if we already have the plugin.
+                // TODO edge case: if a new platform is added, then you want
+                // to re-add the plugin to the new platform.
+                if (plugins.indexOf(targetName) > -1) {
+                    throw new Error('Plugin "' + targetName + '" already added to project.');
+                }
+                // Check if the plugin has a plugin.xml in the root of the
+                // specified dir.
+                if (pluginContents.indexOf('plugin.xml') == -1) {
+                    throw new Error('Plugin "' + targetName + '" does not have a plugin.xml in the root. Plugin must support the Cordova Plugin Specification: https://github.com/alunny/cordova-plugin-spec');
+                }
 
-                if (target[target.length - 1] == path.sep) {
-                    target = target.substring(0, target.length - 1);
+                // Check if there is at least one match between plugin
+                // supported platforms and app platforms
+                var pluginXml = new plugin_parser(path.join(target, 'plugin.xml'));
+                var intersection = pluginXml.platforms.filter(function(e) {
+                    if (platforms.indexOf(e) == -1) return false;
+                    else return true;
+                });
+                if (intersection.length === 0) {
+                    throw new Error('Plugin "' + targetName + '" does not support any of your application\'s platforms. Plugin platforms: ' + pluginXml.platforms.join(', ') + '; your application\'s platforms: ' + platforms.join(', '));
                 }
 
-                // Fetch the plugin first.
-                plugman.fetch(target, pluginsDir, false);
-                
-                // Iterate over all platforms in the project and install the plugin.
-                platforms.forEach(function(platform) {
-                    var platformRoot = path.join(projectRoot, 'platforms', platform);
-                    var parser = new parsers[platform](platformRoot);
-                    plugman.install(platform, platformRoot,
-                                    names[index], pluginsDir, {}, parser.staging_dir());
+                hooks.fire('before_plugin_add');
+
+                var cli = path.join(__dirname, '..', 'node_modules', 'plugman', 'plugman.js');
+
+                // Iterate over all matchin app-plugin platforms in the project and install the
+                // plugin.
+                intersection.forEach(function(platform) {
+                    var cmd = util.format('%s --platform %s --project "%s" --plugin "%s"', cli, platform, path.join(projectRoot, 'platforms', platform), target);
+                    var plugin_cli = shell.exec(cmd, {silent:true});
+                    if (plugin_cli.code > 0) throw new Error('An error occured during plugin installation for ' + platform + '. ' + plugin_cli.output);
                 });
 
+                // Finally copy the plugin into the project
+                var targetPath = path.join(pluginPath, targetName);
+                shell.mkdir('-p', targetPath);
+                shell.cp('-r', path.join(target, '*'), targetPath);
+
                 hooks.fire('after_plugin_add');
             });
             if (callback) callback();
@@ -110,6 +131,8 @@ module.exports = function plugin(command, targets, callback) {
                 if (plugins.indexOf(targetName) > -1) {
                     var targetPath = path.join(pluginPath, targetName);
                     hooks.fire('before_plugin_rm');
+                    var cli = path.join(__dirname, '..', 'node_modules', 'plugman', 'plugman.js');
+
                     // Check if there is at least one match between plugin
                     // supported platforms and app platforms
                     var pluginXml = new plugin_parser(path.join(targetPath, 'plugin.xml'));
@@ -118,18 +141,16 @@ module.exports = function plugin(command, targets, callback) {
                         else return true;
                     });
 
-                    // Iterate over all the common platforms between the plugin
-                    // and the app, and uninstall.
-                    // If this is a web-only plugin with no platform tags, this step
-                    // is not needed and we just --remove the plugin below.
+                    // Iterate over all matchin app-plugin platforms in the project and uninstall the
+                    // plugin.
                     intersection.forEach(function(platform) {
-                        var platformRoot = path.join(projectRoot, 'platforms', platform);
-                        var parser = new parsers[platform](platformRoot);
-                        plugman.uninstall(platform, platformRoot, targetName, path.join(projectRoot, 'plugins'), {}, parser.staging_dir());
+                        var cmd = util.format('%s --platform %s --project "%s" --plugin "%s" --remove', cli, platform, path.join(projectRoot, 'platforms', platform), targetPath);
+                        var plugin_cli = shell.exec(cmd, {silent:true});
+                        if (plugin_cli.code > 0) throw new Error('An error occured during plugin uninstallation for ' + platform + '. ' + plugin_cli.output);
                     });
 
                     // Finally remove the plugin dir from plugins/
-                    plugman.remove(targetName, path.join(projectRoot, 'plugins'));
+                    shell.rm('-rf', targetPath);
 
                     hooks.fire('after_plugin_rm');
                 } else {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/d2776687/src/util.js
----------------------------------------------------------------------
diff --git a/src/util.js b/src/util.js
index 4620e03..7ebbb17 100644
--- a/src/util.js
+++ b/src/util.js
@@ -63,13 +63,18 @@ module.exports = {
             return core_platforms.indexOf(p) > -1;
         });
     },
-    projectWww: function(projectDir) {
-        return path.join(projectDir, 'app', 'www');
-    },
-    appDir: function(projectDir) {
-        return path.join(projectDir, 'app');
-    },
-    projectConfig: function(projectDir) {
-        return path.join(projectDir, 'app', 'config.xml');
+    // list the directories in the path, ignoring any files
+    findPlugins:function(pluginPath) {
+        var plugins = [],
+            stats;
+
+        if (fs.existsSync(pluginPath)) {
+            plugins = fs.readdirSync(pluginPath).filter(function (fileName) {
+               stats = fs.statSync(path.join(pluginPath, fileName));
+               return stats.isDirectory();
+            });
+        }
+
+        return plugins;
     }
 };