Last active
November 1, 2023 14:34
-
-
Save robostheimer/9b5b6324e530fde35f2989515ba211a8 to your computer and use it in GitHub Desktop.
Node script that converts json files created from `rehearsal graph`(via `rehearsal-js`) running on any directories user supplies (i.e. packages, lib, app, tests, etc.) and creates a spreadsheet using `json2csv`, and `SheetsJS `.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Node script that converts json files created from `rehearsal graph`(via `rehearsal-js`) running on | |
* from user supplies (packages, lib, app, tests, etc.) and creates a spreadsheet using `json2csv`, and `SheetsJS `. | |
* It also exports png visualizations of your graph. | |
* Simply add a `graph-scripts` directory to the root of your ember app, add this gist. Run `node graph-to-spreadsheet.js` | |
* with a list of directories to graph individual directories inside of your app. | |
* | |
* NOTE, you will need to flag directories with subdirectories that should be graphed, by using `--subdirectories` | |
* flag (see examples below) to get the graph of all subdirectories inside of a root directory of your app/addon. | |
* | |
* run `node graph-scripts/graph-to-spreadsheet.js app,lib--subdirectories,packages--subdirectories,tests,mirage,test-package` | |
* to get graphs of your ember directories | |
* | |
* run `node graph-scripts/graph-to-spreadsheet.js app,lib--subdirectories,packages--subdirectories,tests,mirage,test-package --externals` | |
* to get graphs of your ember directories that includes packages external to your package (i.e. node_modules packages). | |
* | |
* run `node graph-scripts/graph-to-spreadsheet.js app,lib--subdirectories,packages--subdirectories,tests,mirage,test-packages --getDiff <path-to-spreadsheet-to-compare>` | |
* to compare your current graph to a previous graph | |
* | |
* run `node graph-scripts/graph-to-spreadsheet.js packages--subdirectories --withViz --getDiff <path-to-spreadsheet>` | |
* | |
* NOTE, for sheet-js to work, you will likely need to add `"sheetjs": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"` to your package.json | |
* | |
*/ | |
const fs = require('fs-extra'); | |
const { exec } = require('child_process'); | |
const rehearsal = (...args) => | |
import('@rehearsal/cli/dist/src/index.js').then(({ default: rehearsal }) => rehearsal(...args)); | |
const { | |
Parser, | |
transforms: { unwind, flatten } | |
} = require('json2csv'); | |
const { isEqual } = require('lodash'); | |
const XLSX = require('sheetjs'); | |
const process = require('process'); | |
const renderDot = (...args) => | |
import('render-dot/cli/dist/src/index.js').then(({ default: renderDot }) => renderDot(...args)); | |
const workBook = XLSX.utils.book_new(); | |
// need to refactor so ordering of the flags does not matter | |
const directoriesToGraph = process.argv[2].split(',') | |
const getDiff = process.argv.includes('--getDiff') ?? false | |
const indexOfDiffUrl = process.argv.indexOf('--getDiff') +1 | |
const previousWorkBook = getDiff ? XLSX.readFile(process.argv[indexOfDiffUrl]) : XLSX.utils.book_new(); | |
const withViz = process.argv.includes('--withViz') ?? false; | |
const withExternalModules = process.argv.includes('--externals') ?? false; | |
console.log(process.argv) | |
const changedWorkBook = XLSX.utils.book_new(); | |
const getGraphJSON = () => { | |
fs.readdir('./', (err, directories) => { | |
directoriesToGraph.forEach((directory, index) => { | |
if(directory.match('--subdirectories')) { | |
const directoryWoFlag = directory.replace('--subdirectories', ''); | |
fs.mkdirSync(`graph-scripts/json/${directoryWoFlag}`, { recursive: true }, (err) => {}); | |
fs.mkdirSync(`graph-scripts/dots/${directoryWoFlag}`, { recursive: true }, (err) => {}); | |
fs.mkdirSync(`graph-scripts/pngs/${directoryWoFlag}`, { recursive: true }, (err) => {}); | |
fs.readdir(directoryWoFlag, async (err, directories) => { | |
directories.forEach((subDirectory) => { | |
const executionString = withExternalModules | |
? `yarn rehearsal graph ${directoryWoFlag}/${subDirectory} -o ./graph-scripts/json/${directoryWoFlag}/${subDirectory}.json --externals` | |
: `yarn rehearsal graph ${directoryWoFlag}/${subDirectory} -o ./graph-scripts/json/${directoryWoFlag}/${subDirectory}.json`; | |
exec( | |
executionString, | |
(error, stdout, stderr) => { | |
if (err) { | |
console.log(`json_error: ${error.message}`); | |
return; | |
} | |
if (stderr) { | |
console.log(`json_stderr: ${stderr}`); | |
return; | |
} | |
console.log(`json_stdout: ${stdout}`); | |
parseJSONFile(`./graph-scripts/json/${directoryWoFlag}/${subDirectory}.json`); | |
} | |
); | |
if(withViz) { | |
exec( | |
`yarn rehearsal graph ${directoryWoFlag}/${subDirectory} -o ./graph-scripts/dots/${directoryWoFlag}/${subDirectory}.dot`, | |
(error, stdout, stderr) => { | |
if (err) { | |
console.log(`dot_error: ${error.message}`); | |
return; | |
} | |
if (stderr) { | |
console.log(`dot_stderr: ${stderr}`); | |
return; | |
} | |
console.log(`dot_stdout: ${stdout}`); | |
createPNG(`./graph-scripts/dots/${directoryWoFlag}/${subDirectory}.dot`, directoryWoFlag); | |
} | |
); | |
} | |
}); | |
}); | |
} else { | |
fs.mkdirSync(`graph-scripts/json`, { recursive: true }, (err) => {}); | |
fs.mkdirSync(`graph-scripts/dots`, { recursive: true }, (err) => {}); | |
fs.mkdirSync(`graph-scripts/pngs`, { recursive: true }, (err) => {}); | |
const executionString = withExternalModules ? `yarn rehearsal graph ${directory} -o ./graph-scripts/json/${directory}.json --externals` : `yarn rehearsal graph ${directory} -o ./graph-scripts/json/${directory}.json` | |
exec(executionString, (error, stdout, stderr) => { | |
if (err) { | |
console.log(`json_error: ${error.message}`); | |
return; | |
} | |
if (stderr) { | |
console.log(`json_stderr: ${stderr}`); | |
return; | |
} | |
console.log(`json_stdout: ${stdout}`); | |
parseJSONFile(`./graph-scripts/json/${directory}.json`); | |
}); | |
if(withViz) { | |
exec(`yarn rehearsal graph ${directory} -o ./graph-scripts/dots/${directory}.dot`, (error, stdout, stderr) => { | |
if (err) { | |
console.log(`dot_error: ${error.message}`); | |
return; | |
} | |
if (stderr) { | |
console.log(`dot_stderr: ${stderr}`); | |
return; | |
} | |
console.log(`dot_stdout: ${stdout}`); | |
createPNG(`./graph-scripts/dots/${directory}.dot`); | |
}); | |
} | |
} | |
}); | |
}); | |
}; | |
async function parseJSONFile(fileName) { | |
try { | |
const file = await fs.readFile(fileName); | |
const json = await JSON.parse(file); | |
arrayToCSV(json, fileName); | |
} catch (err) { | |
console.log(err); | |
process.exit(1); | |
} | |
} | |
async function createPNG(fileName, directory='') { | |
await exec( | |
`render-dot --input ${fileName} --output ./graph-scripts/pngs/${directory} --format png --quality -s ALLOW_MEMORY_GROWTH=1`, | |
(error, stdout, stderr) => { | |
if (error) { | |
console.log(`png_error: ${error.message}`); | |
return; | |
} | |
if (stderr) { | |
console.log(`png_stderr: ${stderr}`); | |
return; | |
} | |
console.log(`png_stdout: ${stdout}`); | |
} | |
); | |
} | |
async function arrayToCSV(data, fileName) { | |
fs.mkdirSync('./graph-scripts/xlsx', { recursive: true }, (err) => {}); | |
const json2csvParser = await new Parser({ transforms: [unwind({ paths: ['files', 'files.edges'] }), flatten('__')] }); | |
const csv = await json2csvParser.parse(data); | |
const readCSV = await XLSX.read(csv, { type: 'string' }); | |
const workSheet = readCSV.Sheets.Sheet1; | |
// sheetName cannot exceed 31 characters | |
const sheetName = fileName | |
.slice(fileName.lastIndexOf('/') + 1) | |
.replace(/.json/g, '') | |
.slice(0, 31); | |
const date = new Date(); | |
if(getDiff) { | |
const previousCSV = XLSX.utils.sheet_to_csv(previousWorkBook.Sheets[sheetName]); | |
if (!isEqual(previousCSV.toLowerCase().trim().replace(/"/g, ''), csv.toLowerCase().trim().replace(/"/g, ''))) { | |
XLSX.utils.book_append_sheet(changedWorkBook, workSheet, sheetName); | |
XLSX.writeFile( | |
changedWorkBook, | |
`./graph-scripts/xlsx/Diff_Graph_${date.getMonth() +1}_${date.getDate()}_${date.getFullYear()}.xlsx` | |
); | |
} | |
} | |
XLSX.utils.book_append_sheet(workBook, workSheet, sheetName); | |
XLSX.writeFile(workBook, `./graph-scripts/xlsx/Graph_${date.getMonth() + 1}_${date.getDate()}_${date.getFullYear()}.xlsx`); | |
} | |
async function writeCSV(fileName, data) { | |
try { | |
await fs.writeFile(fileName, data, 'utf8'); | |
} catch (err) { | |
console.log(err); | |
process.exit(1); | |
} | |
} | |
getGraphJSON(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment