Files
linea-monorepo/contracts/docs/scripts/updateSidebar.js
The Dark Jester 643110c696 [Chore] - Match contract docs locally (#493)
* add docgen for solidity changes to husky

* add solidity docs

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

* Update .husky/pre-commit.js

Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>

---------

Signed-off-by: The Dark Jester <thedarkjester@users.noreply.github.com>
Co-authored-by: kyzooghost <73516204+kyzooghost@users.noreply.github.com>
2025-01-06 06:12:38 -08:00

177 lines
5.9 KiB
JavaScript

/* eslint-disable */
// This script is meant to be executed in the root directory of https://github.com/Consensys/doc.linea, which has different linting rules
// The purpose of this script is to modify the sidebars.js file to correctly include the autogenerated smart contract documentation
/**
* PURPOSE
*
* Modifies sidebars.js in the root directory of https://github.com/Consensys/doc.linea to correctly include smart contract documentation pages.
* The sidebars.js file configures the sidebar for the documentation website @ https://docs.linea.build/
*/
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
/**
* TYPES
*/
/**
* Represents a sidebar section - see https://docusaurus.io/docs/sidebar/items#sidebar-item-category
* @property {'category'} type - Type of sidebar item
* @property {number} label - Sidebar label text
* @property {null} link - Sidebar item link, set to null so only collapsing/expanding the sidebar occurs on click
* @property {boolean} collapsible - If true, sidebar item can be collapsed. If false, sidebar item is permanently expanded
* @property {string | FolderSidebar} items - Items contained in this sidebar section
*/
class FolderSidebar {
type = "category";
label = "";
link = null;
collapsible = true;
items = [];
constructor(label = "", collapsible = true) {
this.label = label;
this.collapsible = collapsible;
}
}
/**
* CONSTANTS
*/
const SIDEBAR_FILE_PATH = "sidebars.js";
const SMART_CONTRACT_SIDEBAR_LABEL = "Linea smart contracts";
// Import the sidebar JS object from sidebars.js
const sidebarObject = require(path.join(__dirname, SIDEBAR_FILE_PATH));
/**
* MAIN FUNCTION
*/
main();
function main() {
removeExistingSmartContractSidebar(sidebarObject);
const smartContractSidebarNode = getSmartContractSidebar();
sidebarObject?.apiSidebar?.push(smartContractSidebarNode);
createNewSidebarFile(sidebarObject);
}
/**
* HELPER FUNCTIONS
*/
/**
* Remove existing smart contract section from sidebar object
* @param {FolderSidebar} sidebarObject
*/
function removeExistingSmartContractSidebar(sidebarObject) {
if (sidebarObject?.apiSidebar) {
sidebarObject.apiSidebar = sidebarObject?.apiSidebar.filter(
(sidebarSection) => sidebarSection?.label !== SMART_CONTRACT_SIDEBAR_LABEL,
);
}
}
/**
* Creates FolderSidebar representing folder structure of smart contract documentation pages
* @returns {FolderSidebar}
*/
function getSmartContractSidebar() {
// Create and populate smart contract sidebar
const smartContractsPath = path.join(__dirname, "docs", "api", "linea-smart-contracts");
let smartContractSidebar = new FolderSidebar(
SMART_CONTRACT_SIDEBAR_LABEL,
// Prefer having the smart contract sidebar section permanently expanded to fill out the main sidebar
false,
);
populateFolderSidebar(smartContractSidebar, smartContractsPath, ".mdx");
return smartContractSidebar;
}
/**
* Recursive function to populate FolderSidebar for a given folder
* Performs depth-first search (DFS) of the folder tree
* @param {FolderSidebar} folderSidebar - Mutated throughout the function body. Mutated object is then returned by the function.
* @param {string} subdirectoryPath - folder path
* @param {string} fileExtension
* @return {FolderSidebar}
*/
function populateFolderSidebar(folderSidebar, subdirectoryPath, fileExtension) {
const folderFileList = fs.readdirSync(subdirectoryPath);
// Ensure *.mdx files at the top of the sidebar section
for (const fileNode of folderFileList) {
const filePath = path.join(subdirectoryPath, fileNode);
const fileMetadata = fs.statSync(filePath);
// Base case => *.mdx file => Add relative path to sidebar
if (fileMetadata.isFile() && fileNode.endsWith(fileExtension)) {
const relativePath = path.relative(path.join(__dirname, "docs"), filePath.split(fileExtension)[0]);
folderSidebar?.items.push(relativePath);
}
}
// Ensure directories are below *.mdx files in the sidebar section
for (const fileNode of folderFileList) {
const filePath = path.join(subdirectoryPath, fileNode);
const fileMetadata = fs.statSync(filePath);
// Directory => Create new child FolderSidebar, then make recursive call to populate new child FolderSidebar
if (fileMetadata.isDirectory()) {
let newFolderNode = new FolderSidebar(fileNode);
populateFolderSidebar(newFolderNode, filePath, fileExtension);
// Add populated child FolderSidebar to current sidebar section
folderSidebar?.items.push(newFolderNode);
}
}
// Not a *.mdx file or directory => Do nothing
return folderSidebar;
}
/**
* Overwrites existing sidebars.js file with modified sidebar object
* @param {FolderSidebar} sidebarObject - Entire sidebar object to save
*/
function createNewSidebarFile(sidebarObject) {
// Create new sidebars.js file content
const sidebarFileLine1 = "/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */";
const sidebarFileLine2 = "const sidebars =";
const sidebarFileLineFinal = "module.exports = sidebars;";
const newSidebarFileContent = `${sidebarFileLine1}\n${sidebarFileLine2}\n${JSON.stringify(sidebarObject, null, 2)}\n\n${sidebarFileLineFinal}`;
// Overwrite existing sidebars.js
const newSidebarFilePath = path.join(__dirname, SIDEBAR_FILE_PATH);
fs.writeFileSync(newSidebarFilePath, newSidebarFileContent);
// Do linting
lintJSFile(newSidebarFilePath);
}
/**
* Execute linting of Javascript file
* @param {string} filePath
*/
function lintJSFile(filePath) {
try {
const installCmd = `npm install --save-dev --no-save eslint`;
execSync(installCmd, { stdio: "inherit" });
const lintCmd = `npx eslint --fix --no-ignore ${filePath}`;
// Execute command synchronously and route output directly to the current stdout
execSync(lintCmd, { stdio: "inherit" });
} catch (error) {
console.error(`Error:`, error.message);
console.error(`Exiting...`);
process.exit(1);
}
}