🛠️ chore: adding linter

This commit is contained in:
Carlos 2024-08-13 20:20:06 -04:00
parent 0e72a35ba7
commit a6c2ffd5e6
10 changed files with 3126 additions and 1 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
pre-files/

View File

@ -4,12 +4,33 @@ module.exports = {
es2021: true, es2021: true,
node: true, node: true,
}, },
extends: ['eslint:recommended', 'plugin:prettier/recommended'], extends: [
'eslint:recommended',
'plugin:prettier/recommended',
],
plugins: ['jsdoc'],
parserOptions: { parserOptions: {
ecmaVersion: 12, ecmaVersion: 12,
sourceType: 'module', sourceType: 'module',
}, },
rules: { rules: {
'prettier/prettier': 'error', 'prettier/prettier': 'error',
'complexity': ['error', { 'max': 5 }],
'jsdoc/check-tag-names': 'error',
'jsdoc/check-types': 'error',
'jsdoc/require-jsdoc': [
'error',
{
require: {
FunctionDeclaration: true,
MethodDefinition: true,
ClassDeclaration: true,
ArrowFunctionExpression: true,
FunctionExpression: true,
},
},
],
'jsdoc/require-param': 'error',
'jsdoc/require-returns': 'error',
}, },
}; };

4
.husky/commit-msg Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
node ./.husky/commit-msg-linter.js "$1"

167
.husky/commit-msg-linter.js Normal file
View File

@ -0,0 +1,167 @@
const { exec, execSync } = require('child_process');
const { promises: fs } = require('fs');
const chalk = require('chalk');
const commitTypes = {
feat: '✨',
fix: '🐛',
docs: '📚',
style: '🎨',
refactor: '🔨',
test: '✅',
chore: '🛠️',
};
const defaultEmoji = '🔖'; // Default emoji if the commit type is not found
async function run() {
// Dynamically import the ES Module
const ora = (await import('ora')).default;
const spinner = ora('Running custom commit message check...').start();
try {
console.log(chalk.blue('🔍 Running custom commit message check...'));
console.log();
// Get the commit message file path from the command line arguments
const commitMsgFile = process.argv[2];
if (!commitMsgFile) {
spinner.fail('❌ Error: Commit message file path not provided.');
console.error(
chalk.red('❌ Error: Commit message file path not provided.')
);
process.exit(1);
}
const commitMsg = (await fs.readFile(commitMsgFile, 'utf8')).trim();
// Check for duplicate commit messages in the last 100 commits
const duplicateCommitMsg = execSync(`git log -n 100 --pretty=format:%s`)
.toString()
.split('\n')
.some((msg) => msg.trim() === commitMsg);
if (duplicateCommitMsg) {
spinner.fail('❌ Duplicate commit message detected.');
console.error(
chalk.red(
'❌ Duplicate commit message detected. Please use a unique commit message.'
)
);
console.log();
process.exit(1);
}
spinner.succeed('✅ Message is not duplicated');
console.log(chalk.green('✅ Message is not duplicated'));
console.log();
} catch (err) {
spinner.fail('❌ Error running custom commit message check.');
console.error(chalk.red('❌ Error:', err));
process.exit(1);
}
spinner.start('Running commitlint...');
try {
console.log(chalk.blue('🔍 Running commitlint...'));
console.log();
const commitMsgFile = process.argv[2];
if (!commitMsgFile) {
spinner.fail('❌ Error: Commit message file path not provided.');
console.error(
chalk.red('❌ Error: Commit message file path not provided.')
);
process.exit(1);
}
const commitMsg = (await fs.readFile(commitMsgFile, 'utf8')).trim();
// Run commitlint
exec(
`npx commitlint --edit ${commitMsgFile}`,
async (error, stdout, stderr) => {
if (error) {
spinner.fail('❌ Commitlint check failed.');
console.error(chalk.red(stdout || stderr));
console.error(chalk.red('❌ Commitlint check failed.'));
console.log();
console.error(
chalk.yellow(
'💡 Hint: Commit message should follow the Conventional Commits standard.'
)
);
console.error(
chalk.yellow(
'👀 See: https://www.conventionalcommits.org/en/v1.0.0/'
)
);
console.error(chalk.yellow('📋 Examples:'));
console.error(chalk.yellow(' feat: add a new feature'));
console.error(chalk.yellow(' fix: fix a bug'));
console.error(chalk.yellow(' docs: update documentation'));
console.error(
chalk.yellow(
' style: improve formatting, missing semi colons, etc'
)
);
console.error(
chalk.yellow(
' refactor: code change that neither fixes a bug nor adds a feature'
)
);
console.error(chalk.yellow(' test: add or modify tests'));
console.error(
chalk.yellow(
" chore: maintain tasks that don't fit in other categories"
)
);
process.exit(1);
} else {
spinner.succeed('✅ Commitlint check passed.');
console.log(chalk.green('✅ Commitlint check passed.'));
console.log(chalk.green(stdout));
// Add emoji to the commit message
const commitRegex =
/^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?:\s.+/;
const match = commitMsg.match(commitRegex);
if (match) {
const commitType = match[1];
const emoji = commitTypes[commitType] || defaultEmoji;
const newCommitMsg = `${emoji} ${commitMsg}`;
// Write the updated commit message back to the file
await fs.writeFile(commitMsgFile, newCommitMsg + '\n', 'utf8');
console.log(
chalk.green('✅ Commit message updated with emoji:'),
newCommitMsg
);
} else {
const newCommitMsg = `${defaultEmoji} ${commitMsg}`;
await fs.writeFile(commitMsgFile, newCommitMsg + '\n', 'utf8');
console.log(
chalk.yellow(
'⚠️ Commit message did not match expected format, added default emoji:'
),
newCommitMsg
);
}
process.exit(0);
}
}
);
} catch (err) {
spinner.fail('❌ Error running commitlint.');
console.error(chalk.red('❌ Error:', err));
process.exit(1);
}
}
run();

