Skip to content

CB-13123 : plugin add should use cordovaDependency instead #598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 67 additions & 5 deletions spec/plugman/install.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var events = require('cordova-common').events;
var plugman = require('../../src/plugman/plugman');
var platforms = require('../../src/plugman/platforms/common');
var knownPlatforms = require('../../src/platforms/platforms');
var cordovaUtil = require('../../src/cordova/util');
var common = require('../common');
var fs = require('fs');
var os = require('os');
Expand Down Expand Up @@ -287,15 +288,12 @@ describe('install', function () {
.fin(function () {
var plugmanVersion = require('../../package.json').version.replace(/-dev|-nightly.*$/, '');
var cordovaVersion = require('../../package.json').version.replace(/-dev|-nightly.*$/, '');
expect(satisfies.calls.count()).toBe(4);
// var megaFun = require('../../package.json').version.replace(/-dev|-nightly.*$/, '');
expect(satisfies.calls.count()).toBe(2);
// <engine name="cordova" version=">=2.3.0"/>
expect(satisfies.calls.argsFor(0)).toEqual([ cordovaVersion, '>=2.3.0', true ]);
// <engine name="cordova-plugman" version=">=0.10.0" />
expect(satisfies.calls.argsFor(1)).toEqual([ plugmanVersion, '>=0.10.0', true ]);
// <engine name="mega-fun-plugin" version=">=1.0.0" scriptSrc="megaFunVersion" platform="*" />
expect(satisfies.calls.argsFor(2)).toEqual([ null, '>=1.0.0', true ]);
// <engine name="mega-boring-plugin" version=">=3.0.0" scriptSrc="megaBoringVersion" platform="ios|android" />
expect(satisfies.calls.argsFor(3)).toEqual([ null, '>=3.0.0', true ]);
done();
});
}, TIMEOUT);
Expand Down Expand Up @@ -543,3 +541,67 @@ describe('end', function () {
shell.rm('-rf', temp_dir);
}, TIMEOUT);
});

describe('unit tests for checkEngines', function () {
var fail;
var engine = [ { platform: 'android',
minVersion: '>=3.6.0',
currentVersion: '6.2.3' } ];
beforeEach(function () {
spyOn(semver, 'satisfies');
});

it('checkEngines should return true', function () {
spyOn(fs, 'existsSync').and.returnValue(false);
semver.satisfies.and.returnValue(true);
install.checkEngines(engine, 'pluginDir')
.then(function (res) {
expect(res).toBe(true);
}).fail(function err (errMsg) {
fail('fail handler unexpectedly invoked');
console.error(errMsg);
});
});

it('checkEngines should check cordovaDependencies', function () {
var pkgJson = { engines: { cordovaDependencies: { '9.0.0': [Object], '2.0.0': [Object] } } };
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(cordovaUtil, 'requireNoCache').and.returnValue(pkgJson);
semver.satisfies.and.callThrough();
install.checkEngines(engine, 'pluginDir')
.then(function (res) {
expect(res).toBe(true);
expect(semver.satisfies).toHaveBeenCalledWith('6.2.3', '>=3.6.0', true);
}).fail(function err (errMsg) {
fail('fail handler unexpectedly invoked');
console.error(errMsg);
});
});

it('checkEngines should check if plugin version is supported', function () {
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(cordovaUtil, 'requireNoCache').and.returnValue(true);
semver.satisfies.and.callThrough();
install.checkEngines(engine, 'pluginDir')
.then(function (res) {
expect(res).toBe(true);
expect(semver.satisfies).toHaveBeenCalledWith('6.2.3', '>=3.6.0', true);
}).fail(function err (errMsg) {
fail('fail handler unexpectedly invoked');
console.error(errMsg);
});
});

it('checkEngines should warn if plugin is not supported', function () {
spyOn(events, 'emit');
spyOn(Q, 'reject').and.callThrough();
semver.satisfies.and.returnValue(false);
install.checkEngines(engine, 'pluginDir')
.then(function (res) {
fail('success handler unexpectedly invoked');
}).fail(function err (errMsg) {
expect(errMsg).toBe('skip');
expect(events.emit).toHaveBeenCalledWith('warn', jasmine.stringMatching(/failed version requirement/));
});
});
});
59 changes: 40 additions & 19 deletions src/plugman/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,33 +100,54 @@ function possiblyFetch (id, plugins_dir, options) {
return require('./plugman').fetch(id, plugins_dir, opts);
}

