Skip to content

Commit

Permalink
Add an option to output the result as JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
yardnsm committed Mar 24, 2018
1 parent 132b536 commit b207905
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 9 deletions.
61 changes: 61 additions & 0 deletions __tests__/cli.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,41 @@ describe('CLI', () => {
expect(output).toMatch(`test
└── 1.0.0 (devDependencies, npm install test)`);
});

describe('JSON output', () => {
it('should output a single module version in JSON when using the --json flag', () => {
const cwd = resolveFixture('single-module');
const output = runCommand('test --json', { cwd });

expect(JSON.parse(output)).toMatchObject({
name: 'test',
version: '1.0.0',
});
});

it('should work with the --match options', () => {
const cwd = resolveFixture('single-module');
const output = runCommand('-m te --json', { cwd });

expect(JSON.parse(output)).toMatchObject([
{
name: 'test',
version: '1.0.0',
},
]);
});

it('should work with the --why option', () => {
const cwd = resolveFixture('single-module');
const output = runCommand('test --why --json', { cwd });

expect(JSON.parse(output)).toMatchObject({
name: 'test',
version: '1.0.0',
whyInfo: ['devDependencies', 'npm install test'],
});
});
});
});

describe('qnm list', () => {
Expand All @@ -64,5 +99,31 @@ test
└─┬ another
└── 1.0.0`);
});

it('should output results as JSON when providing the --json flag', () => {
const cwd = resolveFixture('mix-modules');
const output = runCommand('list --json-output', { cwd });

expect(JSON.parse(output)).toMatchObject([
{
name: '@scope/test',
version: '1.0.0',
},
{
name: 'another',
version: '1.0.0',
},
{
name: 'test',
version: '1.0.0',
dependents: [
{
name: 'another',
version: '1.0.0',
},
],
},
]);
});
});
});
7 changes: 7 additions & 0 deletions src/actions/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const isEmpty = require('lodash/isEmpty');
const getSuggestions = require('../suggest/get-suggestions');
const { notFoundModuleMessage } = require('../printer');
const renderModuleOccurrences = require('../render/render-module-occurrences');
const renderModuleOccurrencesJson = require('../render/render-module-occurrences-json');

module.exports = (workspace, name, options = {}) => {
const moduleOccurrences = workspace.getModuleOccurrences(name);
Expand All @@ -13,5 +14,11 @@ module.exports = (workspace, name, options = {}) => {
return notFoundModuleMessage(name, suggestions);
}

if (options.json) {
return JSON.stringify(
renderModuleOccurrencesJson(moduleOccurrences, options),
);
}

return renderModuleOccurrences(moduleOccurrences, options);
};
4 changes: 2 additions & 2 deletions src/actions/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ const isEmpty = require('lodash/isEmpty');
const { noModulesMessage } = require('../printer');
const renderModuleList = require('../render/render-module-list');

module.exports = workspace => {
module.exports = (workspace, options = {}) => {
const moduleOccurrencesList = workspace.list();

if (isEmpty(moduleOccurrencesList)) {
return noModulesMessage();
}

return renderModuleList(moduleOccurrencesList);
return renderModuleList(moduleOccurrencesList, options);
};
7 changes: 5 additions & 2 deletions src/actions/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ const isEmpty = require('lodash/isEmpty');
const { notMatchModuleMessage } = require('../printer');
const renderModuleList = require('../render/render-module-list');

module.exports = (workspace, match) => {
module.exports = (workspace, match, options = {}) => {
const moduleOccurrencesList = workspace.match(match);

if (isEmpty(moduleOccurrencesList)) {
return notMatchModuleMessage(match);
}

return renderModuleList(moduleOccurrencesList, { match });
return renderModuleList(moduleOccurrencesList, {
match,
json: options.json,
});
};
12 changes: 7 additions & 5 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ try {
.version(pkg.version)
.command('list')
.description('list all node_modules with their versions')
.action(() => {
.option('--json-output', 'output results as json')
.action(({ jsonOutput: json }) => {
const workspace = Workspace.loadSync();
console.log(listAction(workspace));
console.log(listAction(workspace, { json }));
});

program
Expand All @@ -28,6 +29,7 @@ try {
'-w, --why',
'add information regarding why this package was installed',
)
.option('--json', 'output results as json')
.option('-d, --debug', 'see full error messages, mostly for debugging');

program.parse(process.argv);
Expand All @@ -44,12 +46,12 @@ try {

if (!preDefinedCommands.includes(firstArg) && firstArg !== 'completion') {
const arg = program.args[0];
const { match, why } = program;
const { match, why, json } = program;

if (match) {
console.log(matchAction(workspace, arg));
console.log(matchAction(workspace, arg, { json }));
} else {
console.log(getAction(workspace, arg, { why }));
console.log(getAction(workspace, arg, { why, json }));
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/render/render-module-list.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const renderModuleOccurrences = require('./render-module-occurrences');
const renderModuleOccurrencesJson = require('./render-module-occurrences-json');

module.exports = (moduleOccurrencesList, options) => {
if (options.json) {
return JSON.stringify(
moduleOccurrencesList.map(([, moduleOccurrences]) =>
renderModuleOccurrencesJson(moduleOccurrences, options),
),
);
}

return moduleOccurrencesList
.map(([, moduleOccurrences]) =>
renderModuleOccurrences(moduleOccurrences, options),
Expand Down
51 changes: 51 additions & 0 deletions src/render/render-module-occurrences-json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const buildWithAncestors = (m, { why }) => {
let hierarchy = {
version: m.version,
};

if (why) {
hierarchy.whyInfo = m.whyInfo || [];
}

if (m.parent) {
let currentModule = m;

while (currentModule.parent) {
currentModule = currentModule.parent;

if (hierarchy.dependents) {
hierarchy = {
name: currentModule.name,
dependents: hierarchy,
};
} else {
hierarchy = {
name: currentModule.name,
...hierarchy,
};
}
}
}

return hierarchy;
};

module.exports = (moduleOccurrences, { why } = {}) => {
const buildedOccurrences = moduleOccurrences.map(m =>
buildWithAncestors(m, { why }),
);

const rootOccurrence = buildedOccurrences.find(
occurrence => !occurrence.dependents && !occurrence.name,
);

const result = {
name: moduleOccurrences[0].name,
...(rootOccurrence || {}),
dependents: buildedOccurrences.filter(
occurrence => occurrence !== rootOccurrence,
),
};

return result;
};

0 comments on commit b207905

Please sign in to comment.