Skip to content

Instantly share code, notes, and snippets.

@beefchimi
Last active May 26, 2022 20:14
Show Gist options
  • Save beefchimi/89ccde361e32b7184f8d89d4df149b95 to your computer and use it in GitHub Desktop.
Save beefchimi/89ccde361e32b7184f8d89d4df149b95 to your computer and use it in GitHub Desktop.
Tool to help compare `declared vs installed` dependencies
///
/// Helper function simply for sorting alphabetically
function sortObjectAlphabetically(obj) {
const keys = Object.keys(obj);
const sorted = keys.sort((a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
return sorted.reduce((accumulated, current) => ({
...accumulated,
[current]: obj[current]
}), {});
}
///
/// Utilities for parsing our dependencies
const TYPE_MISMATCH = ['major', 'minor', 'patch', 'equal', 'not-found'];
const REGEXP_VERSION_PREFIX = new RegExp(/(~|\^|=)/, 'g');
const REGEXP_ALHPA_BETA_SEPARATOR = new RegExp(/-.*/, 'g');
function parseVersion(version) {
return version
.replace(REGEXP_VERSION_PREFIX, '')
.replace(REGEXP_ALHPA_BETA_SEPARATOR, '')
.split('.')
.map((value) => parseInt(value, 10));
}
function compareVersions(declaredVersion, reportedVersion) {
const declaredParsed = parseVersion(declaredVersion);
const reportedParsed = parseVersion(reportedVersion);
if (declaredParsed[0] !== reportedParsed[0]) {
return 'major';
}
if (declaredParsed[1] !== reportedParsed[1]) {
return 'minor';
}
if (declaredParsed[2] !== reportedParsed[2]) {
return 'patch';
}
// Do an array equality comparison and return 'not-found' if unequal.
return 'equal';
}
function buildComparison(declaredVersions, reportedVersions) {
const declaredKeys = Object.keys(declaredVersions);
return declaredKeys.reduce((accumulated, current) => {
const declaredVersion = declaredVersions[current];
const reportedVersion = reportedVersions[current];
return [
...accumulated,
{
package: current,
declared: declaredVersion,
reported: reportedVersion,
mismatch: reportedVersion ? compareVersions(declaredVersion, reportedVersion) : 'not-found'
},
];
}, []);
}
function filterMismatchedDependencies(comparison) {
return comparison.reduce((accumulated, current) => {
const includeResult = current.mismatch === 'major' || current.mismatch === 'minor' || current.mismatch === 'patch';
return [
...accumulated,
...(includeResult ? [current] : [])
];
}, []);
}
///
/// Examples of dependency arrays
const declared = {
'@test/dep1': '^1.2.3',
'dep2': '~2.0.0',
'dep3': '=3.33.333',
'dep4': '4.0.0',
'dep5': '^5.0.0-alpha.1',
'dep6': '^6.0.0-beta.123',
};
const reported = {
'@test/dep1': '1.2.16',
'dep2': '2.1.0',
'dep3': '3.33.333',
'dep4': '4.0.1',
'dep5': '5.0.0-alpha.1',
'dep6': '6.0.0-beta.321',
};
///
/// Code to execute in order to generate results
const comparison = buildComparison(declared, reported);
const filtered = filterMismatchedDependencies(comparison);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment