You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ka...@apache.org on 2014/05/05 22:17:45 UTC

git commit: CB-5259: Print plugin versions and check deps

Repository: cordova-lib
Updated Branches:
  refs/heads/master 78a285f22 -> c8910b972


CB-5259: Print plugin versions and check deps

On `plugin ls` print out plugin versions and check whether versions specified
in dependencies are satisfied.


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

Branch: refs/heads/master
Commit: c8910b972fafae524c9e29ac5263c7822f018020
Parents: 78a285f
Author: Mark Koudritsky <ka...@gmail.com>
Authored: Mon May 5 16:15:48 2014 -0400
Committer: Mark Koudritsky <ka...@gmail.com>
Committed: Mon May 5 16:15:48 2014 -0400

----------------------------------------------------------------------
 cordova-lib/spec-cordova/PluginInfo.spec.js | 48 ++++++++++++++
 cordova-lib/spec-cordova/plugin.spec.js     |  1 -
 cordova-lib/src/PluginInfo.js               | 82 ++++++++++++++++++++++++
 cordova-lib/src/cordova/plugin.js           | 76 ++++++++++++++++------
 4 files changed, 188 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/c8910b97/cordova-lib/spec-cordova/PluginInfo.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/PluginInfo.spec.js b/cordova-lib/spec-cordova/PluginInfo.spec.js
