Roadmap to becoming a developer in 2022
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

const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/best-practices');
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);
}
function prepareDirTree(control, dirTree) {
// 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
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) {
return;
}
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlName.split(':');
// 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) => {
prepareDirTree(childControl, dirTree);
});
}
return { dirTree };
}
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating
const dirTree = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree);
});
/**
* @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
*/
function createDirTree(parentDir, dirTree, filePaths = {}) {
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
createDirTree(bestPracticeContentDirPath, dirTree);
console.log('Created best practice content directory structure');