I've got a git diff output string parsed to this array, which gives me all changed dependencies in a package.json file:
const data = [
[ '-', '@date-io/moment', '1.3.13', '1', '3', '13' ],
[ '+', '@date-io/moment', '1.3.14', '1', '3', '14' ],
[ '-', '@emotion/react', '11.7.0', '11', '7', '0' ],
[ '-', '@emotion/styled', '11.6.0', '11', '6', '0' ],
[ '+', '@emotion/react', '11.8.2', '11', '8', '2' ],
[ '+', '@emotion/styled', '11.8.1', '11', '8', '1' ]
]
The first element (+/ -) shows me if this change was added or deleted. The second element is the package name (this is the element, which connects two arrays), and the next fields give me the version.
Now I need to iterate this array to find out which kind of version change has been made for each package. So the output should be:
{
'@date-io/moment': 'patch',
'@emotion/react': 'minor',
'@emotion/styled': 'minor'
}
I tried to get all packages by doing
const result = {}
data.forEach(d => {
result[d[1]] = bump // how to calculate `bump`?
})
But this doesn't handle + and - and it doesn't calculate the type of version bump.
Using Array.prototype.reduce to reduce you can reduce the array into an object and for each package use Array.prototype.find to find the corresponding change. Then you can compare the versions and determine its change.
const data = [
[ '-', '@date-io/moment', '1.3.13', '1', '3', '13' ],
[ '+', '@date-io/moment', '1.3.14', '1', '3', '14' ],
[ '-', '@emotion/react', '11.7.0', '11', '7', '0' ],
[ '-', '@emotion/styled', '11.6.0', '11', '6', '0' ],
[ '+', '@emotion/react', '11.8.2', '11', '8', '2' ],
[ '+', '@emotion/styled', '11.8.1', '11', '8', '1' ]
];
const changes = data.reduce((t, [type, name, , major, minor, patch], i, arr) => {
if (type === "+") {
const match = arr
.find(([type, pName]) => type === "-" && pName === name);
if (!match) {
return t; // handle no match here
}
const [, , , pMajor, pMinor, pPatch] = match;
return {
...t,
[name]: pMajor !== major ? "major" :
pMinor !== minor ? "minor" :
"patch"
}
}
return t;
}, {});
console.log(changes);
Map of all subtractionsconst data = [
["-", "@date-io/moment", "1.3.13", "1", "3", "13"],
["+", "@date-io/moment", "1.3.14", "1", "3", "14"],
["-", "@emotion/react", "11.7.0", "11", "7", "0"],
["-", "@emotion/styled", "11.6.0", "11", "6", "0"],
["+", "@emotion/react", "11.8.2", "11", "8", "2"],
["+", "@emotion/styled", "11.8.1", "11", "8", "1"],
];
const subMap = new Map(data.filter((d) => d[0] === "-").map((d) => [d[1], d]));
const additions = data.filter((d) => d[0] === "+");
const updates = additions.reduce((updates, addition) => {
const pkgName = addition[1];
const [maj, min, patch] = addition.slice(-3);
const [oldMaj, oldMin, oldPatch] = subMap.get(pkgName).slice(-3);
if (maj === oldMaj && min === oldMin && patch >= oldPatch) {
updates[pkgName] = "patch";
} else if (maj === oldMaj && min >= oldMin) {
updates[pkgName] = "minor";
} else {
updates[pkgName] = "major";
}
return updates;
}, {});
console.log(updates);