Return-Path: X-Original-To: apmail-cordova-dev-archive@www.apache.org Delivered-To: apmail-cordova-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B89B81887F for ; Thu, 18 Feb 2016 12:11:37 +0000 (UTC) Received: (qmail 92405 invoked by uid 500); 18 Feb 2016 12:11:34 -0000 Delivered-To: apmail-cordova-dev-archive@cordova.apache.org Received: (qmail 92363 invoked by uid 500); 18 Feb 2016 12:11:34 -0000 Mailing-List: contact dev-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cordova.apache.org Delivered-To: mailing list dev@cordova.apache.org Received: (qmail 92352 invoked by uid 99); 18 Feb 2016 12:11:34 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Feb 2016 12:11:34 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 0F71FDFF67; Thu, 18 Feb 2016 12:11:34 +0000 (UTC) From: TimBarham To: dev@cordova.apache.org Reply-To: dev@cordova.apache.org References: In-Reply-To: Subject: [GitHub] cordova-lib pull request: New plugin version selection implementat... Content-Type: text/plain Message-Id: <20160218121134.0F71FDFF67@git1-us-west.apache.org> Date: Thu, 18 Feb 2016 12:11:34 +0000 (UTC) Github user TimBarham commented on a diff in the pull request: https://github.com/apache/cordova-lib/pull/363#discussion_r53305804 --- Diff: cordova-lib/src/cordova/plugin.js --- @@ -507,3 +527,117 @@ function versionString(version) { return null; } + +/** + * Gets the version of a plugin that should be fetched for a given project based + * on the plugin's engine information from NPM and the platforms/plugins installed + * in the project + * + * @param {string} projectRoot The path to the root directory of the project + * @param {object} pluginInfo The NPM info of the plugin be fetched (e.g. the + * result of calling `registry.info()`) + * @param {string} cordovaVersion The semver version of cordova-lib + * + * @return {Promise} A promise that will resolve to either a string + * if there is a version of the plugin that this + * project satisfies or null if there is not + */ +function getFetchVersion(projectRoot, pluginInfo, cordovaVersion) { + // Figure out the project requirements + if (pluginInfo.engines && pluginInfo.engines.cordovaDependencies) { + var pluginList = getInstalledPlugins(projectRoot); + var pluginMap = {}; + + for(var i = 0; i < pluginList.length; i++) { + pluginMap[pluginList[i].id] = pluginList[i].version; + } + + return cordova_util.getInstalledPlatformsWithVersions(projectRoot) + .then(function(platformVersions) { + return determinePluginVersionToFetch( + pluginInfo.versions, + pluginInfo.engines.cordovaDependencies, + pluginMap, + platformVersions, + cordovaVersion); + }); + } else { + // If we have no engine, we want to fall back to the default behavior + return Q.fcall(function() { + return null; + }); + } +} + +function determinePluginVersionToFetch(allVersions, engine, pluginMap, platformMap, cordovaVersion) { + var upperBounds = []; + var versions = []; + + for(var version in engine) { + if(version.indexOf('<') === 0 && semver.valid(version.substring(1))) { + // We only care about upper bounds that our project does not support + if(!satisfiesProjectRequirements(engine[version], pluginMap, platformMap, cordovaVersion)) { + upperBounds.push(version); + } + } else if(semver.valid(version) && allVersions.indexOf(version) !== -1) { + versions.push(version); + } + } + + // Sort in descending order; we want to start at latest and work back + versions.sort(semver.rcompare); + + for(var i = 0; i < versions.length; i++) { + for(var j = 0; j < upperBounds.length; j++) { + if(semver.satisfies(versions[i], upperBounds[j])) { + // Because we sorted in desc. order, if we find an upper bound + // that applies to this version (and the ones below) we can just + // quit (we already filtered out ones that our project supports) + return null; + } + } + + // Check the version constraint + if(satisfiesProjectRequirements(engine[versions[i]], pluginMap, platformMap, cordovaVersion)) { + // Because we sorted in descending order, we can stop searching once + // we hit a satisfied constraint + var index = versions.indexOf(versions[i]); + if(index > 0) { + // Return the highest plugin version below the next highest + // constrainted version + var nextHighest = versions[index - 1]; + return allVersions[allVersions.indexOf(nextHighest) - 1]; + } else { + // Return the latest plugin version + return allVersions[allVersions.length - 1]; + } + } + } + + // No constraints were satisfied + return null; +} + +function satisfiesProjectRequirements(reqs, pluginMap, platformMap, cordovaVersion) { + for (var req in reqs) { + var okay = true; + + if(pluginMap[req]) { + okay = semver.satisfies(pluginMap[req], reqs[req]); + } else if(req === 'cordova') { + okay = semver.satisfies(cordovaVersion, reqs[req]); + } else if(req.indexOf('cordova-') === 0) { + // Might be a platform constraint + var platform = req.substring(8); + if(platformMap[platform]) { + okay = semver.satisfies(platformMap[platform], reqs[req]); + } + } + + if(!okay) { + return false; --- End diff -- If we reject a version, it might be useful to output a message describing the version we rejected an why (with a log level of `verbose` of course). --- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastructure@apache.org or file a JIRA ticket with INFRA. --- --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org For additional commands, e-mail: dev-help@cordova.apache.org