mirror of
https://github.com/vacp2p/linea-monorepo.git
synced 2026-01-08 15:13:50 -05:00
* 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>
224 lines
6.4 KiB
JavaScript
224 lines
6.4 KiB
JavaScript
/**
|
|
* Runs as git pre-commit hook
|
|
* Filters the list of changed files on 'git commit'
|
|
* If *.ts files in specified projects are detected, runs the 'lint:ts:fix' package.json script for that project
|
|
* E.g. if a *.ts file is changed in /sdk, then this script will run 'pnpm run lint:ts:fix' in the /sdk project
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const { execSync } = require('child_process');
|
|
|
|
/**
|
|
* ENUMS
|
|
*/
|
|
|
|
// File extensions to filter for
|
|
const FILE_EXTENSION = {
|
|
TYPESCRIPT: "TYPESCRIPT",
|
|
SOLIDITY: "SOLIDITY",
|
|
}
|
|
|
|
// Projects to filter for
|
|
const FOLDER = {
|
|
BRIDGEUI: "BRIDGEUI",
|
|
CONTRACTS: "CONTRACTS",
|
|
E2E: "E2E",
|
|
OPERATIONS: "OPERATIONS",
|
|
POSTMAN: "POSTMAN",
|
|
SDK: "SDK",
|
|
}
|
|
|
|
// Project runtimes
|
|
const RUNTIME = {
|
|
NODEJS: "NODEJS"
|
|
}
|
|
|
|
/**
|
|
* MAPPINGS
|
|
*/
|
|
|
|
// File extension => regex
|
|
const FILE_EXTENSION_FILTERS = {
|
|
[FILE_EXTENSION.TYPESCRIPT]: "\.ts$",
|
|
[FILE_EXTENSION.SOLIDITY]: "\.sol$",
|
|
};
|
|
|
|
// File extension => script in package.json to run for linting
|
|
const FILE_EXTENSION_LINTING_COMMAND = {
|
|
[FILE_EXTENSION.TYPESCRIPT]: "pnpm run lint:ts:fix",
|
|
[FILE_EXTENSION.SOLIDITY]: "pnpm run lint:sol:fix",
|
|
};
|
|
|
|
// File extension => script in package.json to run for documentation generation
|
|
const FILE_EXTENSION_DOCUMENTATION_UPDATING_COMMAND = {
|
|
[FILE_EXTENSION.SOLIDITY]: "pnpm run solidity:docgen",
|
|
};
|
|
|
|
// Project => Path in monorepo
|
|
const FOLDER_PATH = {
|
|
[FOLDER.BRIDGEUI]: "bridge-ui/",
|
|
[FOLDER.CONTRACTS]: "contracts/",
|
|
[FOLDER.E2E]: "e2e/",
|
|
[FOLDER.OPERATIONS]: "operations/",
|
|
[FOLDER.POSTMAN]: "postman/",
|
|
[FOLDER.SDK]: "sdk/",
|
|
};
|
|
|
|
// Project => List of changed files
|
|
const FOLDER_CHANGED_FILES = {
|
|
[FOLDER.BRIDGEUI]: new Array(),
|
|
[FOLDER.CONTRACTS]: new Array(),
|
|
[FOLDER.E2E]: new Array(),
|
|
[FOLDER.OPERATIONS]: new Array(),
|
|
[FOLDER.POSTMAN]: new Array(),
|
|
[FOLDER.SDK]: new Array(),
|
|
};
|
|
|
|
// Project => Runtime
|
|
const FOLDER_RUNTIME = {
|
|
[FOLDER.BRIDGEUI]: RUNTIME.NODEJS,
|
|
[FOLDER.CONTRACTS]: RUNTIME.NODEJS,
|
|
[FOLDER.E2E]: RUNTIME.NODEJS,
|
|
[FOLDER.OPERATIONS]: RUNTIME.NODEJS,
|
|
[FOLDER.POSTMAN]: RUNTIME.NODEJS,
|
|
[FOLDER.SDK]: RUNTIME.NODEJS,
|
|
};
|
|
|
|
/**
|
|
* MAIN FUNCTION
|
|
*/
|
|
|
|
main();
|
|
|
|
function main() {
|
|
const changedFileList = getChangedFileList();
|
|
partitionChangedFileList(changedFileList);
|
|
|
|
for (const folder in FOLDER) {
|
|
if (!isDependenciesInstalled(folder)) {
|
|
console.error(`Dependencies not installed in ${FOLDER_PATH[folder]}, exiting...`)
|
|
process.exit(1);
|
|
}
|
|
const changedFileExtensions = getChangedFileExtensions(folder);
|
|
executeCommand(folder, changedFileExtensions, FILE_EXTENSION_LINTING_COMMAND);
|
|
executeCommand(folder, changedFileExtensions, FILE_EXTENSION_DOCUMENTATION_UPDATING_COMMAND);
|
|
}
|
|
|
|
updateGitIndex();
|
|
}
|
|
|
|
/**
|
|
* HELPER FUNCTIONS
|
|
*/
|
|
|
|
/**
|
|
* Gets a list of changed files in the git commit
|
|
* @returns {string[]}
|
|
*/
|
|
function getChangedFileList() {
|
|
try {
|
|
const cmd = 'git diff --name-only HEAD'
|
|
const stdout = execSync(cmd, { encoding: 'utf8' });
|
|
return stdout.split('\n').filter(file => file.trim() !== '');
|
|
} catch (error) {
|
|
console.error($`Error running ${cmd}:`, error.message);
|
|
process.exit(1)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Partitions list of changed files from getChangedFileList() by project
|
|
* Stores results in FOLDER_CHANGED_FILES
|
|
* @param {string[]}
|
|
*/
|
|
function partitionChangedFileList(_changedFileList) {
|
|
for (const file of _changedFileList) {
|
|
for (const path in FOLDER) {
|
|
if (file.match(new RegExp(`^${FOLDER_PATH[path]}`))) {
|
|
FOLDER_CHANGED_FILES[path].push(file);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if runtime dependencies are installed for a project
|
|
* @param {FOLDER}
|
|
* @returns {boolean}
|
|
*/
|
|
function isDependenciesInstalled(_folder) {
|
|
const runtime = FOLDER_RUNTIME[_folder];
|
|
const path = FOLDER_PATH[_folder];
|
|
|
|
switch(runtime) {
|
|
case RUNTIME.NODEJS:
|
|
const dependencyFolder = `${path}node_modules`
|
|
return fs.existsSync(dependencyFolder)
|
|
default:
|
|
console.error(`${runtime} runtime not supported.`);
|
|
return false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resolve list of changed file extensions for a project
|
|
* @param {FOLDER}
|
|
* @returns {FILE_EXTENSION[]}
|
|
*/
|
|
function getChangedFileExtensions(_folder) {
|
|
// Use sets to implement early exit from loop, once we have matched all configured file extensions
|
|
const remainingFileExtensionsSet = new Set(Object.values(FILE_EXTENSION));
|
|
const foundFileExtensionsSet = new Set();
|
|
|
|
for (const file of FOLDER_CHANGED_FILES[_folder]) {
|
|
for (const fileExtension of remainingFileExtensionsSet) {
|
|
if (file.match(new RegExp(FILE_EXTENSION_FILTERS[fileExtension]))) {
|
|
foundFileExtensionsSet.add(fileExtension);
|
|
remainingFileExtensionsSet.delete(fileExtension);
|
|
}
|
|
}
|
|
|
|
// No more remaining file extensions to look for
|
|
if (remainingFileExtensionsSet.size == 0) break;
|
|
}
|
|
|
|
return Array.from(foundFileExtensionsSet);
|
|
}
|
|
|
|
/**
|
|
* Execute command based on file extension
|
|
* @param {FOLDER, FILE_EXTENSION[], FILE_EXTENSION_LINTING_COMMAND | FILE_EXTENSION_DOCUMENTATION_UPDATING_COMMAND}
|
|
*/
|
|
function executeCommand(_folder, _changedFileExtensions, _command) {
|
|
for (const fileExtension of _changedFileExtensions) {
|
|
const path = FOLDER_PATH[_folder];
|
|
const cmd = _command[fileExtension];
|
|
if (!cmd) return;
|
|
console.log(`${fileExtension} change found in ${path}, executing command ${cmd}`);
|
|
try {
|
|
// Execute command synchronously and stream output directly to the current stdout
|
|
execSync(`
|
|
cd ${path};
|
|
${cmd};
|
|
`, { stdio: 'inherit' });
|
|
} catch (error) {
|
|
console.error(`Error:`, error.message);
|
|
console.error(`Exiting...`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Redo `git add` for files updated during executeLinting(), so that they are not left out of the commit
|
|
* The difference between 'git add .' and 'git update-index --again', is that the latter will not include untracked files
|
|
*/
|
|
function updateGitIndex() {
|
|
try {
|
|
const cmd = 'git update-index --again'
|
|
execSync(cmd, { stdio: 'inherit' });
|
|
} catch (error) {
|
|
console.error($`Error running ${cmd}:`, error.message);
|
|
process.exit(1);
|
|
}
|
|
} |