Skip to content

Commit e324d03

Browse files
author
sparshithNR
committed
Allow csv output format
1 parent 2d12e9c commit e324d03

8 files changed

Lines changed: 190 additions & 38 deletions

File tree

bin/supported

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#!/usr/bin/env node
22
'use strict';
33
const ora = require('ora');
4+
const { writeFileSync } = require('fs');
45
const { displayResult } = require('../lib/output/cli-output');
6+
const { writeToCsv } = require('../lib/output/csv-output');
57

68
(async function main(cli) {
79
if (cli.input.length === 0) {
@@ -31,6 +33,11 @@ const { displayResult } = require('../lib/output/cli-output');
3133
2,
3234
),
3335
);
36+
} else if(cli.flags.csv && result) {
37+
let fileName = `${result.projectName}-support-audit.csv`;
38+
let filePath = `${projectPath}/${fileName}`;
39+
writeFileSync(filePath, writeToCsv(result), 'utf-8' );
40+
console.log(`Report created at ${filePath}`);
3441
} else {
3542
displayResult(result, cli.flags);
3643
}

lib/help.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = chalk`
1515
{cyan --unsupported, -u} outputs detailed report of unsupport packages only
1616
{cyan --expiring, -e} outputs detailed report of expiring packages only
1717
{cyan --supported, -s} outputs detailed report of support packages only
18+
{cyan --csv} outputs csv file in the project path
1819
{bold Examples}
1920
{gray $} {cyan supported ./path/to/project/}
2021
`;