47
.husky/lint-check.js Normal file
View File

@ -0,0 +1,47 @@
const { exec, execSync } = require('child_process');
const { promises: fs } = require('fs');
const chalk = require('chalk');
async function runCommand(command, description) {
// Dynamically import the ES Module
const ora = (await import('ora')).default;
const spinner = ora(`Running ${description}...`).start();
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
spinner.fail(`${description} failed.`);
console.error(chalk.red(`${description} failed.`));
console.error(chalk.red(stderr));
reject(new Error(stderr));
} else {
spinner.succeed(`${description} passed.`);
console.log(chalk.green(`${description} passed.`));
console.log(stdout);
resolve();
}
});
});
}
async function runLint() {
try {
await runCommand('npm run lint:prettier', 'Prettier check');
//await runCommand('yarn lint:html', 'ESLint HTML report');
console.log(chalk.green('🎉 All checks passed.'));
process.exit(0);
} catch (err) {
console.error(chalk.red('❌ Lint checks failed.'));
console.error(chalk.red('😢 Oh no! Your code is not pretty enough.'));
console.error(chalk.red('Please fix the issues above and try again.'));
console.error(
chalk.yellow(
`💡 Hint: You can run ${chalk.cyan('yarn prettier')} to automatically format your code.`
)
);
process.exit(1);
}
}
runLint();

4
.husky/pre-push Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
node .husky/lint-check.js

3
commitlint.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};

1435
node_modules/.package-lock.json generated vendored

File diff suppressed because it is too large Load Diff

1439
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -44,13 +44,17 @@
"@babel/preset-env": "^7.13.5", "@babel/preset-env": "^7.13.5",
"@babel/preset-react": "^7.13.1", "@babel/preset-react": "^7.13.1",
"@babel/preset-typescript": "^7.24.7", "@babel/preset-typescript": "^7.24.7",
"@commitlint/cli": "^19.4.0",
"@commitlint/config-conventional": "^19.2.2",
"@types/jest": "^29.5.12", "@types/jest": "^29.5.12",
"babel-loader": "^8.2.2", "babel-loader": "^8.2.2",
"css-loader": "^5.1.1", "css-loader": "^5.1.1",
"dotenv-webpack": "^7.0.2", "dotenv-webpack": "^7.0.2",
"eslint": "^9.9.0", "eslint": "^9.9.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-jsdoc": "^50.2.1",
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
"husky": "^9.1.4",
"jest": "^29.7.0", "jest": "^29.7.0",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"sass-loader": "^11.0.1", "sass-loader": "^11.0.1",