Repository: cordova-lib
Updated Branches:
  refs/heads/master b82ee86c3 -> 5c8b4cac0


CB-11985 Check if cached platform/plugin exists before 'npm cache'

This avoids unnecessary npm call with long timeout if not connected to the 
internet.


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

Branch: refs/heads/master
Commit: 5c8b4cac007c21703e182978a403e67a752a9bd2
Parents: b82ee86
Author: TimBarham <tim.bar...@microsoft.com>
Authored: Sat Oct 8 15:26:14 2016 +1000
Committer: TimBarham <tim.bar...@microsoft.com>
Committed: Mon Oct 17 23:57:16 2016 +1000

----------------------------------------------------------------------
 cordova-lib/spec-cordova/lazy_load.spec.js   |  9 +--
 cordova-lib/spec-cordova/util.spec.js        |  2 +-
 cordova-lib/src/cordova/lazy_load.js         | 25 +-------
 cordova-lib/src/cordova/remote_load.js       | 70 +----------------------
 cordova-lib/src/cordova/util.js              | 54 +++++++++++++----
 cordova-lib/src/plugman/registry/registry.js | 21 +++----
 cordova-lib/src/util/npm-helper.js           | 54 +++++++++++++++++
 7 files changed, 113 insertions(+), 122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/spec-cordova/lazy_load.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/lazy_load.spec.js 
b/cordova-lib/spec-cordova/lazy_load.spec.js
index 410c99c..0560649 100644
--- a/cordova-lib/spec-cordova/lazy_load.spec.js
+++ b/cordova-lib/spec-cordova/lazy_load.spec.js
@@ -20,6 +20,7 @@
 /* jshint sub:true */
 
 var lazy_load = require('../src/cordova/lazy_load'),
+    npmHelper = require('../src/util/npm-helper'),
     config = require('../src/cordova/config'),
     shell = require('shelljs'),
     npm = require('npm'),
