Merge pull request #11165 from jankapunkt/list-tree-json

This commit is contained in:
Filipe Névola
2020-10-31 11:45:21 -04:00
committed by GitHub
3 changed files with 135 additions and 18 deletions

View File

@@ -1139,7 +1139,9 @@ main.registerCommand({
requiresApp: true,
options: {
'tree': { type: Boolean },
'json': { type: Boolean },
'weak': { type: Boolean },
'details': { type: Boolean },
'allow-incompatible-update': { type: Boolean }
},
catalogRefresh: new catalog.Refresh.OnceAtStart({ ignoreErrors: true })
@@ -1154,8 +1156,25 @@ main.registerCommand({
// No need to display the PackageMapDelta here, since we're about to list all
// of the packages anyway!
if (options['tree']) {
const showJson = !!options['json'];
const showTree = !!options['tree'];
const suffixes = {
topLevel: '(top level)',
expandedAbove: '(expanded above)',
weak: '[weak]',
skipped: 'package skipped',
missing: 'missing?'
}
if (showJson && showTree) {
throw new Error('can only run for one option,found --json and --tree');
}
if (showTree || showJson) {
const jsonOut = showJson && {};
const showWeak = !!options['weak'];
const showDetails = !!options['details'];
// Load package details of all used packages (inc. dependencies)
const packageDetails = new Map;
projectContext.packageMap.eachPackage(function (name, info) {
@@ -1172,7 +1191,7 @@ main.registerCommand({
const dontExpand = new Set(topLevelSet.values());
// Recursive function that outputs each package
const printPackage = function (packageToPrint, isWeak, indent1, indent2) {
const printPackage = function ({ packageToPrint, isWeak, indent1, indent2, parent }) {
const packageName = packageToPrint.packageName;
const depsObj = packageToPrint.dependencies || {};
let deps = Object.keys(depsObj).sort();
@@ -1192,16 +1211,59 @@ main.registerCommand({
const expandedAlready = (deps.length > 0 && dontExpand.has(packageName));
const shouldExpand = (deps.length > 0 && !expandedAlready && !isWeak);
if (indent1 !== '') {
indent1 += (shouldExpand ? '┬' : '─') + ' ';
// with normal tree display we send the current info to stdout
if (showTree) {
if (indent1 !== '') {
indent1 += (shouldExpand ? '┬' : '─') + ' ';
}
let suffix = (isWeak ? suffixes.weak : '');
if (expandedAlready) {
suffix += topLevelSet.has(packageName)
? ` ${suffixes.topLevel}`
: ` ${suffixes.expandedAbove}`
}
Console.info(indent1 + packageName + '@' + packageToPrint.version + suffix);
}
let suffix = (isWeak ? '[weak]' : '');
if (expandedAlready) {
suffix += topLevelSet.has(packageName) ? ' (top level)' : ' (expanded above)';
// with json we add detailed info to the json object
if (showJson) {
if (expandedAlready) {
// on expanded packages we only want to add minimal information to
// keep the json file compact, so we make the value a stirng
if (topLevelSet.has(packageName)) {
parent[packageName] = `${packageToPrint.version}-${suffixes.topLevel}`
} else {
parent[packageName] = `${packageToPrint.version}-${suffixes.expandedAbove}`
}
} else {
// on non-expanded packages we want detailed information but we
// omit falsy values in order to keep the output minimal and readable
const entry = {};
parent[packageName] = entry;
const mapInfo = projectContext.packageMap.getInfo(packageName);
const infoSource = Object.assign({}, showDetails ? packageToPrint : {}, {
version: packageToPrint.version,
local: mapInfo && mapInfo.kind === 'local',
weak: isWeak,
newerVersion: getNewerVersion(packageName, packageToPrint.version, catalog.official)
});
Object.entries(infoSource).forEach(([key, value]) => {
if (value) {
entry[key] = value;
}
});
if (shouldExpand) {
entry.dependencies = {};
}
}
}
Console.info(indent1 + packageName + '@' + packageToPrint.version + suffix);
if (shouldExpand) {
dontExpand.add(packageName);
deps.forEach((dep, index) => {
@@ -1209,14 +1271,37 @@ main.registerCommand({
const weakRef = references.length > 0 && references.every(r => r.weak);
const last = ((index + 1) === deps.length);
const child = packageDetails.get(dep);
const newIndent1 = indent2 + (last ? '└─' : '├─');
const newIndent2 = indent2 + (last ? ' ' : '│ ');
if (child) {
printPackage(child, weakRef, newIndent1, newIndent2);
} else if (weakRef) {
Console.info(newIndent1 + '─ ' + dep + '[weak] package skipped');
} else {
Console.info(newIndent1 + '─ ' + dep + ' missing?');
// with normal tree display we increase indentation
if (showTree) {
const newIndent1 = indent2 + (last ? '└─' : '├─');
const newIndent2 = indent2 + (last ? ' ' : '│ ');
if (child) {
printPackage({
packageToPrint: child,
isWeak: weakRef,
indent1: newIndent1,
indent2: newIndent2
});
} else if (weakRef) {
Console.info(`${newIndent1}${dep} ${suffixes.weak} ${suffixes.skipped}`);
} else {
Console.info(`${newIndent1}${dep} ${suffixes.missing}`);
}
}
if (showJson) {
if (child) {
printPackage({
packageToPrint: child,
isWeak: weakRef,
parent: parent[packageName].dependencies
});
} else if (weakRef) {
parent[packageName].dependencies[dep] = `${suffixes.weak} ${suffixes.skipped}`;
} else {
parent[packageName].dependencies = suffixes.missing;
}
}
});
}
@@ -1228,10 +1313,23 @@ main.registerCommand({
if (topLevelPackage) {
// Force top level packages to be expanded
dontExpand.delete(topLevelPackage.packageName);
printPackage(topLevelPackage, false, '', '');
printPackage({
packageToPrint: topLevelPackage,
isWeak: false,
indent1: '',
indent2: '',
parent: jsonOut
})
}
});
if (showJson) {
// we can't use Console here, because it pretty prints the output with
// a wrap at 80 chars per line, which causes the json to break if details
// options is active and the package descriptions exceed the limit
console.info(JSON.stringify(jsonOut));
}
return 0;
}

View File

@@ -289,13 +289,17 @@ Options:
List the packages explicitly used by your project.
Usage: meteor list
meteor list --tree [--weak]
meteor list --json [--weak] [--details]
Lists the packages that you have explicitly added to your project.
Transitive dependencies are not listed unless you use the --tree option,
which outputs a tree showing how packages are referenced.
Use the --json option to output the tree in JSON format.
Options:
--weak Show weakly referenced dependencies in the tree.
--details Adds more package details to the JSON output.
>>> add-platform
Add a platform to this project.

View File

@@ -347,10 +347,25 @@ selftest.define("argument parsing", function () {
s.createApp('myapp', 'standard-app');
s.cd('myapp', function () {
run = s.run("list");
run.waitSecs(60);
run.waitSecs(20);
run.expectExit(0);
});
s.cd('myapp', function () {
run = s.run("list", "--tree");
run.waitSecs(20);
run.match("├─┬")
run.match("│ ├─┬")
run.expectExit(0);
})
s.cd('myapp', function () {
run = s.run("list", "--json");
run.waitSecs(20);
run.match(/[{}"a-zA-Z0-9,\s\n\r:_.()\[\]]+/)
run.expectExit(0);
})
s.createApp("app-with-extra-packages", "extra-packages-option", {
dontPrepareApp: true
});