cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From purplecabb...@apache.org
Subject [3/3] git commit: Merge branch 'CB-6615' of https://github.com/MSOpenTech/cordova-plugman
Date Fri, 20 Jun 2014 21:51:17 GMT
Merge branch 'CB-6615' of https://github.com/MSOpenTech/cordova-plugman


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

Branch: refs/heads/master
Commit: aa2a04be79ef70e327d70af6f9277d2494ebd91a
Parents: 1cecf6a f658489
Author: Jesse MacFadyen <purplecabbage@gmail.com>
Authored: Fri Jun 20 14:50:30 2014 -0700
Committer: Jesse MacFadyen <purplecabbage@gmail.com>
Committed: Fri Jun 20 14:50:30 2014 -0700

----------------------------------------------------------------------
 cordova-lib/spec-plugman/fetch.spec.js | 45 +++++++++++++++++++++++++++--
 cordova-lib/src/plugman/fetch.js       | 11 +++++++
 2 files changed, 53 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/aa2a04be/cordova-lib/spec-plugman/fetch.spec.js
----------------------------------------------------------------------
diff --cc cordova-lib/spec-plugman/fetch.spec.js
index 4b9e234,0000000..8464141
mode 100644,000000..100644
--- a/cordova-lib/spec-plugman/fetch.spec.js
+++ b/cordova-lib/spec-plugman/fetch.spec.js
@@@ -1,229 -1,0 +1,268 @@@
 +/**
 +    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.
 +*/
 +var fetch   = require('../src/plugman/fetch'),
 +    fs      = require('fs'),
 +    os      = require('osenv'),
 +    path    = require('path'),
 +    shell   = require('shelljs'),
 +    xml_helpers = require('../src/util/xml-helpers'),
 +    metadata = require('../src/plugman/util/metadata'),
 +    temp    = path.join(os.tmpdir(), 'plugman'),
 +    test_plugin = path.join(__dirname, 'plugins', 'ChildBrowser'),
 +    test_plugin_with_space = path.join(__dirname, 'folder with space', 'plugins', 'ChildBrowser'),
 +    plugins = require('../src/plugman/util/plugins'),
 +    Q = require('q'),
 +    registry = require('../src/plugman/registry/registry');
 +
 +describe('fetch', function() {
 +    function wrapper(p, done, post) {
 +        p.then(post, function(err) {
 +            expect(err).toBeUndefined();
 +        }).fin(done);
 +    }
 +
 +    describe('local plugins', function() {
 +        var xml, rm, sym, mkdir, cp, save_metadata;
 +        beforeEach(function() {
 +            xml = spyOn(xml_helpers, 'parseElementtreeSync').andReturn({
-                 getroot:function() { return {attrib:{id:'id'}};}
++                getroot:function() { return {attrib:{id:'id', version:'version'}};}
 +            });
 +            rm = spyOn(shell, 'rm');
 +            sym = spyOn(fs, 'symlinkSync');
 +            mkdir = spyOn(shell, 'mkdir');
 +            cp = spyOn(shell, 'cp');
 +            save_metadata = spyOn(metadata, 'save_fetch_metadata');
 +        });
 +
 +        it('should copy locally-available plugin to plugins directory', function(done) {
 +            wrapper(fetch(test_plugin, temp), done, function() {
 +                expect(cp).toHaveBeenCalledWith('-R', path.join(test_plugin, '*'), path.join(temp,
'id'));
 +            });
 +        });
 +        it('should copy locally-available plugin to plugins directory when spaces in path',
function(done) {
 +            //XXX: added this because plugman tries to fetch from registry when plugin folder
does not exist
 +            spyOn(fs,'existsSync').andReturn(true);
 +            wrapper(fetch(test_plugin_with_space, temp), done, function() {
 +                expect(cp).toHaveBeenCalledWith('-R', path.join(test_plugin_with_space,
'*'), path.join(temp, 'id'));
 +            });
 +        });
 +        it('should create a symlink if used with `link` param', function(done) {
 +            wrapper(fetch(test_plugin, temp, { link: true }), done, function() {
 +                expect(sym).toHaveBeenCalledWith(test_plugin, path.join(temp, 'id'), 'dir');
 +            });
 +        });
 +        it('should fail when the expected ID doesn\'t match', function(done) {
 +            fetch(test_plugin, temp, { expected_id: 'wrongID' })
 +            .then(function() {
 +                expect('this call').toBe('fail');
 +            }, function(err) {
 +                expect(''+err).toContain('Expected fetched plugin to have ID "wrongID" but
got "id".');
 +            }).fin(done);
 +        });
 +        it('should succeed when the expected ID is correct', function(done) {
 +            wrapper(fetch(test_plugin, temp, { expected_id: 'id' }), done, function() {
 +                expect(1).toBe(1);
 +            });
 +        });
++        it('should fail when the expected ID with version specified doesn\'t match', function(done)
{
++            fetch(test_plugin, temp, { expected_id: 'id@wrongVersion' })
++            .then(function() {
++                expect('this call').toBe('fail');
++            }, function(err) {
++                expect(''+err).toContain('Expected fetched plugin to have ID "id@wrongVersion"
but got "id@version".');
++            }).fin(done);
++        });
++        it('should succeed when the plugin version specified is correct', function(done)
{
++            wrapper(fetch(test_plugin, temp, { expected_id: 'id@version' }), done, function()
{
++                expect(1).toBe(1);
++            });
++        });
 +    });
 +    describe('git plugins', function() {
 +        var clone, save_metadata, done, xml;
 +
 +        function fetchPromise(f) {
 +            f.then(function() { done = true; }, function(err) { done = err; });
 +        }
 +
 +        beforeEach(function() {
 +            clone = spyOn(plugins, 'clonePluginGitRepo').andReturn(Q('somedir'));
 +            save_metadata = spyOn(metadata, 'save_fetch_metadata');
 +            done = false;
 +            xml = spyOn(xml_helpers, 'parseElementtreeSync').andReturn({
-                 getroot:function() { return {attrib:{id:'id'}};}
++                getroot:function() { return {attrib:{id:'id', version:'version'}};}
 +            });
 +        });
 +        it('should call clonePluginGitRepo for https:// and git:// based urls', function()
{
 +            var url = "https://github.com/bobeast/GAPlugin.git";
 +            runs(function() {
 +                fetchPromise(fetch(url, temp));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(done).toBe(true);
 +                expect(clone).toHaveBeenCalledWith(url, temp, '.', undefined);
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should call clonePluginGitRepo with subdir if applicable', function() {
 +            var url = "https://github.com/bobeast/GAPlugin.git";
 +            var dir = 'fakeSubDir';
 +            runs(function() {
 +                fetchPromise(fetch(url, temp, { subdir: dir }));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(clone).toHaveBeenCalledWith(url, temp, dir, undefined);
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should call clonePluginGitRepo with subdir and git ref if applicable', function()
{
 +            var url = "https://github.com/bobeast/GAPlugin.git";
 +            var dir = 'fakeSubDir';
 +            var ref = 'fakeGitRef';
 +            runs(function() {
 +                fetchPromise(fetch(url, temp, { subdir: dir, git_ref: ref }));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(clone).toHaveBeenCalledWith(url, temp, dir, ref);
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should extract the git ref from the URL hash, if provided', function() {
 +            var url = "https://github.com/bobeast/GAPlugin.git#fakeGitRef";
 +            var baseURL = "https://github.com/bobeast/GAPlugin.git";
 +            runs(function() {
 +                fetchPromise(fetch(url, temp, {}));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(clone).toHaveBeenCalledWith(baseURL, temp, '.', 'fakeGitRef');
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should extract the subdir from the URL hash, if provided', function() {
 +            var url = "https://github.com/bobeast/GAPlugin.git#:fakeSubDir";
 +            var baseURL = "https://github.com/bobeast/GAPlugin.git";
 +            runs(function() {
 +                fetchPromise(fetch(url, temp, {}));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(clone).toHaveBeenCalledWith(baseURL, temp, 'fakeSubDir', undefined);
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should extract the git ref and subdir from the URL hash, if provided', function()
{
 +            var url = "https://github.com/bobeast/GAPlugin.git#fakeGitRef:/fake/Sub/Dir/";
 +            var baseURL = "https://github.com/bobeast/GAPlugin.git";
 +            runs(function() {
 +                fetchPromise(fetch(url, temp, {}));
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(clone).toHaveBeenCalledWith(baseURL, temp, 'fake/Sub/Dir', 'fakeGitRef');
 +                expect(save_metadata).toHaveBeenCalledWith('somedir', jasmine.any(Object));
 +            });
 +        });
 +        it('should throw if used with url and `link` param', function() {
 +            runs(function() {
 +                fetch("https://github.com/bobeast/GAPlugin.git", temp, {link:true}).then(null,
function(err) { done = err; });
 +            });
 +            waitsFor(function() { return done; }, 'fetch promise never resolved', 250);
 +            runs(function() {
 +                expect(''+done).toContain('--link is not supported for git URLs');
 +            });
 +        });
 +        it('should fail when the expected ID doesn\'t match', function(done) {
 +            fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id: 'wrongID'
})
 +            .then(function() {
 +                expect('this call').toBe('fail');
 +            }, function(err) {
 +                expect(''+err).toContain('Expected fetched plugin to have ID "wrongID" but
got "id".');
 +            }).fin(done);
 +        });
++        it('should fail when the expected ID with version specified doesn\'t match', function(done)
{
++            fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id: 'id@wrongVersion'
})
++            .then(function() {
++                expect('this call').toBe('fail');
++            }, function(err) {
++                expect(''+err).toContain('Expected fetched plugin to have ID "id@wrongVersion"
but got "id@version".');
++            }).fin(done);
++        });
 +        it('should succeed when the expected ID is correct', function(done) {
 +            wrapper(fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id:
'id' }), done, function() {
 +                expect(1).toBe(1);
 +            });
 +        });
++        it('should succeed when the plugin version specified is correct', function(done)
{
++            wrapper(fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id:
'id@version' }), done, function() {
++                expect(1).toBe(1);
++            });
++        });
 +    });
 +    describe('registry plugins', function() {
 +        var pluginId = 'dummyplugin', sFetch;
 +        var xml, rm, sym, mkdir, cp, save_metadata;
 +        beforeEach(function() {
 +            xml = spyOn(xml_helpers, 'parseElementtreeSync').andReturn({
-                 getroot:function() { return {attrib:{id:'id'}};}
++                getroot:function() { return {attrib:{id:'id', version:'version'}};}
 +            });
 +            rm = spyOn(shell, 'rm');
 +            sym = spyOn(fs, 'symlinkSync');
 +            mkdir = spyOn(shell, 'mkdir');
 +            cp = spyOn(shell, 'cp');
 +            save_metadata = spyOn(metadata, 'save_fetch_metadata');
 +            sFetch = spyOn(registry, 'fetch').andReturn(Q('somedir'));
 +        });
 +
 +        it('should get a plugin from registry and set the right client when argument is
not a folder nor URL', function(done) {
 +            wrapper(fetch(pluginId, temp, {client: 'plugman'}), done, function() {
 +                expect(sFetch).toHaveBeenCalledWith([pluginId], 'plugman');
 +            });
 +        });
 +        it('should fail when the expected ID doesn\'t match', function(done) {
 +            fetch(pluginId, temp, { expected_id: 'wrongID' })
 +            .then(function() {
 +                expect('this call').toBe('fail');
 +            }, function(err) {
 +                expect(''+err).toContain('Expected fetched plugin to have ID "wrongID" but
got "id".');
 +            }).fin(done);
 +        });
++        it('should fail when the expected ID with version specified doesn\'t match', function(done)
{
++            fetch(pluginId, temp, { expected_id: 'id@wrongVersion' })
++            .then(function() {
++                expect('this call').toBe('fail');
++            }, function(err) {
++                expect(''+err).toContain('Expected fetched plugin to have ID "id@wrongVersion"
but got "id@version".');
++            }).fin(done);
++        });
 +        it('should succeed when the expected ID is correct', function(done) {
 +            wrapper(fetch(pluginId, temp, { expected_id: 'id' }), done, function() {
 +                expect(1).toBe(1);
 +            });
 +        });
++        it('should succeed when the plugin version specified is correct', function(done)
{
++            wrapper(fetch(pluginId, temp, { expected_id: 'id@version' }), done, function()
{
++                expect(1).toBe(1);
++            });
++        });
 +    });
 +});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/aa2a04be/cordova-lib/src/plugman/fetch.js
----------------------------------------------------------------------
diff --cc cordova-lib/src/plugman/fetch.js
index 0292ad1,0000000..839384b
mode 100644,000000..100644
--- a/cordova-lib/src/plugman/fetch.js
+++ b/cordova-lib/src/plugman/fetch.js
@@@ -1,204 -1,0 +1,215 @@@
 +/**
 +    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, bitwise:true, undef:true, trailing:true, quotmark:true,
 +          indent:4, unused:vars, latedef:nofunc
 +*/
 +
 +var shell   = require('shelljs'),
 +    fs      = require('fs'),
 +    url     = require('url'),
 +    plugins = require('./util/plugins'),
 +    xml_helpers = require('../util/xml-helpers'),
 +    CordovaError  = require('../CordovaError'),
 +    events = require('../events'),
 +    metadata = require('./util/metadata'),
 +    path    = require('path'),
 +    Q       = require('q'),
 +    registry = require('./registry/registry');
 +// XXX: leave the require('./plugman') because jasmine shits itself if you declare it up
top
 +// possible options: link, subdir, git_ref, client, expected_id
 +// Returns a promise.
 +module.exports = function fetchPlugin(plugin_src, plugins_dir, options) {
 +    // Ensure the containing directory exists.
 +    shell.mkdir('-p', plugins_dir);
 +
 +    options = options || {};
 +    options.subdir = options.subdir || '.';
 +    options.searchpath = options.searchpath || [];
 +    if ( typeof options.searchpath === 'string' ) {
 +        options.searchpath = options.searchpath.split(path.delimiter);
 +    }
 +
 +    // clone from git repository
 +    var uri = url.parse(plugin_src);
 +
 +    // If the hash exists, it has the form from npm: http://foo.com/bar#git-ref[:subdir]
 +    // NB: No leading or trailing slash on the subdir.
 +    if (uri.hash) {
 +        var result = uri.hash.match(/^#([^:]*)(?::\/?(.*?)\/?)?$/);
 +        if (result) {
 +            if (result[1])
 +                options.git_ref = result[1];
 +            if(result[2])
 +                options.subdir = result[2];
 +
 +            // Recurse and exit with the new options and truncated URL.
 +            var new_dir = plugin_src.substring(0, plugin_src.indexOf('#'));
 +            return fetchPlugin(new_dir, plugins_dir, options);
 +        }
 +    }
 +
 +    // If it looks like a network URL, git clone it.
 +    if ( uri.protocol && uri.protocol != 'file:' && uri.protocol != 'c:'
&& !plugin_src.match(/^\w+:\\/)) {
 +        events.emit('log', 'Fetching plugin "' + plugin_src + '" via git clone');
 +        if (options.link) {
 +            return Q.reject(new CordovaError('--link is not supported for git URLs'));
 +        } else {
 +            var data = {
 +                source: {
 +                    type: 'git',
 +                    url:  plugin_src,
 +                    subdir: options.subdir,
 +                    ref: options.git_ref
 +                }
 +            };
 +
 +            return plugins.clonePluginGit(plugin_src, plugins_dir, options)
 +            .then(function(dir) {
 +                return checkID(options.expected_id, dir);
 +            })
 +            .then(function(dir) {
 +                metadata.save_fetch_metadata(dir, data);
 +                return dir;
 +            });
 +        }
 +    } else {
 +        // If it's not a network URL, it's either a local path or a plugin ID.
 +
 +        var p,  // The Q promise to be returned.
 +            linkable = true,
 +            plugin_dir = path.join(plugin_src, options.subdir);
 +
 +        if (fs.existsSync(plugin_dir)) {
 +            p = Q(plugin_dir);
 +        } else {
 +            // If there is no such local path, it's a plugin id.
 +            // First look for it in the local search path (if provided).
 +            var local_dir = findLocalPlugin(plugin_src, options.searchpath);
 +            if (local_dir) {
 +                p = Q(local_dir);
 +                events.emit('verbose', 'Found ' + plugin_src + ' at ' + local_dir);
 +            } else if ( options.noregistry ) {
 +                p = Q.reject(new CordovaError(
 +                        'Plugin ' + plugin_src + ' not found locally. ' +
 +                        'Note, plugin registry was disabled by --noregistry flag.'
 +                    ));
 +            } else {
 +                // If not found in local search path, fetch from the registry.
 +                linkable = false;
 +                events.emit('log', 'Fetching plugin "' + plugin_src + '" via plugin registry');
 +                p = registry.fetch([plugin_src], options.client);
 +            }
 +        }
 +
 +        return p
 +        .then(function(dir) {
 +                options.plugin_src_dir = dir;
 +
 +                return copyPlugin(dir, plugins_dir, options.link && linkable);
 +            })
 +        .then(function(dir) {
 +                return checkID(options.expected_id, dir);
 +            });
 +    }
 +};
 +
 +function readId(dir) {
 +    var xml_path = path.join(dir, 'plugin.xml');
 +    var et = xml_helpers.parseElementtreeSync(xml_path);
 +    var plugin_id = et.getroot().attrib.id;
 +    return plugin_id;
 +}
 +
++function readVersion(dir) {
++    var xml_path = path.join(dir, 'plugin.xml');
++    var et = xml_helpers.parseElementtreeSync(path.join(dir, 'plugin.xml'));
++    var plugin_id = et.getroot().attrib.version;
++    return plugin_id;
++}
++
 +// Helper function for checking expected plugin IDs against reality.
 +function checkID(expected_id, dir) {
 +    if ( expected_id ) {
 +        var id = readId(dir);
++        // if id with specific version provided, append version to id
++        if (expected_id.split('@').length > 1) {
++            id = id + "@" + readVersion(dir);
++        }
 +        if (expected_id != id) {
 +            throw new Error('Expected fetched plugin to have ID "' + expected_id + '" but
got "' + id + '".');
 +        }
 +    }
 +    return dir;
 +}
 +
 +var idCache = Object.create(null);
 +// Look for plugin in local search path.
 +function findLocalPlugin(plugin_id, searchpath) {
 +    function tryPath(p) {
 +        if (!(p in idCache)) {
 +            var id = null;
 +            if (fs.existsSync(path.join(p, 'plugin.xml'))) {
 +                id = readId(p);
 +            }
 +            idCache[p] = id;
 +        }
 +        return (plugin_id === idCache[p]);
 +    }
 +
 +    for (var i = 0; i < searchpath.length; i++) {
 +        // Allow search path to point right to a plugin.
 +        if (tryPath(searchpath[i])) {
 +            return searchpath[i];
 +        }
 +        var files = fs.readdirSync(searchpath[i]);
 +        for (var j = 0; j < files.length; j++) {
 +            var pluginPath = path.join(searchpath[i], files[j]);
 +            if (tryPath(pluginPath)) {
 +                return pluginPath;
 +            }
 +        }
 +    }
 +    return null;
 +}
 +
 +
 +// Copy or link a plugin from plugin_dir to plugins_dir/plugin_id.
 +function copyPlugin(plugin_dir, plugins_dir, link) {
 +    var plugin_id = readId(plugin_dir);
 +    var dest = path.join(plugins_dir, plugin_id);
 +    shell.rm('-rf', dest);
 +    if (link) {
 +        events.emit('verbose', 'Linking plugin "' + plugin_dir + '" => "' + dest + '"');
 +        fs.symlinkSync(plugin_dir, dest, 'dir');
 +    } else {
 +        shell.mkdir('-p', dest);
 +        events.emit('verbose', 'Copying plugin "' + plugin_dir + '" => "' + dest + '"');
 +        shell.cp('-R', path.join(plugin_dir, '*') , dest);
 +    }
 +
 +    var data = {
 +        source: {
 +            type: 'local',
 +            path: plugin_dir
 +        }
 +    };
 +    metadata.save_fetch_metadata(dest, data);
 +    return dest;
 +}


Mime
View raw message