@@ -31,11 +32,11 @@ var lazy_load = require('../src/cordova/lazy_load'),
     platforms = require('../src/platforms/platforms');
 
 describe('lazy_load module', function() {
-    var custom_path, npm_cache_add, fakeLazyLoad;
+    var custom_path, cachePackage, fakeLazyLoad;
     beforeEach(function() {
         custom_path = spyOn(config, 'has_custom_path').andReturn(false);
-        npm_cache_add = spyOn(lazy_load, 
'npm_cache_add').andReturn(Q(path.join('lib','dir')));
-        fakeLazyLoad = function(id, platform, version) {
+        cachePackage = spyOn(npmHelper, 
'cachePackage').andReturn(Q(path.join('lib', 'dir')));
+        fakeLazyLoad = function (id, platform, version) {
             if (platform == 'wp7' || platform == 'wp8') {
                 return Q(path.join('lib', 'wp', id, version, platform));
             } else {
@@ -63,7 +64,7 @@ describe('lazy_load module', function() {
         });
         it('should invoke lazy_load.custom with appropriate url, platform, and 
version as specified in platforms manifest', function(done) {
             lazy_load.cordova('android').then(function(dir) {
-                expect(npm_cache_add).toHaveBeenCalled();
+                expect(cachePackage).toHaveBeenCalled();
                 expect(dir).toBeDefined();
                 done();
             });

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/spec-cordova/util.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/util.spec.js 
b/cordova-lib/spec-cordova/util.spec.js
index e0799f7..2bcdae4 100644
--- a/cordova-lib/spec-cordova/util.spec.js
+++ b/cordova-lib/spec-cordova/util.spec.js
@@ -248,7 +248,7 @@ describe('util module', function() {
         });
 
         it('should pick buildConfig if no option is provided, but 
buildConfig.json exists', function() {
-            spyOn(fs, 'existsSync').andReturn(true);
+            spyOn(util, 'existsSync').andReturn(true);
             // Using path.join below to normalize path separators
             expect(util.preProcessOptions())
                 .toEqual(jasmine.objectContaining({options: {buildConfig: 
path.join('/fake/path/build.json')}}));

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/src/cordova/lazy_load.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/lazy_load.js 
b/cordova-lib/src/cordova/lazy_load.js
index 47677b7..379f447 100644
--- a/cordova-lib/src/cordova/lazy_load.js
+++ b/cordova-lib/src/cordova/lazy_load.js
@@ -35,7 +35,6 @@ var path          = require('path'),
     Q             = require('q'),
     npm           = require('npm'),
     npmhelper     = require('../util/npm-helper'),
-    unpack        = require('../util/unpack'),
     util          = require('./util'),
     gitclone      = require('../gitclone'),
     stubplatform  = {
@@ -49,7 +48,6 @@ exports.cordova = cordova;
 exports.cordova_git = cordova_git;
 exports.git_clone = git_clone_platform;
 exports.cordova_npm = cordova_npm;
-exports.npm_cache_add = npm_cache_add;
 exports.custom = custom;
 exports.based_on_config = based_on_config;
 
@@ -137,28 +135,7 @@ function cordova_npm(platform) {
 
         // Note that because the version of npm we use internally doesn't 
support caret versions, in order to allow them
         // from the command line and in config.xml, we use the actual version 
returned by getLatestMatchingNpmVersion().
-        var pkg = platform.packageName + '@' + version;
-        return exports.npm_cache_add(pkg);
-    });
-}
-
-// Equivalent to a command like
-// npm cache add cordova-android@3.5.0
-// Returns a promise that resolves to directory containing the package.
-function npm_cache_add(pkg) {
-    var npm_cache_dir = path.join(util.libDirectory, 'npm_cache');
-    var platformNpmConfig = {
-        cache: npm_cache_dir
-    };
-
-    return npmhelper.loadWithSettingsThenRestore(platformNpmConfig, function 
() {
-        return Q.ninvoke(npm.commands, 'cache', ['add', pkg])
-        .then(function (info) {
-            var pkgDir = path.resolve(npm.cache, info.name, info.version, 
'package');
-            // Unpack the package that was added to the cache (CB-8154)
-            var package_tgz = path.resolve(npm.cache, info.name, info.version, 
'package.tgz');
-            return unpack.unpackTgz(package_tgz, pkgDir);
-        });
+        return npmhelper.cachePackage(platform.packageName, version);
     });
 }
 

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/src/cordova/remote_load.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/remote_load.js 
b/cordova-lib/src/cordova/remote_load.js
index 8d5342e..90aa0b1 100644
--- a/cordova-lib/src/cordova/remote_load.js
+++ b/cordova-lib/src/cordova/remote_load.js
@@ -20,9 +20,7 @@
 var path = require('path');
 var shell = require('shelljs');
 var Q = require('q');
-var npm = require('npm');
 var npmHelper = require('../util/npm-helper');
-var unpack = require('../util/unpack');
 var util = require('./util');
 var git = require('../gitclone');
 
@@ -34,72 +32,7 @@ passed containing a packageName, name, and version.
 options - Package options
  */
 function npmFetch(packageName, packageVersion) {
-    var versionCallback;        // Resultant callback
-    var downloadDir;            // Download directory
-    var npmPackage;             // NPM package information
-
-    // Get the latest matching version from NPM if a version range is specified
-    versionCallback = util.getLatestMatchingNpmVersion(packageName, 
packageVersion).then(
-        function (latestVersion) {
-            downloadDir = path.join(util.libDirectory, packageName, 'cordova', 
latestVersion);
-            npmPackage = packageName + '@' + latestVersion;
-
-            return exports.npmCacheAdd(npmPackage);
-        },
-        function (err) {
-            return Q.reject(err);
-        }
-    );
-
-    return versionCallback;
-}
-
-/*
-Invokes "npm cache add," and then returns a promise that resolves to a
-directory containing the downloaded, or cached package. NPM package information
-must be passed in the form of package@version.
-
-npmPackage - NPM package details
- */
-function npmCacheAdd(npmPackage) {
-    var loadCallback;           // Resultant callback
-    var cacheAddCallback;       // Callback for cache
-    var cacheDir;               // Cache directory
-    var npmConfig;              // NPM Configuration
-    var packageDir;             // Downloaded package directory
-    var packageTGZ;             // Downloaded TGZ directory
-
-    cacheDir = path.join(util.libDirectory, 'npm_cache');
-
-    npmConfig = {
-        'cache': cacheDir
-    };
-
-    // Load with NPM configuration
-    loadCallback = npmHelper.loadWithSettingsThenRestore(npmConfig,
-        function () {
-
-            // Invoke NPM Cache Add
-            cacheAddCallback = Q.ninvoke(npm.commands, 'cache', ['add', 
npmPackage]).then(
-                function (info) {
-                    packageDir = path.resolve(npm.cache, info.name, 
info.version, 'package');
-                    packageTGZ = path.resolve(npm.cache, info.name, 
info.version, 'package.tgz');
-
-                    return unpack.unpackTgz(packageTGZ, packageDir);
-                },
-                function (err) {
-                    return Q.reject(err);
-                }
-            );
-
-            return cacheAddCallback;
-        },
-        function (err) {
-            return Q.reject(err);
-        }
-    );
-
-    return loadCallback;
+    return npmHelper.fetchPackage(packageName, packageVersion);
 }
 
 /*
@@ -143,4 +76,3 @@ function gitClone(gitURL, branch) {
 
 exports.gitClone = gitClone;
 exports.npmFetch = npmFetch;
-exports.npmCacheAdd = npmCacheAdd;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/src/cordova/util.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/util.js b/cordova-lib/src/cordova/util.js
index 1dffcd8..e77ea56 100644
--- a/cordova-lib/src/cordova/util.js
+++ b/cordova-lib/src/cordova/util.js
@@ -75,6 +75,7 @@ exports.isUrl = isUrl;
 exports.getLatestMatchingNpmVersion = getLatestMatchingNpmVersion;
 exports.getAvailableNpmVersions = getAvailableNpmVersions;
 exports.getInstalledPlatformsWithVersions = getInstalledPlatformsWithVersions;
+exports.existsSync = existsSync;
 
 function isUrl(value) {
     var u = value && url.parse(value);
@@ -82,23 +83,34 @@ function isUrl(value) {
 }
 
 function isRootDir(dir) {
-    if (fs.existsSync(path.join(dir, 'www'))) {
-        if (fs.existsSync(path.join(dir, 'config.xml'))) {
+    if (exports.existsSync(path.join(dir, 'www'))) {
+        if (exports.existsSync(path.join(dir, 'config.xml'))) {
             // For sure is.
-            if (fs.existsSync(path.join(dir, 'platforms'))) {
+            if (exports.existsSync(path.join(dir, 'platforms'))) {
                 return 2;
             } else {
                 return 1;
             }
         }
         // Might be (or may be under platforms/).
-        if (fs.existsSync(path.join(dir, 'www', 'config.xml'))) {
+        if (exports.existsSync(path.join(dir, 'www', 'config.xml'))) {
             return 1;
         }
     }
     return 0;
 }
 
+function existsSync(fileSpec) {
+    // Since fs.existsSync() is deprecated
+    try {
+        fs.statSync(fileSpec);
+        return true;
+    } catch (error) {
+        return false;
+    }
+}
+
+
 // Runs up the directory chain looking for a .cordova directory.
 // IF it is found we are in a Cordova project.
 // Omit argument to use CWD.
@@ -169,7 +181,7 @@ function fixRelativePath(value, /* optional */ cwd) {
 
 // Resolve any symlinks in order to avoid relative path issues. See 
https://issues.apache.org/jira/browse/CB-8757
 function convertToRealPathSafe(path) {
-    if (path && fs.existsSync(path)) {
+    if (path && exports.existsSync(path)) {
         return fs.realpathSync(path);
     }
 
@@ -192,7 +204,7 @@ function deleteSvnFolders(dir) {
 function listPlatforms(project_dir) {
     var core_platforms = require('../platforms/platforms');
     var platforms_dir = path.join(project_dir, 'platforms');
-    if ( !fs.existsSync(platforms_dir)) {
+    if ( !exports.existsSync(platforms_dir)) {
         return [];
     }
     var subdirs = fs.readdirSync(platforms_dir);
@@ -223,7 +235,7 @@ function findPlugins(pluginPath) {
     var plugins = [],
         stats;
 
-    if (fs.existsSync(pluginPath)) {
+    if (exports.existsSync(pluginPath)) {
         plugins = fs.readdirSync(pluginPath).filter(function (fileName) {
             stats = fs.statSync(path.join(pluginPath, fileName));
             return fileName != '.svn' && fileName != 'CVS' && 
stats.isDirectory();
@@ -244,9 +256,9 @@ function projectWww(projectDir) {
 function projectConfig(projectDir) {
     var rootPath = path.join(projectDir, 'config.xml');
     var wwwPath = path.join(projectDir, 'www', 'config.xml');
-    if (fs.existsSync(rootPath)) {
+    if (exports.existsSync(rootPath)) {
         return rootPath;
-    } else if (fs.existsSync(wwwPath)) {
+    } else if (exports.existsSync(wwwPath)) {
         return wwwPath;
     }
     return false;
@@ -283,7 +295,7 @@ function preProcessOptions (inputOptions) {
         result.platforms = projectPlatforms;
     }
 
-    if (!result.options.buildConfig && fs.existsSync(path.join(projectRoot, 
'build.json'))) {
+    if (!result.options.buildConfig && 
exports.existsSync(path.join(projectRoot, 'build.json'))) {
         result.options.buildConfig = path.join(projectRoot, 'build.json');
     }
 
@@ -383,6 +395,11 @@ function addModuleProperty(module, symbol, modulePath, 
opt_wrap, opt_obj) {
  * @returns {Promise} Promise for version (a valid semver version if one is 
found, otherwise whatever was provided).
  */
 function getLatestMatchingNpmVersion(module_name, version) {
+    if (!version) {
+        // If no version specified, get the latest
+        return getLatestNpmVersion(module_name);
+    }
+
     var validVersion = semver.valid(version, /* loose */ true);
     if (validVersion) {
         // This method is really intended to work with ranges, so if a version 
rather than a range is specified, we just
@@ -417,3 +434,20 @@ function getAvailableNpmVersions(module_name) {
         });
     });
 }
+
+/**
+ * Returns a promise for the latest version available for the specified npm 
module.
+ * @param {string} module_name - npm module name.
+ * @returns {Promise} Promise for an array of versions.
+ */
+function getLatestNpmVersion(module_name) {
+    var npm = require('npm');
+    return Q.nfcall(npm.load).then(function () {
+        return Q.ninvoke(npm.commands, 'view', [module_name, 'version'], /* 
silent = */ true).then(function (result) {
+            // result is an object in the form:
+            //     {'<version>': {version: '<version>'}}
+            // (where <version> is the latest version)
+            return Object.keys(result)[0];
+        });
+    });
+}

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/src/plugman/registry/registry.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/plugman/registry/registry.js 
b/cordova-lib/src/plugman/registry/registry.js
index 2772524..c11eba5 100644
--- a/cordova-lib/src/plugman/registry/registry.js
+++ b/cordova-lib/src/plugman/registry/registry.js
@@ -20,10 +20,10 @@
 /* jshint laxcomma:true */
 
 var npm = require('npm'),
-    path = require('path'),
     Q = require('q'),
     npmhelper = require('../../util/npm-helper'),
-    events = require('cordova-common').events;
+    events = require('cordova-common').events,
+    pluginSpec = require('../../cordova/plugin_spec_parser');
 
 module.exports = {
     settings: null,
@@ -114,19 +114,12 @@ function initThenLoadSettingsWithRestore(promises) {
 }
 
 /**
-* @param {Array} with one element - the plugin id or "id@version"
+* @param {string} plugin - the plugin id or "id@version"
 * @return {Promise.<string>} Promised path to fetched package.
 */
 function fetchPlugin(plugin) {
-    return initThenLoadSettingsWithRestore(function () {
-        events.emit('log', 'Fetching plugin "' + plugin + '" via npm');
-        return Q.ninvoke(npm.commands, 'cache', ['add', plugin])
-        .then(function (info) {
-            var unpack = require('../../util/unpack');
-            var pluginDir = path.resolve(npm.cache, info.name, info.version, 
'package');
-            // Unpack the plugin that was added to the cache (CB-8154)
-            var package_tgz = path.resolve(npm.cache, info.name, info.version, 
'package.tgz');
-            return unpack.unpackTgz(package_tgz, pluginDir);
-        });
-    });
+    events.emit('log', 'Fetching plugin "' + plugin + '" via npm');
+    var parsedSpec = pluginSpec.parse(plugin);
+    var scope = parsedSpec.scope || '';
+    return npmhelper.fetchPackage(scope + parsedSpec.id, parsedSpec.version);
 }

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/5c8b4cac/cordova-lib/src/util/npm-helper.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/util/npm-helper.js 
b/cordova-lib/src/util/npm-helper.js
index e8c5b18..4bd0ea1 100644
--- a/cordova-lib/src/util/npm-helper.js
+++ b/cordova-lib/src/util/npm-helper.js
@@ -20,7 +20,10 @@
 // Helper methods to help keep npm operations separated.
 
 var npm = require('npm'),
+    path = require('path'),
     Q = require('q'),
+    unpack = require('./unpack'),
+    util = require('../cordova/util'),
     cachedSettings = null,
     cachedSettingsValues = null;
 
@@ -72,4 +75,55 @@ function restoreSettings() {
     }
 }
 
+/**
+ * Fetches the latest version of a package from NPM that matches the specified 
version. Returns a promise that
+ * resolves to the directory the NPM package is located in.
+ * @param packageName - name of an npm package
+ * @param packageVersion - requested version or version range
+ */
+function fetchPackage(packageName, packageVersion) {
+    // Get the latest matching version from NPM if a version range is specified
+    return util.getLatestMatchingNpmVersion(packageName, packageVersion).then(
+        function (latestVersion) {
+            return cachePackage(packageName, latestVersion);
+        }
+    );
+}
+
+/**
+ * Invokes "npm cache add," and then returns a promise that resolves to a 
directory containing the downloaded,
+ * or cached package.
+ * @param packageName - name of an npm package
+ * @param packageVersion - requested version (not a version range)
+ */
+function cachePackage(packageName, packageVersion) {
+    return Q().then(function () {
+        var cacheDir = path.join(util.libDirectory, 'npm_cache');
+
+        // If already cached, use that rather than calling 'npm cache add' 
again.
+        var packageCacheDir = path.resolve(cacheDir, packageName, 
packageVersion);
+        var packageTGZ = path.resolve(packageCacheDir, 'package.tgz');
+        if (util.existsSync(packageTGZ)) {
+            return unpack.unpackTgz(packageTGZ, path.resolve(packageCacheDir, 
'package'));
+        }
+
+        // Load with NPM configuration
+        return loadWithSettingsThenRestore({'cache': cacheDir},
+            function () {
+                // Invoke NPM Cache Add
+                return Q.ninvoke(npm.commands, 'cache', ['add', (packageName + 
'@' + packageVersion)]).then(
+                    function (info) {
+                        var packageDir = path.resolve(npm.cache, info.name, 
info.version, 'package');
+                        var packageTGZ = path.resolve(npm.cache, info.name, 
info.version, 'package.tgz');
+
+                        return unpack.unpackTgz(packageTGZ, packageDir);
+                    }
+                );
+            }
+        );
+    });
+}
+
 module.exports.loadWithSettingsThenRestore = loadWithSettingsThenRestore;
+module.exports.fetchPackage = fetchPackage;
+module.exports.cachePackage = cachePackage;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org
For additional commands, e-mail: commits-h...@cordova.apache.org

Reply via email to