Skip to content
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

Update npm v7+ installation method #345

Merged
merged 5 commits into from
Jun 29, 2022
Merged
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
22 changes: 19 additions & 3 deletions bin/helpers/packageInstaller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
fileHelpers = require('./fileHelpers'),
logger = require("./logger").winstonLogger,
Constants = require('./constants'),
process = require('process'),
utils = require('./utils'),
{ get_version } = require('./usageReporting'),
process = require('process'),
{ spawn } = require('child_process'),
util = require('util');

Expand Down Expand Up @@ -64,15 +65,30 @@ const packageInstall = (packageDir) => {
logger.info(`Packages were installed locally successfully.`);
resolve('Packages were installed successfully.');
} else {
logger.error(`Some error occurred while installing packages. Error code ${code}`);
logger.error(`Some error occurred while installing packages. Error code ${code}. Please read npm_install_debug.log for more info.`);
reject(`Packages were not installed successfully. Error code ${code}`);
}
};
const nodeProcessErrorCallback = (error) => {
logger.error(`Some error occurred while installing packages: %j`, error);
reject(`Packages were not installed successfully. Error Description ${util.format('%j', error)}`);
};
nodeProcess = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['install', '--loglevel', 'verbose', '>', '../npm_install_debug.log', '2>&1'], {cwd: packageDir, shell: true});

let nodeProcess;
logger.debug(`Fetching npm version and its major version`);
const npm_version = get_version('npm')
const npm_major_version = utils.getMajorVersion(npm_version);
logger.debug(`Fetched npm version: ${npm_version} and its major version: ${npm_major_version}`);

// add --legacy-peer-deps flag while installing dependencies for npm v7+
// For more info please read "Peer Dependencies" section here -> https://github.blog/2021-02-02-npm-7-is-now-generally-available/
if (parseInt(npm_major_version) >= 7) {
logger.debug(`Running NPM install command: npm install --legacy-peer-deps --loglevel verbose > ../npm_install_debug.log`);
nodeProcess = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['install', '--legacy-peer-deps', '--loglevel', 'verbose', '>', '../npm_install_debug.log', '2>&1'], {cwd: packageDir, shell: true});
} else {
logger.debug(`Running NPM install command: 'npm install --loglevel verbose > ../npm_install_debug.log'`);
nodeProcess = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['install', '--loglevel', 'verbose', '>', '../npm_install_debug.log', '2>&1'], {cwd: packageDir, shell: true});
}
nodeProcess.on('close', nodeProcessCloseCallback);
nodeProcess.on('error', nodeProcessErrorCallback);
});
Expand Down
21 changes: 21 additions & 0 deletions bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1233,3 +1233,24 @@ exports.getVideoConfig = (cypressJson) => {
logger.debug(`Setting videoUploadOnPasses = ${conf.videoUploadOnPasses}`);
return conf;
}

exports.getMajorVersion = (version) => {
try {
if (!version || !version.match(/^(\d+\.)?(\d+\.)?(\*|\d+)$/)) {
return null;
}

const matches = version.match(/^(\d+\.)?(\d+\.)?(\*|\d+)$/)
if(matches && matches.length >= 2) {
if (!matches[1]) {
return matches[0];
}
return matches[1].replace('.','');
} else {
return null;
}
} catch(error) {
logger.debug(`Some Error occurred while fetching major version of ${version}. Returning null. Error Details: ${error}`)
return null;
}
}
40 changes: 37 additions & 3 deletions test/unit/bin/helpers/packageInstaller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ const chai = require("chai"),
cp = require('child_process');

const logger = require("../../../../bin/helpers/logger").winstonLogger,
fileHelpers = require("../../../../bin/helpers/fileHelpers");
fileHelpers = require("../../../../bin/helpers/fileHelpers"),
utils = require('../../../../bin/helpers/utils');

const rewire = require("rewire");

Expand Down Expand Up @@ -214,15 +215,47 @@ describe("packageInstaller", () => {
context("packageInstall", () => {
const packageInstaller = rewire("../../../../bin/helpers/packageInstaller");

it("should call npm install on directory and resolve if spawn is closed successfully", () => {
it("should call npm install on directory with npm <= 6 and resolve if spawn is closed successfully", () => {
let spawnStub = sandbox.stub(cp, 'spawn').returns({
on: (_close, nodeProcessCloseCallback) => {
nodeProcessCloseCallback(0);
}
});
let getMajorVersionStub = sandbox.stub(utils, 'getMajorVersion').returns('7');
packageInstaller.__set__({
nodeProcess: {},
spawn: spawnStub
spawn: spawnStub,
utils: {
getMajorVersion: getMajorVersionStub
}
});
let packageInstallrewire = packageInstaller.__get__('packageInstall');
let directoryPath = "/random/path";
return packageInstallrewire(directoryPath)
.then((data) => {
console.log(data);
chai.assert.equal(data, "Packages were installed successfully.")
spawnStub.restore();
getMajorVersionStub.restore();
})
.catch((_error) => {
chai.assert.fail(`Promise error ${_error}`);
});
});

it("should call npm install on directory with npm >= 7 and resolve if spawn is closed successfully", () => {
let spawnStub = sandbox.stub(cp, 'spawn').returns({
on: (_close, nodeProcessCloseCallback) => {
nodeProcessCloseCallback(0);
}
});
let getMajorVersionStub = sandbox.stub(utils, 'getMajorVersion').returns('7');
packageInstaller.__set__({
nodeProcess: {},
spawn: spawnStub,
utils: {
getMajorVersion: getMajorVersionStub
}
});
let packageInstallrewire = packageInstaller.__get__('packageInstall');
let directoryPath = "/random/path";
Expand All @@ -231,6 +264,7 @@ describe("packageInstaller", () => {
console.log(data);
chai.assert.equal(data, "Packages were installed successfully.")
spawnStub.restore();
getMajorVersionStub.restore();
})
.catch((_error) => {
chai.assert.fail(`Promise error ${_error}`);
Expand Down
30 changes: 30 additions & 0 deletions test/unit/bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3378,4 +3378,34 @@ describe('utils', () => {
expect(utils.formatRequest(null, {statusCode: 500}, cricularBody)).to.be.eql({err: null, status: 500, body: '[Circular]'});
});
});

describe('getMajorVersion', () => {
it('should return null if undefined version is sent', () => {
expect(utils.getMajorVersion()).to.be.eql(null);
});

it('should return null if null version is sent', () => {
expect(utils.getMajorVersion(null)).to.be.eql(null);
});

it('should return null if improper version is sent', () => {
expect(utils.getMajorVersion('test')).to.be.eql(null);
expect(utils.getMajorVersion('a1.1.1')).to.be.eql(null);
expect(utils.getMajorVersion('1a.1.1')).to.be.eql(null);
expect(utils.getMajorVersion('1.a1.1')).to.be.eql(null);
expect(utils.getMajorVersion('1.1a.1')).to.be.eql(null);
expect(utils.getMajorVersion('1.1.a1')).to.be.eql(null);
expect(utils.getMajorVersion('1.1.1a')).to.be.eql(null);
expect(utils.getMajorVersion('.1.1.1')).to.be.eql(null);
expect(utils.getMajorVersion('1.')).to.be.eql(null);
expect(utils.getMajorVersion('$')).to.be.eql(null);
});

it('should return proper major version if proper version is sent', () => {
expect(utils.getMajorVersion('1.1.1')).to.be.eql('1');
expect(utils.getMajorVersion('2.1')).to.be.eql('2');
expect(utils.getMajorVersion('3')).to.be.eql('3');
expect(utils.getMajorVersion('4.1')).to.be.eql('4');
});
});
});