Skip to content

Instantly share code, notes, and snippets.

@athulmurali
Last active April 24, 2023 21:08
Show Gist options
  • Save athulmurali/c651455311703f7d5b6eaea36735c71e to your computer and use it in GitHub Desktop.
Save athulmurali/c651455311703f7d5b6eaea36735c71e to your computer and use it in GitHub Desktop.
const chalk = require('chalk');
const semver = require('semver');
function chalkLog(color, message) {
console.log(chalk[color](message));
}
function loadNodeVersionFromPackageJson() {
chalkLog('green', 'Loading... loadNodeVersionFromPackageJson from ~/.zshrc');
const packageJsonPath = `${process.cwd()}/package.json`;
// Check if package.json file exists.
if (fs.existsSync(packageJsonPath)) {
const packageJson = require(packageJsonPath);
const nodeVersion = packageJson.engines?.node;
if (!nodeVersion) {
chalkLog('yellow', 'package.json has no .engines.node version defined');
return;
}
const validRange = semver.validRange(nodeVersion);
if (!validRange) {
chalkLog('yellow', `Invalid node version range: ${nodeVersion}`);
return;
}
const versions = Object.keys(nvm_ls());
let matchedVersion = null;
for (const version of versions) {
if (semver.satisfies(version, validRange)) {
matchedVersion = version;
break;
}
}
if (matchedVersion) {
chalkLog('green', `This directory has a package.json file with .engines.node (${nodeVersion})`);
nvm_use(matchedVersion);
// Record modification of node version.
process.env.NODE_VERSION_MODIFIED = true;
return;
}
chalkLog('yellow', `No matching node version found for range: ${nodeVersion}`);
return;
}
if (process.env.NODE_VERSION_MODIFIED) {
// Revert to default node version.
chalkLog('green', 'Reverting to default node version.');
nvm_use('default');
process.env.NODE_VERSION_MODIFIED = false;
}
}
const { loadNodeVersionFromPackageJson } = require('./loadNodeVersionFromPackageJson');
describe('loadNodeVersionFromPackageJson', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should use the version specified in package.json', () => {
const packageJson = {
engines: {
node: '14.15.3',
},
};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const nvmUseSpy = jest.spyOn(global.console, 'log');
loadNodeVersionFromPackageJson();
expect(nvmUseSpy).toHaveBeenCalledWith(expect.stringContaining('Now using node version 14.15.3'));
});
it('should print a warning if package.json has no engines.node version defined', () => {
const packageJson = {};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const consoleWarnSpy = jest.spyOn(global.console, 'warn');
loadNodeVersionFromPackageJson();
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('package.json has no .engines.node version defined'));
});
it('should print a warning if package.json .engines.node version has special characters', () => {
const packageJson = {
engines: {
node: '~14.15.3',
},
};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const consoleWarnSpy = jest.spyOn(global.console, 'warn');
loadNodeVersionFromPackageJson();
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('nvm does not support special characters (^, >, ~)'));
});
it('should print a warning if package.json .engines.node version is not compatible with nvm', () => {
const packageJson = {
engines: {
node: '>=16.0.0 <17.0.0 || >=18.0.0 <19.0.0',
},
};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const consoleWarnSpy = jest.spyOn(global.console, 'warn');
loadNodeVersionFromPackageJson();
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('is not compatible with nvm'));
});
it('should print a warning if package.json .engines.node version has wildcard', () => {
const packageJson = {
engines: {
node: '14.x',
},
};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const consoleWarnSpy = jest.spyOn(global.console, 'warn');
loadNodeVersionFromPackageJson();
expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining('is not compatible with nvm'));
});
it('should use the major version specified in package.json', () => {
const packageJson = {
engines: {
node: '>=14',
},
};
jest.mock(`${process.cwd()}/package.json`, () => packageJson, { virtual: true });
const nvmUseSpy = jest.spyOn(global.console, 'log');
loadNodeVersionFromPackageJson();
expect(nvmUseSpy).toHaveBeenCalledWith(expect.stringContaining('Now using node version 14'));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment