handle multiple version of the same package, new JSON format

JSON `results` format has changed and now includes keys for each
dependency type.

Fixes #29
This commit is contained in:
silverwind 2019-09-08 21:50:57 +02:00
parent 44fb393293
commit 25c1db6b1a
Signed by: silverwind
GPG Key ID: 2E62B41C93869443
4 changed files with 258 additions and 202 deletions

@ -77,20 +77,22 @@ The JSON output is an object with possible properties `results`, `message` and `
$ updates -j | jq
{
"results": {
"string-width": {
"old": "2.1.1",
"new": "3.0.0",
"info": "https://github.com/sindresorhus/string-width"
},
"eslint": {
"old": "5.9.0",
"new": "5.10.0",
"info": "https://github.com/eslint/eslint"
},
"eslint-config-silverwind": {
"old": "2.0.11",
"new": "2.0.12",
"info": "https://github.com/silverwind/eslint-config-silverwind"
"dependencies": {
"string-width": {
"old": "2.1.1",
"new": "3.0.0",
"info": "https://github.com/sindresorhus/string-width"
},
"eslint": {
"old": "5.9.0",
"new": "5.10.0",
"info": "https://github.com/eslint/eslint"
},
"eslint-config-silverwind": {
"old": "2.0.11",
"new": "2.0.12",
"info": "https://github.com/silverwind/eslint-config-silverwind"
}
}
}
}

370
test.js

@ -19,200 +19,238 @@ async function run(args) {
async function main() {
assert.deepStrictEqual(await run("-j -f test.json"), {
results: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
dependencies: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
},
"prismjs": {
old: "1.0.0",
new: "1.17.1",
info: "https://github.com/LeaVerou/prism",
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.2.0-beta",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
},
"prismjs": {
old: "1.0.0",
new: "1.17.1",
info: "https://github.com/LeaVerou/prism",
peerDependencies: {
"@babel/preset-env": {
"old": "~6.0.0",
"new": "~7.6.0",
"info": "https://github.com/babel/babel/tree/master/packages/babel-preset-env"
}
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.2.0-beta",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
}
});
assert.deepStrictEqual(await run("-j -g -f test.json"), {
results: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
dependencies: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
},
"prismjs": {
old: "1.0.0",
new: "9000.0.1",
info: "https://github.com/LeaVerou/prism",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
},
"prismjs": {
old: "1.0.0",
new: "9000.0.1",
info: "https://github.com/LeaVerou/prism",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
peerDependencies: {
"@babel/preset-env": {
"old": "~6.0.0",
"new": "~7.6.0",
"info": "https://github.com/babel/babel/tree/master/packages/babel-preset-env"
}
}
}
});
assert.deepStrictEqual(await run("-j -g -p -f test.json"), {
results: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
dependencies: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
},
"prismjs": {
old: "1.0.0",
new: "9000.0.1",
info: "https://github.com/LeaVerou/prism",
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.2.0-beta",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
},
"prismjs": {
old: "1.0.0",
new: "9000.0.1",
info: "https://github.com/LeaVerou/prism",
peerDependencies: {
"@babel/preset-env": {
"old": "~6.0.0",
"new": "~7.6.0",
"info": "https://github.com/babel/babel/tree/master/packages/babel-preset-env"
}
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.2.0-beta",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "5.0.0-beta.8-groupsizefix",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
}
});
assert.deepStrictEqual(await run("-j -R -f test.json"), {
results: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
dependencies: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.6.5",
info: "https://github.com/gulp-sourcemaps/gulp-sourcemaps",
},
"prismjs": {
old: "1.0.0",
new: "1.17.1",
info: "https://github.com/LeaVerou/prism",
},
"svgstore": {
old: "^3.0.0",
new: "^2.0.3",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "3.2.0",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "4.3.2",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
},
"prismjs": {
old: "1.0.0",
new: "1.17.1",
info: "https://github.com/LeaVerou/prism",
peerDependencies: {
"@babel/preset-env": {
"old": "~6.0.0",
"new": "~7.6.0",
"info": "https://github.com/babel/babel/tree/master/packages/babel-preset-env"
}
},
"svgstore": {
old: "^3.0.0",
new: "^2.0.3",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "3.2.0",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
},
"jpeg-buffer-orientation": {
old: "0.0.0",
new: "2.0.1",
info: "https://github.com/fisker/jpeg-buffer-orientation",
},
"styled-components": {
old: "2.5.0-1",
new: "4.3.2",
info: "https://github.com/styled-components/styled-components",
},
"@babel/preset-env": {
old: "7.0.0",
new: "7.6.0",
info: "https://github.com/babel/babel/tree/master/packages/babel-preset-env",
}
}
});
assert.deepStrictEqual(await run("-j -P -f test.json"), {
results: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.0.1",
info: "https://github.com/floridoo/gulp-sourcemaps",
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
dependencies: {
"gulp-sourcemaps": {
old: "2.0.0",
new: "2.0.1",
info: "https://github.com/floridoo/gulp-sourcemaps",
},
"svgstore": {
old: "^3.0.0",
new: "^3.0.0-2",
info: "https://github.com/svgstore/svgstore",
},
"html-webpack-plugin": {
old: "4.0.0-alpha.2",
new: "4.0.0-beta.8",
info: "https://github.com/jantimon/html-webpack-plugin",
},
"noty": {
old: "3.1.0",
new: "3.1.4",
info: "https://github.com/needim/noty",
},
},
}
});

@ -8,5 +8,8 @@
"jpeg-buffer-orientation": "0.0.0",
"styled-components": "2.5.0-1",
"@babel/preset-env": "7.0.0"
},
"peerDependencies": {
"@babel/preset-env": "~6.0.0"
}
}

@ -175,7 +175,7 @@ for (const key of dependencyTypes) {
for (const name of names) {
const old = pkg[key][name];
if (isValidSemverRange(old)) {
deps[name] = {old};
deps[`${key}|${name}`] = {old};
}
}
}
@ -238,7 +238,7 @@ function fetchFromRegistry(name, registry, auth) {
return fetch(`${registry}/${name}`, opts);
}
const get = async (name, originalRegistry) => {
const get = async (name, type, originalRegistry) => {
const [auth, registry] = getAuthAndRegistry(name, originalRegistry);
let res;
@ -248,7 +248,7 @@ const get = async (name, originalRegistry) => {
if (registry === defaultRegistry) throw err;
}
if (res && res.ok) {
return [await res.json(), registry];
return [await res.json(), type, registry];
} else if (res && res.status && res.statusText && registry === defaultRegistry) {
throw new Error(`Received ${res.status} ${res.statusText} for ${name}`);
}
@ -258,7 +258,7 @@ const get = async (name, originalRegistry) => {
if (registry !== defaultRegistry) {
res = await fetchFromRegistry(name, defaultRegistry);
if (res && res.ok) {
return [await res.json(), registry];
return [await res.json(), type, registry];
} else if (res && res.status && res.statusText) {
throw new Error(`Received ${res.status} ${res.statusText} for ${name}`);
}
@ -278,8 +278,11 @@ const getInfoUrl = ({repository, homepage}, registry, name) => {
return homepage || "";
};
Promise.all(Object.keys(deps).map(name => get(name, registry))).then(dati => {
for (const [data, registry] of dati) {
Promise.all(Object.keys(deps).map(key => {
const [type, name] = key.split("|");
return get(name, type, registry);
})).then(dati => {
for (const [data, type, registry] of dati) {
if (data && data.error) {
throw new Error(data.error);
}
@ -297,15 +300,16 @@ Promise.all(Object.keys(deps).map(name => get(name, registry))).then(dati => {
semvers = ["patch", "minor", "major"];
}
const oldRange = deps[data.name].old;
const key = `${type}|${data.name}`;
const oldRange = deps[key].old;
const newVersion = findNewVersion(data, {usePre, useRel, useGreatest, semvers, range: oldRange});
const newRange = updateRange(oldRange, newVersion);
if (!newVersion || oldRange === newRange) {
delete deps[data.name];
delete deps[key];
} else {
deps[data.name].new = newRange;
deps[data.name].info = getInfoUrl(data.versions[newVersion] || data, registry, data.name);
deps[key].new = newRange;
deps[key].info = getInfoUrl(data.versions[newVersion] || data, registry, data.name);
}
}
@ -318,7 +322,7 @@ Promise.all(Object.keys(deps).map(name => get(name, registry))).then(dati => {
}
try {
write(packageFile, updatePkg());
write(packageFile, updatePackageJson());
} catch (err) {
finish(new Error(`Error writing ${packageFile}: ${err.message}`));
}
@ -341,7 +345,12 @@ function finish(obj, opts = {}) {
if (args.json) {
if (!hadError) {
output.results = deps;
output.results = {};
for (const [key, value] of Object.entries(deps)) {
const [type, name] = key.split("|");
if (!output.results[type]) output.results[type] = {};
output.results[type][name] = value;
}
}
console.info(JSON.stringify(output));
} else {
@ -411,12 +420,15 @@ function highlightDiff(a, b, added) {
function formatDeps() {
const arr = [["NAME", "OLD", "NEW", "INFO"]];
for (const [name, data] of Object.entries(deps)) arr.push([
name,
highlightDiff(data.old, data.new, false),
highlightDiff(data.new, data.old, true),
data.info,
]);
for (const [key, data] of Object.entries(deps)) {
const [_type, name] = key.split("|");
arr.push([
name,
highlightDiff(data.old, data.new, false),
highlightDiff(data.new, data.old, true),
data.info,
]);
}
return require("text-table")(arr, {
hsep: " ".repeat(2),
@ -424,12 +436,13 @@ function formatDeps() {
});
}
function updatePkg() {
function updatePackageJson() {
let newPkgStr = pkgStr;
for (const dep of Object.keys(deps)) {
const re = new RegExp(`"${esc(dep)}": +"${esc(deps[dep].old)}"`, "g");
newPkgStr = newPkgStr.replace(re, `"${dep}": "${deps[dep].new}"`);
for (const key of Object.keys(deps)) {
const [_type, name] = key.split("|");
const re = new RegExp(`"${esc(name)}": +"${esc(deps[key].old)}"`, "g");
newPkgStr = newPkgStr.replace(re, `"${name}": "${deps[key].new}"`);
}
return newPkgStr;