computer-scienceangular-roadmapbackend-roadmapblockchain-roadmapdba-roadmapdeveloper-roadmapdevops-roadmapfrontend-roadmapgo-roadmaphactoberfestjava-roadmapjavascript-roadmapnodejs-roadmappython-roadmapqa-roadmapreact-roadmaproadmapstudy-planvue-roadmapweb3-roadmap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.4 KiB
144 lines
4.4 KiB
2 years ago
|
const fs = require('fs');
|
||
|
const path = require('path');
|
||
|
|
||
|
const CONTENT_DIR = path.join(__dirname, '../content');
|
||
|
// Directory containing the best-practices
|
||
2 years ago
|
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/data/best-practices');
|
||
2 years ago
|
const bestPracticeId = process.argv[2];
|
||
|
|
||
|
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
|
||
|
if (!bestPracticeId) {
|
||
|
console.error('bestPractice is required');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
if (!allowedBestPracticeId.includes(bestPracticeId)) {
|
||
|
console.error(`Invalid best practice key ${bestPracticeId}`);
|
||
|
console.error(`Allowed keys are ${allowedBestPracticeId.join(', ')}`);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
// Directory holding the best parctice content files
|
||
|
const bestPracticeDirName = fs
|
||
|
.readdirSync(BEST_PRACTICE_CONTENT_DIR)
|
||
|
.find((dirName) => dirName.replace(/\d+-/, '') === bestPracticeId);
|
||
|
|
||
|
if (!bestPracticeDirName) {
|
||
|
console.error('Best practice directory not found');
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
|
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName);
|
||
|
const bestPracticeContentDirPath = path.join(
|
||
|
BEST_PRACTICE_CONTENT_DIR,
|
||
|
bestPracticeDirName,
|
||
|
'content'
|
||
|
);
|
||
|
|
||
|
// If best practice content already exists do not proceed as it would override the files
|
||
|
if (fs.existsSync(bestPracticeContentDirPath)) {
|
||
|
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`);
|
||
|
process.exit(1);
|
||
|
}
|
||
|
|
||
2 years ago
|
function prepareDirTree(control, dirTree) {
|
||
2 years ago
|
// Directories are only created for groups
|
||
|
if (control.typeID !== '__group__') {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// e.g. 104-testing-your-apps:other-options
|
||
|
const controlName = control?.properties?.controlName || '';
|
||
|
|
||
|
// No directory for a group without control name
|
||
2 years ago
|
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) {
|
||
2 years ago
|
return;
|
||
|
}
|
||
|
|
||
|
// e.g. ['testing-your-apps', 'other-options']
|
||
2 years ago
|
const dirParts = controlName.split(':');
|
||
2 years ago
|
|
||
|
// Nest the dir path in the dirTree
|
||
|
let currDirTree = dirTree;
|
||
|
dirParts.forEach((dirPart) => {
|
||
|
currDirTree[dirPart] = currDirTree[dirPart] || {};
|
||
|
currDirTree = currDirTree[dirPart];
|
||
|
});
|
||
|
|
||
|
const childrenControls = control.children.controls.control;
|
||
|
// No more children
|
||
|
if (childrenControls.length) {
|
||
|
childrenControls.forEach((childControl) => {
|
||
2 years ago
|
prepareDirTree(childControl, dirTree);
|
||
2 years ago
|
});
|
||
|
}
|
||
|
|
||
2 years ago
|
return { dirTree };
|
||
2 years ago
|
}
|
||
|
|
||
|
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
|
||
|
const controls = bestPractice.mockup.controls.control;
|
||
|
|
||
2 years ago
|
// Prepare the dir tree that we will be creating
|
||
2 years ago
|
const dirTree = {};
|
||
|
|
||
|
controls.forEach((control) => {
|
||
2 years ago
|
prepareDirTree(control, dirTree);
|
||
2 years ago
|
});
|
||
|
|
||
|
/**
|
||
|
* @param parentDir Parent directory in which directory is to be created
|
||
|
* @param dirTree Nested dir tree to be created
|
||
|
* @param filePaths The mapping from groupName to file path
|
||
|
*/
|
||
2 years ago
|
function createDirTree(parentDir, dirTree, filePaths = {}) {
|
||
2 years ago
|
const childrenDirNames = Object.keys(dirTree);
|
||
|
const hasChildren = childrenDirNames.length !== 0;
|
||
|
|
||
|
// @todo write test for this, yolo for now
|
||
|
const groupName = parentDir
|
||
|
.replace(bestPracticeContentDirPath, '') // Remove base dir path
|
||
|
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
|
||
|
.replaceAll('/', ':') // Replace slashes with `:`
|
||
|
.replace(/:\d+-/, ':');
|
||
|
|
||
|
const humanizedGroupName = groupName
|
||
|
.split(':')
|
||
|
.pop()
|
||
|
?.replaceAll('-', ' ')
|
||
|
.replace(/^\w/, ($0) => $0.toUpperCase());
|
||
|
|
||
|
// If no children, create a file for this under the parent directory
|
||
|
if (!hasChildren) {
|
||
|
let fileName = `${parentDir}.md`;
|
||
|
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
|
||
|
|
||
|
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
|
||
|
return filePaths;
|
||
|
}
|
||
|
|
||
|
// There *are* children, so create the parent as a directory
|
||
|
// and create `index.md` as the content file for this
|
||
|
fs.mkdirSync(parentDir);
|
||
|
|
||
|
let readmeFilePath = path.join(parentDir, 'index.md');
|
||
|
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
|
||
|
|
||
|
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
|
||
|
|
||
|
// For each of the directory names, create a
|
||
|
// directory inside the given directory
|
||
|
childrenDirNames.forEach((dirName) => {
|
||
|
createDirTree(
|
||
|
path.join(parentDir, dirName),
|
||
|
dirTree[dirName],
|
||
|
filePaths
|
||
|
);
|
||
|
});
|
||
|
|
||
|
return filePaths;
|
||
|
}
|
||
|
|
||
|
// Create directories and get back the paths for created directories
|
||
2 years ago
|
createDirTree(bestPracticeContentDirPath, dirTree);
|
||
2 years ago
|
console.log('Created best practice content directory structure');
|