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.
120 lines
4.8 KiB
120 lines
4.8 KiB
const fs = require('fs'); |
|
const path = require('path'); |
|
|
|
// 1 - Renames each readme.md to index.md |
|
// e.g. |
|
// before => roadmaps/frontend/content/internet/readme.md |
|
// after => roadmaps/frontend/content/internet/index.md |
|
// |
|
// 2 - Replaces the resource tags with short codes |
|
// e.g. |
|
// <ResourceGroupTitle>Free Content</ResourceGroupTitle> |
|
// <BadgeLink colorScheme='yellow' badgeText='Read' href='https://www.w3schools.com/css/'>W3Schools — Learn CSS</BadgeLink> |
|
// |
|
// {% resources %} |
|
// {% Blog "https://www.w3schools.com/css/", "W3Schools — Learn CSS" %} |
|
// {% endresources %} |
|
// |
|
// 3 - Removes the index.md file from within the content dir i.e. to avoid `/frontend` permalink for `/frontend/index.md` |
|
// Because we have the `/frontend` permalink serving the actual roadmap and not any content |
|
const roadmapsDir = path.join(__dirname, '../src/roadmaps'); |
|
const roadmapDirs = fs.readdirSync(roadmapsDir); |
|
|
|
roadmapDirs.forEach((roadmapDirName) => { |
|
const roadmapDirPath = path.join(roadmapsDir, roadmapDirName); |
|
const contentDirPath = path.join(roadmapDirPath, 'content'); |
|
|
|
console.log(`[Start] == Migrating ${roadmapDirName}`); |
|
|
|
if (!fs.existsSync(contentDirPath)) { |
|
console.log(`Content dir not found ${roadmapDirName}/content`); |
|
return; |
|
} |
|
|
|
function handleContentDir(parentDirPath) { |
|
const dirChildrenNames = fs.readdirSync(parentDirPath); |
|
|
|
dirChildrenNames.forEach((dirChildName) => { |
|
let dirChildPath = path.join(parentDirPath, dirChildName); |
|
|
|
// If directory, handle the children for it |
|
if (fs.lstatSync(dirChildPath).isDirectory()) { |
|
handleContentDir(dirChildPath); |
|
} |
|
|
|
////////////////////////////////////////////////////////// |
|
// 1 - Rename directories to remove the numbers |
|
////////////////////////////////////////////////////////// |
|
// let newDirChildPath = path.join( |
|
// path.dirname(dirChildPath), |
|
// path.basename(dirChildPath).replace(/^\d+-/, '') |
|
// ); |
|
// fs.renameSync(dirChildPath, dirChildPath); |
|
|
|
////////////////////////////////////////////////////////// |
|
// 1 - Rename readme.md to index.md |
|
////////////////////////////////////////////////////////// |
|
if (dirChildPath.endsWith('readme.md')) { |
|
const newFilePath = path.join(path.dirname(dirChildPath), `index.md`); |
|
|
|
fs.renameSync(dirChildPath, newFilePath); |
|
dirChildPath = newFilePath; |
|
} |
|
|
|
////////////////////////////////////////////////////////// |
|
// 2 - Replace the resource tags with short codes |
|
////////////////////////////////////////////////////////// |
|
if (fs.lstatSync(dirChildPath).isFile()) { |
|
const fileContent = fs.readFileSync(dirChildPath, 'utf-8'); |
|
|
|
let resourceLinks = [...fileContent.matchAll(/<BadgeLink.+<\/BadgeLink>/g)].map(([fullMatch]) => { |
|
// const resourceType = fullMatch.match(/badgeText=["'](.+?)["']/)[1]; |
|
const link = fullMatch.match(/href=["'](.+?)["']/)[1]; |
|
const text = fullMatch.match(/>([^<]+)<\/BadgeLink>$/)[1]; |
|
|
|
return `- [${text.replaceAll(/['"]/g, '')}](${link})`; |
|
}); |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Replace the dedicated roadmap tag with the short code |
|
////////////////////////////////////////////////////////////////////// |
|
// prettier-ignore |
|
const dedicatedRegex = /<DedicatedRoadmap\s*href=['"](.+?)['"]\s*title=['"](.+?)['"]\s*description=['"].+?['"]\s*\/>/; |
|
const dedicatedMatches = fileContent.match(dedicatedRegex); |
|
|
|
if (dedicatedMatches) { |
|
const [, href, title] = dedicatedMatches; |
|
|
|
resourceLinks = [`- [Visit Dedicated ${title}](${href})`, ...resourceLinks]; |
|
} |
|
|
|
resourceLinks = ['Visit the following resources to learn more:\n', ...resourceLinks]; |
|
resourceLinks = resourceLinks.join('\n'); |
|
|
|
let newFileContent = fileContent.replace( |
|
/<ResourceGroupTitle>([^<\/BadgeLink>]|\S|\s)+<\/BadgeLink>/, |
|
resourceLinks |
|
); |
|
|
|
// In case if the resources were not wrapped in <ResourceGroupTitle> |
|
newFileContent = newFileContent.replace( |
|
/<BadgeLink([^<\/BadgeLink>]|\S|\s)+<\/BadgeLink>/, |
|
resourceLinks |
|
); |
|
|
|
fs.writeFileSync(dirChildPath, newFileContent); |
|
} |
|
}); |
|
} |
|
|
|
handleContentDir(contentDirPath); |
|
|
|
// 3 - Removes the index.md file from within the content dir i.e. to avoid `/frontend` permalink for `/frontend/index.md` |
|
// Because we have the `/frontend` permalink serving the actual roadmap and not any content |
|
const contentRootFile = path.join(contentDirPath, '/index.md'); |
|
if (fs.existsSync(contentRootFile)) { |
|
fs.rmSync(contentRootFile); |
|
} |
|
|
|
console.log(` == Migrated ${roadmapDirName}`); |
|
});
|
|
|