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. // Free Content // W3Schools — Learn CSS // // {% 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(//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 = //; 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( /([^<\/BadgeLink>]|\S|\s)+<\/BadgeLink>/, resourceLinks ); // In case if the resources were not wrapped in newFileContent = newFileContent.replace( /]|\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}`); });