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/12 19:16:08 UTC

[52/56] [abbrv] git commit: added ability to specify custom locations for libraries. added before + after_library_download, and progress event for lib downloads via library_download

added ability to specify custom locations for libraries. added before + after_library_download, and progress event for lib downloads via library_download


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

Branch: refs/heads/lazy
Commit: c5e56f7defd22a03413016b768cd67d8000d9bda
Parents: c23c847
Author: Fil Maj <ma...@gmail.com>
Authored: Tue Jun 11 15:51:36 2013 -0700
Committer: Fil Maj <ma...@gmail.com>
Committed: Wed Jun 12 10:14:53 2013 -0700

----------------------------------------------------------------------
 cordova.js       |   1 +
 platforms.js     |  13 ++--
 src/config.js    |  54 +++++++++++++++
 src/create.js    |  88 ++++++++++++++++++-------
 src/hooker.js    |   9 +++
 src/lazy_load.js | 179 +++++++++++++++++++++++++++++++-------------------
 src/util.js      |   2 +-
 7 files changed, 250 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/cordova.js
----------------------------------------------------------------------
diff --git a/cordova.js b/cordova.js
index 35b8134..94d5aec 100644
--- a/cordova.js
+++ b/cordova.js
@@ -36,6 +36,7 @@ var emit = function() {
 
 module.exports = {
     help:      require('./src/help'),
+    config:    require('./src/config'),
     create:    require('./src/create'),
     platform:  platform,
     platforms: platform,

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/platforms.js
----------------------------------------------------------------------
diff --git a/platforms.js b/platforms.js
index d41abd3..7d894b4 100644
--- a/platforms.js
+++ b/platforms.js
@@ -20,22 +20,25 @@
 module.exports = {
     'ios' : {
         parser : require('./src/metadata/ios_parser'),
-        url    : 'https://git-wip-us.apache.org/repos/asf/cordova-ios.git'
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git'
     }, 
     'android' : {
         parser : require('./src/metadata/android_parser'),
-        url    : 'https://git-wip-us.apache.org/repos/asf/cordova-ios.git'
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-ios.git'
     }, 
     'wp7' : {
         parser : require('./src/metadata/wp7_parser'),
-        url    : 'https://git-wip-us.apache.org/repos/asf/cordova-wp7.git'
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp7.git'
     },
     'wp8' : {
         parser : require('./src/metadata/wp8_parser'),
-        url    : 'https://git-wip-us.apache.org/repos/asf/cordova-wp8.git'
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-wp8.git'
     },
     blackberry : {
         parser : require('./src/metadata/blackberry_parser'),
-        url    : 'https://git-wip-us.apache.org/repos/asf/cordova-blackberry.git'
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-blackberry.git'
+    },
+    'www':{
+        url    : 'https://git-wip-us.apache.org/repos/asf?p=cordova-app-hello-world.git'
     }
 };

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/src/config.js
----------------------------------------------------------------------
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 0000000..fb0a59b
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,54 @@
+/**
+    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 path          = require('path'),
+    fs            = require('fs'),
+    shell         = require('shelljs'),
+    events        = require('./events'),
+    util          = require('./util');
+
+module.exports = function config(project_root, opts) {
+    var json = module.exports.read(project_root);
+    Object.keys(opts).forEach(function(p) {
+        json[p] = opts[p];
+    });
+    return module.exports.write(project_root, json);
+};
+
+module.exports.read = function get_config(project_root) {
+    var dotCordova = path.join(project_root, '.cordova');
+
+    if (!fs.existsSync(dotCordova)) {
+        shell.mkdir('-p', dotCordova);
+    }
+
+    var config_json = path.join(dotCordova, 'config.json');
+    if (!fs.existsSync(config_json)) {
+        return module.exports.write(project_root, {});
+    } else {
+        return JSON.parse(fs.readFileSync(config_json, 'utf-8'));
+    }
+};
+
+module.exports.write = function set_config(project_root, json) {
+    var dotCordova = path.join(project_root, '.cordova');
+    var config_json = path.join(dotCordova, 'config.json');
+    fs.writeFileSync(config_json, JSON.stringify(json), 'utf-8');
+    return json;
+};

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/src/create.js
----------------------------------------------------------------------
diff --git a/src/create.js b/src/create.js
index be9966c..6665694 100644
--- a/src/create.js
+++ b/src/create.js
@@ -22,6 +22,8 @@ var path          = require('path'),
     help          = require('./help'),
     config_parser = require('./config_parser'),
     events        = require('./events'),
+    config        = require('./config'),
+    lazy_load     = require('./lazy_load'),
     util          = require('./util');
 
 var DEFAULT_NAME = "HelloCordova",
@@ -33,18 +35,26 @@ var DEFAULT_NAME = "HelloCordova",
  * create(dir, name) - as above, but with specified name
  * create(dir, id, name) - you get the gist
  **/
-module.exports = function create (dir, id, name) {
-    if (dir === undefined) {
+module.exports = function create (dir, id, name, callback) {
+    if (arguments.length === 0) {
         return help();
     }
 
-    // Massage parameters a bit.
-    if (id && name === undefined) {
-        name = id;
-        id = undefined;
+    // Massage parameters
+    var args = Array.prototype.slice.call(arguments, 0);
+    if (typeof args[args.length-1] == 'function') {
+        callback = args.pop();
+    }
+    if (args.length === 0) {
+        dir = process.cwd();
+        id = DEFAULT_ID;
+        name = DEFAULT_NAME;
+    } else if (args.length == 1) {
+        id = DEFAULT_ID;
+        name = DEFAULT_NAME;
+    } else if (args.length == 2) {
+        name = DEFAULT_NAME;
     }
-    id = id || DEFAULT_ID;
-    name = name || DEFAULT_NAME;
 
     // Make absolute.
     dir = path.resolve(dir);
@@ -53,11 +63,6 @@ module.exports = function create (dir, id, name) {
 
     var dotCordova = path.join(dir, '.cordova');
 
-    // Check for existing cordova project
-    if (fs.existsSync(dotCordova)) {
-        throw new Error('Cordova project already exists at ' + dir + ', aborting.');
-    }
-
     // Create basic project structure.
     shell.mkdir('-p', dotCordova);
     shell.mkdir('-p', path.join(dir, 'platforms'));
@@ -93,18 +98,55 @@ module.exports = function create (dir, id, name) {
     shell.mkdir(path.join(hooks, 'before_run'));
 
     // Write out .cordova/config.json file with a simple json manifest
-    fs.writeFileSync(path.join(dotCordova, 'config.json'), JSON.stringify({
+    config(dir, {
         id:id,
         name:name
-    }));
+    });
 
-    // Copy in base template
-    events.emit('log', 'Copying stock application assets into "' + path.join(dir, 'www') + '"');
-    shell.cp('-r', path.join(__dirname, '..', 'templates', 'www'), dir);
+    // Copy in base www template
+    var config_json = config.read(dir);
+    // Check if www assets to use was overridden.
+    var www_dir = path.join(dir, 'www');
+    var finalize = function(www_lib) {
+        while (!fs.existsSync(path.join(www_lib, 'config.xml'))) {
+            www_lib = path.join(www_lib, 'www');
+            if (!fs.existsSync(www_lib)) {
+                var err = new Error('downloaded www assets in ' + www_lib + ' does not contain config.xml, or www subdir with config.xml');
+                if (callback) return callback(err);
+                else throw err;
+            }
+        }
+        shell.cp('-rf', path.join(www_lib, '*'), www_dir);
+        // Write out id and name to config.xml
+        var configPath = util.projectConfig(dir);
+        var config = new config_parser(configPath);
+        config.packageName(id);
+        config.name(name);
+        if (callback) callback();
+    };
 
-    // Write out id and name to config.xml
-    var configPath = util.projectConfig(dir);
-    var config = new config_parser(configPath);
-    config.packageName(id);
-    config.name(name);
+    if (config_json.lib && config_json.lib.www) {
+        events.emit('log', 'Using custom www assets ('+config_json.lib.www.id+').');
+        lazy_load.custom(config_json.lib.www.uri, config_json.lib.www.id, 'www', config_json.lib.www.version, function(err) {
+            if (err) {
+                if (callback) callback(err);
+                else throw err;
+            } else {
+                events.emit('log', 'Copying custom www assets into "' + www_dir + '"');
+                finalize(path.join(util.libDirectory, 'www', config_json.lib.www.id, config_json.lib.www.version));
+            }
+        });
+    } else {
+        // Nope, so use stock cordova-hello-world-app one.
+        events.emit('log', 'Using stock cordova hello-world application.');
+        lazy_load.cordova('www', function(err) {
+            if (err) {
+                if (callback) callback(err);
+                else throw err;
+            } else {
+                events.emit('log', 'Copying stock Cordova www assets into "' + www_dir + '"');
+                finalize(path.join(util.libDirectory, 'www', 'cordova', util.cordovaTag));
+            }
+        });
+    }
 };

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/src/hooker.js
----------------------------------------------------------------------
diff --git a/src/hooker.js b/src/hooker.js
index a483b8f..247385f 100644
--- a/src/hooker.js
+++ b/src/hooker.js
@@ -28,6 +28,15 @@ module.exports = function hooker(root) {
     else this.root = r;
 }
 
+module.exports.fire = function global_fire(hook, opts, callback) {
+    if (arguments.length == 2) {
+        callback = opts;
+        opts = {};
+    }
+    var handlers = events.listeners(hook);
+    execute_handlers_serially(handlers, opts, callback);
+};
+
 module.exports.prototype = {
     fire:function fire(hook, opts, callback) {
         if (arguments.length == 2) {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/src/lazy_load.js
----------------------------------------------------------------------
diff --git a/src/lazy_load.js b/src/lazy_load.js
index 8094965..f7bf15c 100644
--- a/src/lazy_load.js
+++ b/src/lazy_load.js
@@ -21,88 +21,133 @@ var path          = require('path'),
     shell         = require('shelljs'),
     platforms     = require('../platforms'),
     events        = require('./events'),
-    glob          = require('glob'),
+    hooker        = require('./hooker'),
     https         = require('follow-redirects').https,
     zlib          = require('zlib'),
     tar           = require('tar'),
+    URL           = require('url'),
     util          = require('./util');
 
-/**
- * Usage:
- **/
-module.exports = function lazy_load(platform, callback) {
-    if (!(platform in platforms)) {
-        var err = new Error('platform "' + platform + '" not recognized.');
-        if (callback) return callback(err);
-        else throw err;
-    }
+module.exports = {
+    cordova:function lazy_load(platform, callback) {
+        if (!(platform in platforms)) {
+            var err = new Error('Cordova library "' + platform + '" not recognized.');
+            if (callback) return callback(err);
+            else throw err;
+        }
 
-    if (util.has_platform_lib(platform)) {
-        events.emit('log', 'Platform library for "' + platform + '" already exists. No need to download. Continuing.');
-        return (callback ? callback() : true);
-    } else {
-        // TODO: hook in before_library_dl event
         var url = platforms[platform].url + ';a=snapshot;h=' + util.cordovaTag + ';sf=tgz';
-        var filename = path.join(util.libDirectory, 'cordova-' + platform + '-' + util.cordovaTag + '.tar.gz');
-        var req_opts = {
-            hostname: 'git-wip-us.apache.org',
-            path: '/repos/asf?p=cordova-' + platform + '.git;a=snapshot;h=' + util.cordovaTag + ';sf=tgz'
-        };
-        events.emit('log', 'Requesting ' + req_opts.hostname + req_opts.path + '...');
-        var req = https.request(req_opts, function(res) {
-            var downloadfile = fs.createWriteStream(filename, {'flags': 'a'});
-
-            res.on('data', function(chunk){
-                // TODO: hook in progress event
-                downloadfile.write(chunk, 'binary');
-                events.emit('log', 'Wrote ' + chunk.length + ' bytes...');
-            });
+        module.exports.custom(url, 'cordova', platform, util.cordovaTag, function(err) {
+            if (err) {
+                if (callback) return callback(err);
+                else throw err;
+            } else {
+                if (callback) callback();
+            }
+        });
+    },
+    custom:function(url, id, platform, version, callback) {
+        var download_dir = path.join(util.libDirectory, platform, id, version);
+        shell.mkdir('-p', download_dir);
+        if (fs.existsSync(download_dir)) {
+            events.emit('log', 'Platform library for "' + platform + '" already exists. No need to download. Continuing.');
+            if (callback) callback();
+            return;
+        }
 
-            res.on('end', function(){
-                // TODO: hook in end event
-                downloadfile.end();
-                events.emit('log', 'Download complete. Extracting...');
-                var tar_path = path.join(util.libDirectory, 'cordova-' + platform + '-' + util.cordovaTag + '.tar');
-                var tarfile = fs.createWriteStream(tar_path);
-                tarfile.on('error', function(err) {
-                    if (callback) callback(err);
-                    else throw err;
-                });
-                tarfile.on('finish', function() {
+        hooker.fire('before_library_download', {
+            platform:platform,
+            url:url,
+            id:id,
+            version:version
+        }, function() {
+            var uri = URL.parse(url);
+            if (uri.protocol) {
+                // assuming its remote
+                var filename = path.join(download_dir, id+'-'+platform+'-'+version+'.tar.gz');
+                if (fs.existsSync(filename)) {
                     shell.rm(filename);
-                    fs.createReadStream(tar_path)
-                        .pipe(tar.Extract({ path: util.libDirectory }))
-                        .on("error", function (err) {
+                }
+                var req_opts = {
+                    hostname: uri.hostname,
+                    path: uri.path
+                };
+                events.emit('log', 'Requesting ' + url + '...');
+                // TODO: may not be an https request..
+                var req = https.request(req_opts, function(res) {
+                    var downloadfile = fs.createWriteStream(filename, {'flags': 'a'});
+
+                    res.on('data', function(chunk){
+                        downloadfile.write(chunk, 'binary');
+                        hooker.fire('library_download', {
+                            platform:platform,
+                            url:url,
+                            id:id,
+                            version:version,
+                            chunk:chunk
+                        });
+                    });
+
+                    res.on('end', function(){
+                        downloadfile.end();
+                        var payload_size = fs.statSync(filename).size;
+                        events.emit('log', 'Download complete. Extracting...');
+                        var tar_path = path.join(download_dir, id+'-'+platform+'-'+version+'.tar');
+                        var tarfile = fs.createWriteStream(tar_path);
+                        tarfile.on('error', function(err) {
                             if (callback) callback(err);
                             else throw err;
-                        })
-                        .on("end", function () {
-                            shell.rm(tar_path);
-                            // rename the extracted dir to remove the trailing SHA
-                            glob(path.join(util.libDirectory, 'cordova-' + platform + '-' + util.cordovaTag + '-*'), function(err, entries) {
-                                if (err) {
-                                    if (callback) return callback(err);
+                        });
+                        tarfile.on('finish', function() {
+                            shell.rm(filename);
+                            fs.createReadStream(tar_path)
+                                .pipe(tar.Extract({ path: download_dir }))
+                                .on("error", function (err) {
+                                    if (callback) callback(err);
                                     else throw err;
-                                } else {
-                                    var entry = entries[0];
-                                    var final_dir = path.join(util.libDirectory, 'cordova-' + platform + '-' + util.cordovaTag);
-                                    shell.mkdir(final_dir);
-                                    shell.mv('-f', path.join(entry, (platform=='blackberry'?'blackberry10':''), '*'), final_dir);
+                                })
+                                .on("end", function () {
+                                    shell.rm(tar_path);
+                                    // move contents out of extracted dir
+                                    var entries = fs.readdirSync(download_dir);
+                                    var entry = path.join(download_dir, entries[0]);
+                                    shell.mv('-f', path.join(entry, (platform=='blackberry'?'blackberry10':''), '*'), download_dir);
                                     shell.rm('-rf', entry);
-                                    if (callback) callback();
-                                }
-                            });
+                                    hooker.fire('after_library_download', {
+                                        platform:platform,
+                                        url:url,
+                                        id:id,
+                                        version:version,
+                                        path:download_dir,
+                                        size:payload_size
+                                    }, function() {
+                                        if (callback) callback();
+                                    });
+                                });
                         });
+                        fs.createReadStream(filename)
+                            .pipe(zlib.createUnzip())
+                            .pipe(tarfile);
+                    });
                 });
-                fs.createReadStream(filename)
-                    .pipe(zlib.createUnzip())
-                    .pipe(tarfile);
-            });
-        });
-        req.on('error', function(err) {
-            if (callback) return callback(err);
-            else throw err;
+                req.on('error', function(err) {
+                    if (callback) return callback(err);
+                    else throw err;
+                });
+                req.end();
+            } else {
+                // local path
+                shell.cp('-rf', path.join(uri.path, '*'), download_dir);
+                hooker.fire('after_library_download', {
+                    platform:platform,
+                    url:url,
+                    id:id,
+                    version:version,
+                    path:download_dir
+                }, function() {
+                    if (callback) callback();
+                });
+            }
         });
-        req.end();
     }
 };

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/c5e56f7d/src/util.js
----------------------------------------------------------------------
diff --git a/src/util.js b/src/util.js
index d458bc2..c689340 100644
--- a/src/util.js
+++ b/src/util.js
@@ -37,7 +37,7 @@ module.exports = {
     globalConfig:global_config_path,
     libDirectory:lib_path,
     has_platform_lib:function has_platform_lib(platform) {
-        return fs.existsSync(path.join(lib_path, 'cordova-' + platform + '-' + TAG, 'bin', 'create'));
+        return fs.existsSync(path.join(lib_path, platform, 'cordova', TAG, 'bin', 'create'));
     },
     // Runs up the directory chain looking for a .cordova directory.
     // IF it is found we are in a Cordova project.