lib/output/cli-output.js

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -291,24 +291,23 @@ function getHead(
291291

292292
/**
293293
*
294-
* @param {object} reportContent : processed details from the displayContent
295-
* @returns {string} formatted output for the support check run
294+
* @param {object} supportResult : support check result
295+
*
296296
*/
297-
function makeConsoleReport(reportContent) {
298-
const {
299-
body,
300-
isInSupportWindow,
301-
currentPolicy,
297+
function makeConsoleReport(supportResult, flags, supportMessage) {
298+
const isInSupportWindow = supportResult.isInSupportWindow;
299+
const currentPolicy = supportMessage ? supportMessage : DEFAULT_SUPPORT_MESSAGE();
300+
let {
302301
expiresSoon,
303302
unsupportedPackages,
304-
supportedPackages,
305303
nodePackage,
306304
emberPackage,
307-
} = reportContent;
305+
supportedPackages,
306+
} = getCategorisedList(supportResult.supportChecks);
308307

309-
let title = getTitle(isInSupportWindow, expiresSoon, nodePackage, emberPackage);
308+
const title = getTitle(isInSupportWindow, expiresSoon, nodePackage, emberPackage);
310309

311-
let head = getHead(
310+
const head = getHead(
312311
isInSupportWindow,
313312
unsupportedPackages,
314313
supportedPackages,
@@ -318,9 +317,13 @@ function makeConsoleReport(reportContent) {
318317
currentPolicy,
319318
);
320319

321-
return `${title}${head}
322-
${body}
323-
`;
320+
const body = getBodyContent(supportResult.supportChecks, flags);
321+
322+
return {
323+
title,
324+
head,
325+
body,
326+
};
324327
}
325328

326329
/**
@@ -413,36 +416,17 @@ function getCategorisedList(pkgList) {
413416
*
414417
*/
415418
function displayResult(supportResult, flags, supportMessage) {
416-
const title = supportResult.projectName;
417-
const isInSupportWindow = supportResult.isInSupportWindow;
418-
const currentPolicy = supportMessage ? supportMessage : DEFAULT_SUPPORT_MESSAGE();
419-
let {
420-
expiresSoon,
421-
unsupportedPackages,
422-
nodePackage,
423-
emberPackage,
424-
supportedPackages,
425-
} = getCategorisedList(supportResult.supportChecks);
419+
const { title, head, body } = makeConsoleReport(supportResult, flags, supportMessage);
426420

427-
console.log(
428-
makeConsoleReport({
429-
title,
430-
isInSupportWindow,
431-
body: getBodyContent(supportResult.supportChecks, flags),
432-
currentPolicy,
433-
expiresSoon,
434-
unsupportedPackages,
435-
supportedPackages,
436-
nodePackage,
437-
emberPackage,
438-
}),
439-
);
421+
console.log(`${title}${head}
422+
${body}`);
440423
}
441424

442425
module.exports = {
443426
displayResult,
444-
getBodyContent,
445427
getCategorisedList,
428+
getBodyContent,
446429
getHead,
447430
getTitle,
431+
makeConsoleReport,
448432
};

lib/output/csv-output.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
const { Parser } = require('json2csv');
4+
const stripAnsi = require('strip-ansi');
5+
const { makeConsoleReport } = require('./cli-output');
6+
const { MILLSINQUARTER } = require('../util');
7+
const { getQtrLocale } = require('./messages');
8+
9+
module.exports = {
10+
writeToCsv,
11+
};
12+
function writeToCsv(result, policyDetails) {
13+
const fields = [
14+
{
15+
label: 'Name',
16+
value: 'name',
17+
},
18+
{
19+
label: 'Supported',
20+
value: 'isSupported',
21+
},
22+
{
23+
label: 'Status',
24+
value: row => {
25+
if (!row.isSupported) {
26+
return `${row.type} version violated`;
27+
} else if (row.isSupported && row.duration) {
28+
return `${row.type ? row.type : ''} version expiring soon`;
29+
} else {
30+
return `up-to-date`;
31+
}
32+
},
33+
},
34+
{
35+
label: 'Unsupported Since/In',
36+
value: row => {
37+
if (row.duration) {
38+
const qtrs = Math.ceil(row.duration / MILLSINQUARTER);
39+
return `${qtrs} ${getQtrLocale(qtrs)}`;
40+
} else {
41+
return `-`;
42+
}
43+
},
44+
},
45+
{
46+
label: 'Resolved Version',
47+
value: 'resolvedVersion',
48+
},
49+
{
50+
label: 'Latest Version',
51+
value: 'latestVersion',
52+
},
53+
];
54+
55+
const json2csvParser = new Parser({ fields });
56+
const csv = json2csvParser.parse(result.supportChecks);
57+
const { title, head } = makeConsoleReport(result, {}, policyDetails);
58+
const fileContent = `${stripAnsi(title)}${stripAnsi(head)}
59+
60+
${csv}
61+
`;
62+
return fileContent;
63+
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"debug": "^4.3.1",
4747
"execa": "^5.0.0",
4848
"ini": "^1.3.7",
49+
"json2csv": "^5.0.6",
4950
"meow": "^8.0.0",
5051
"minipass-fetch": "^1.3.2",
5152
"moment": "^2.29.1",
@@ -56,6 +57,7 @@
5657
"parse-package-name": "^0.1.0",
5758
"promise.allsettled": "^1.0.4",
5859
"semver": "^7.3.4",
60+
"strip-ansi": "^6.0.0",
5961
"terminal-link": "^2.1.1"
6062
},
6163
"files": [

tests/cli-test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const { expect } = require('chai');
44
const execa = require('execa');
55
const { getBinPath } = require('get-bin-path');
6+
const fs = require('fs');
67
const registries = require('./registries');
78

89
async function runSupportedCmd(inputArgs) {
@@ -145,6 +146,20 @@ describe('CLI', function () {
145146
);
146147
});
147148
});
149+
describe('--csv', function () {
150+
afterEach(function () {
151+
let filePath = `${__dirname}/fixtures/unsupported-project/unsupported-project-support-audit.csv`;
152+
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
153+
});
154+
it('works against a unsupported project', async function () {
155+
const child = await runSupportedCmd([`${__dirname}/fixtures/unsupported-project`, '--csv']);
156+
expect(child.exitCode).to.eql(1);
157+
expect(child.stderr).to.eql('- working');
158+
expect(child.stdout).to.includes(
159+
`Report created at ${__dirname}/fixtures/unsupported-project`,
160+
);
161+
});
162+
});
148163
describe('--json', function () {
149164
it('works against a fully supported project', async function () {
150165
const child = await runSupportedCmd([`${__dirname}/fixtures/supported-project`, '--json']);

tests/csv-output-test.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
const { expect } = require('chai');
4+
const { writeToCsv } = require('../lib/output/csv-output');
5+
6+
describe('csv', function () {
7+
it('supported project', function () {
8+
let supportResult = {
9+
projectName: 'example',
10+
isInSupportWindow: true,
11+
supportChecks: [
12+
{
13+
isSupported: true,
14+
latestVersion: '4.8.5',
15+
name: 'rsvp',
16+
resolvedVersion: '4.8.5',
17+
},
18+
{
19+
isSupported: true,
20+
name: 'node',
21+
resolvedVersion: '15.3.0',
22+
latestVersion: '>=14.*',
23+
message: '',
24+
},
25+
],
26+
};
27+
let result = writeToCsv(supportResult);
28+
expect(result).to.includes(`✓ Congrats!
29+
Your project is using only supported versions of libraries. No action is required.`);
30+
});
31+
it('unsupported project', function () {
32+
let supportResult = {
33+
projectName: 'example',
34+
isInSupportWindow: false,
35+
supportChecks: [
36+
{
37+
isSupported: false,
38+
latestVersion: '4.8.5',
39+
name: 'rsvp',
40+
resolvedVersion: '4.5.5',
41+
},
42+
{
43+
isSupported: true,
44+
name: 'node',
45+
resolvedVersion: '15.3.0',
46+
latestVersion: '>=14.*',
47+
message: '',
48+
},
49+
],
50+
};
51+
let result = writeToCsv(supportResult);
52+
expect(result).to.includes(`Support Policy Problem Detected!
53+
Please upgrade your dependencies!
54+
Your project is not within the support policy window because of outdated dependencies.`);
55+
});
56+
});

yarn.lock

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,11 @@ color-name@~1.1.4:
455455
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
456456
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
457457

458+
commander@^6.1.0:
459+
version "6.2.1"
460+
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
461+
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
462+
458463
concat-map@0.0.1:
459464
version "0.0.1"
460465
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -1471,6 +1476,15 @@ json-stable-stringify-without-jsonify@^1.0.1:
14711476
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
14721477
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
14731478

1479+
json2csv@^5.0.6:
1480+
version "5.0.6"
1481+
resolved "https://registry.yarnpkg.com/json2csv/-/json2csv-5.0.6.tgz#590e0e1b9579e59baa53bda0c0d840f4d8009687"
1482+
integrity sha512-0/4Lv6IenJV0qj2oBdgPIAmFiKKnh8qh7bmLFJ+/ZZHLjSeiL3fKKGX3UryvKPbxFbhV+JcYo9KUC19GJ/Z/4A==
1483+
dependencies:
1484+
commander "^6.1.0"
1485+
jsonparse "^1.3.1"
1486+
lodash.get "^4.4.2"
1487+
14741488
jsonparse@^1.3.1:
14751489
version "1.3.1"
14761490
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@@ -1592,6 +1606,16 @@ locate-path@^6.0.0:
15921606
dependencies:
15931607
p-locate "^5.0.0"
15941608

1609+
lodash.get@^4.4.2:
1610+
version "4.4.2"
1611+
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
1612+
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
1613+
1614+
lodash.toarray@^4.4.0:
1615+
version "4.4.0"
1616+
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
1617+
integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE=
1618+
15951619
lodash@^4.17.14, lodash@^4.17.19:
15961620
version "4.17.20"
15971621
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"

0 commit comments

Comments
 (0)