function checkEngines (engines) {
function checkEngines (engines, plugin_dir) {
var plugin_pkgJson_path = path.join(plugin_dir, 'package.json');
var plugin_pkgJson;

if (fs.existsSync(plugin_pkgJson_path)) {
plugin_pkgJson = cordovaUtil.requireNoCache(plugin_pkgJson_path);
}

for (var i = 0; i < engines.length; i++) {
var engine = engines[i];

// This is a hack to allow plugins with <engine> tag to be installed with
// engine with '-dev' or '-nightly' suffixes. It is required due to new semver range logic,
// introduced in [email protected]. For more details see https://github.com/npm/node-semver#prerelease-tags.
//
// This may lead to false-positive checks, when engine version with dropped
// suffix is equal to one of range bounds, for example: 5.1.0-dev >= 5.1.0.
// However this shouldn't be a problem, because this only should happen in dev workflow.
engine.currentVersion = engine.currentVersion && engine.currentVersion.replace(/-dev|-nightly.*$/, '');
if (semver.satisfies(engine.currentVersion, engine.minVersion, /* loose= */true) || engine.currentVersion === null) {
continue; // engine ok!
} else {
var msg = 'Plugin doesn\'t support this project\'s ' + engine.name + ' version. ' +
engine.name + ': ' + engine.currentVersion +
', failed version requirement: ' + engine.minVersion;
events.emit('warn', msg);
return Q.reject('skip');
if (engine && engine.currentVersion) {
if (plugin_pkgJson && plugin_pkgJson.engines && plugin_pkgJson.engines.cordovaDependencies) {
for (var key in plugin_pkgJson.engines.cordovaDependencies) {
if (plugin_pkgJson.engines.cordovaDependencies.hasOwnProperty(key)) {
if (((key < engine.currentVersion) || (key === engine.currentVersion)) && (plugin_pkgJson.engines.cordovaDependencies[key])) {
var plugin_pkgJson_min = plugin_pkgJson.engines.cordovaDependencies[key];
if (plugin_pkgJson_min[engine.name]) {
engine.minVersion = plugin_pkgJson_min[engine.name];
}
}
}
}
// This is a hack to allow plugins with <engine> tag to be installed with
// engine with '-dev' or '-nightly' suffixes. It is required due to new semver range logic,
// introduced in [email protected]. For more details see https://github.com/npm/node-semver#prerelease-tags.
//
// This may lead to false-positive checks, when engine version with dropped
// suffix is equal to one of range bounds, for example: 5.1.0-dev >= 5.1.0.
// However this shouldn't be a problem, because this only should happen in dev workflow.
}
engine.currentVersion = engine.currentVersion && engine.currentVersion.replace(/-dev|-nightly.*$/, '');
if (semver.satisfies(engine.currentVersion, engine.minVersion, /* loose= */true) || engine.currentVersion === null) {
continue; // engine ok!
} else {
var msg = 'Plugin doesn\'t support this project\'s ' + engine.name + ' version. ' +
engine.name + ': ' + engine.currentVersion +
', failed version requirement: ' + engine.minVersion;
events.emit('warn', msg);
return Q.reject('skip');
}
}
}

return Q(true);
}

module.exports.checkEngines = checkEngines;

function cleanVersionOutput (version, name) {
var out = version.trim();
var rc_index = out.indexOf('rc');
Expand Down Expand Up @@ -310,7 +331,7 @@ function runInstall (actions, platform, project_dir, plugin_dir, plugins_dir, op
options.platformVersion = platformVersion;
return callEngineScripts(theEngines, path.resolve(plugins_dir, '..'));
}).then(function (engines) {
return checkEngines(engines);
return module.exports.checkEngines(engines, plugin_dir);
}).then(function () {
filtered_variables = variableMerge.mergeVariables(plugin_dir, platform, options);
install.filtered_variables = filtered_variables;
Expand Down