new file mode 100644
index 0000000..4bc16bb
--- /dev/null
+++ b/cordova-lib/spec-cordova/PluginInfo.spec.js
@@ -0,0 +1,48 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+/* jshint node:true, laxcomma:true */
+/* globals describe, it, expect */
+
+var PluginInfo = require('../src/PluginInfo'),
+    path = require('path');
+
+var pluginsDir = path.join(__dirname, 'fixtures', 'plugins');
+
+describe('PluginInfo', function () {
+    it('should read a plugin.xml file', function () {
+        var p;
+        expect(function () {
+            p = new PluginInfo.PluginInfo(path.join(pluginsDir, 'ChildBrowser'));
+        }).not.toThrow();
+        expect(p).toBeDefined();
+        expect(p.name).toEqual('Child Browser');
+    });
+    it('should throw when there is no plugin.xml file', function () {
+        expect(function () {
+            var p = new PluginInfo.PluginInfo('/non/existent/dir');
+        }).toThrow();
+    });
+    describe('loadPluginsDir', function () {
+        it('should load all plugins in a dir', function () {
+            var plugins = PluginInfo.loadPluginsDir(pluginsDir);
+            expect(plugins.length).not.toBe(0);
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/c8910b97/cordova-lib/spec-cordova/plugin.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/plugin.spec.js b/cordova-lib/spec-cordova/plugin.spec.js
index dab2d2b..c2abb3d 100644
--- a/cordova-lib/spec-cordova/plugin.spec.js
+++ b/cordova-lib/spec-cordova/plugin.spec.js
@@ -49,7 +49,6 @@ describe('plugin end-to-end', function() {
             return cordova.raw.plugin('ls');
         }).then(function() {
             expect(results).toContain(pluginId);
-            expect(results.length).toEqual(1);
         }).then(function() {
             // And now remove it.
             return cordova.raw.plugin('rm', pluginId);

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/c8910b97/cordova-lib/src/PluginInfo.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/PluginInfo.js b/cordova-lib/src/PluginInfo.js
new file mode 100644
index 0000000..09cc517
--- /dev/null
+++ b/cordova-lib/src/PluginInfo.js
@@ -0,0 +1,82 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+/*
+A class for holidng the information currently stored in plugin.xml
+It should also be able to answer questions like whether the plugin
+is compatible with a given engine version.
+
+For now it's a stub to be gradually extended.
+TODO (kamrik): refactor this to use no fs sync fnctions and return promises.
+*/
+
+/* jshint node:true, laxcomma:true  */
+
+var path = require('path'),
+    fs = require('fs'),
+    _ = require('underscore'),
+    xml_helpers = require('./cordova/xml-helpers');
+
+// Exports
+exports.PluginInfo = PluginInfo;
+exports.loadPluginsDir = loadPluginsDir;
+
+
+function PluginInfo(dirname) {
+    var self = this;
+
+    var filepath = path.join(dirname, 'plugin.xml');
+    if (!fs.existsSync(filepath)) {
+        throw new Error('Could not find plugin info in ' + dirname);
+    }
+
+    self.path = dirname;
+    var et = self._et = xml_helpers.parseElementtreeSync(filepath);
+    self.id = et.getroot().attrib.id;
+    self.version = et.getroot().attrib.version;
+
+    self.name = et.find('name').text;
+    self.deps = {};
+    et.findall('dependency').forEach(function (d) {
+        self.deps[d.attrib.id] = _.clone(d.attrib);
+        // If version is not specified we want '' as default.
+        // semver.satisifies(x, '') -> true.
+        self.deps[d.attrib.id].version = self.deps[d.attrib.id].version || '';
+    });
+}
+
+
+// Given a dir containing multiple plugins, create a PluginInfo objec for
+// each of them and return as array.
+// Should load them all in parallel and return a promise, but not yet.
+function loadPluginsDir(dirname) {
+    if ( !fs.existsSync(dirname) ){
+        return [];
+    }
+    var subdirs = fs.readdirSync(dirname);
+    var plugins = [];
+    subdirs.forEach(function (subdir) {
+        var d = path.join(dirname, subdir);
+        if (!fs.existsSync(path.join(d, 'plugin.xml')))
+            return; // continue
+        var p = new PluginInfo(d);
+        plugins.push(p);
+    });
+    return plugins;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/c8910b97/cordova-lib/src/cordova/plugin.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/plugin.js b/cordova-lib/src/cordova/plugin.js
index 1ed35e7..d488e1e 100644
--- a/cordova-lib/src/cordova/plugin.js
+++ b/cordova-lib/src/cordova/plugin.js
@@ -17,16 +17,20 @@
     under the License.
 */
 
+/* jshint node: true */
+
+var cordova_util  = require('./util'),
+    path          = require('path'),
+    semver        = require('semver'),
+    hooker        = require('./hooker'),
+    config        = require('./config'),
+    Q             = require('q'),
+    CordovaError  = require('../CordovaError'),
+    PluginInfo    = require('../PluginInfo'),
+    events        = require('./events');
+
 // Returns a promise.
 module.exports = function plugin(command, targets, opts) {
-    var cordova_util  = require('./util'),
-        path          = require('path'),
-        hooker        = require('./hooker'),
-        config        = require('./config'),
-        Q             = require('q'),
-        CordovaError  = require('../CordovaError'),
-        events        = require('./events');
-
     var projectRoot = cordova_util.cdProjectRoot(),
         err;
 
@@ -193,18 +197,54 @@ module.exports = function plugin(command, targets, opts) {
             }).then(function() {
                 return hooks.fire('after_plugin_search');
             });
-            break;
         case 'ls':
         case 'list':
         default:
-            return hooks.fire('before_plugin_ls')
-            .then(function() {
-                events.emit('results', (plugins.length ? plugins : 'No plugins added. Use `cordova plugin add <plugin>`.'));
-                return hooks.fire('after_plugin_ls')
-                .then(function() {
-                    return plugins;
-                });
-            });
-            break;
+            return list(projectRoot, hooks);
     }
 };
+
+function list(projectRoot, hooks) {
+    var pluginsList = [];
+    return hooks.fire('before_plugin_ls')
+    .then(function() {
+        var pluginsDir = path.join(projectRoot, 'plugins');
+        return PluginInfo.loadPluginsDir(pluginsDir);
+    })
+    .then(function(plugins) {
+        if (plugins.length === 0) {
+            events.emit('results', 'No plugins added. Use `cordova plugin add <plugin>`.');
+            return;
+        }
+        var pluginsDict = {};
+        var lines = [];
+        var txt, p;
+        for (var i=0; i<plugins.length; i++) {
+            p = plugins[i];
+            pluginsDict[p.id] = p;
+            pluginsList.push(p.id);
+            txt = p.id + ' ' + p.version + ' "' + p.name + '"';
+            lines.push(txt);
+        }
+        // Add warnings for deps with wrong versions.
+        for (var id in pluginsDict) {
+            p = pluginsDict[id];
+            for (var depId in p.deps) {
+                var dep = pluginsDict[depId];
+                if (!semver.satisfies(dep.version, p.deps[depId].version)) {
+                    txt = 'WARNING, broken dependency: plugin ' + id +
+                          ' depends on ' + depId + ' ' + p.deps[depId].version +
+                          ' but installed version is ' + dep.version;
+                    lines.push(txt);
+                }
+            }
+        }
+        events.emit('results', lines.join('\n'));
+    })
+    .then(function() {
+        return hooks.fire('after_plugin_ls');
+    })
+    .then(function() {
+        return pluginsList;
+    });
+}