Skip to content

Commit

Permalink
Automate Linting with Husky and lint-staged to Prevent CI Failures (#896
Browse files Browse the repository at this point in the history
)

This PR addresses the issue where linting was not being automatically
executed before commits, despite Husky being installed. The previous
setup had Husky installed at v8, but proper pre-commit hooks were not
in place to ensure that linting occurred consistently. Since Husky v5,
the configuration and usage have changed. For more details, refer to
the documentation of Husky.

Key changes include:

- Adding the missing pre-commit configuration in the .husky folder,
  and ensure Husky works as expected to automate linting at the
  pre-commit stage.
- Integrating lint-staged to only lint the files that are staged for
  commit, improving efficiency.

With these updates, developers will no longer need to manually run
lint checks, as the process will be automated and enforced during the
commit phase.
  • Loading branch information
gwbaik9717 authored Sep 6, 2024
1 parent 17c8704 commit 4837c7d
Show file tree
Hide file tree
Showing 18 changed files with 7,023 additions and 2,365 deletions.
10 changes: 10 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# common
**/dist/*

# sdk
packages/sdk/src/api/yorkie/v1/yorkie_grpc_web_pb.d.ts
packages/sdk/src/api/yorkie/v1/yorkie_pb.d.ts
packages/sdk/src/api/yorkie/v1/resources_grpc_web_pb.d.ts
packages/sdk/src/api/yorkie/v1/resources_pb.d.ts
packages/sdk/test/vitest.d.ts
packages/sdk/lib
61 changes: 61 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
module.exports = {
root: true,
plugins: ['prettier', 'jsdoc', '@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
'prettier/prettier': 'error',
'object-shorthand': ['error', 'always'],
'no-unreachable': 'error',
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'jsdoc/require-jsdoc': [
'error',
{
contexts: ['MethodDefinition:not([accessibility="private"])'],
require: {
ClassDeclaration: true,
},
checkConstructors: false,
enableFixer: false,
},
],
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['camelCase', 'PascalCase'],
leadingUnderscore: 'allowDouble',
trailingUnderscore: 'allowDouble',
},
],
'@typescript-eslint/ban-types': [
'error',
{
types: { null: 'Use undefined instead of null' },
},
],
'@typescript-eslint/array-type': ['error', { default: 'generic' }],
'@typescript-eslint/no-this-alias': [
'error',
{
allowDestructuring: true,
allowedNames: ['node'],
},
],
},
},
],
};
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: pnpm install

- run: pnpm sdk lint
- run: pnpm lint
- run: pnpm sdk build
- run: pnpm build:examples
- run: docker compose -f docker/docker-compose-ci.yml up --build -d
Expand Down
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx lint-staged
1 change: 1 addition & 0 deletions examples/nextjs-scheduler/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ module.exports = {
endOfLine: 'auto',
},
],
'@next/next/no-html-link-for-pages': 'off',
},
};
1 change: 0 additions & 1 deletion examples/nextjs-scheduler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"@types/react-dom": "18.2.0",
"eslint-config-next": "^14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.0.0",
"prettier": "^3.3.3",
"typescript": "5.3.3"
}
Expand Down
39 changes: 39 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { ESLint } = require('eslint');
const { execSync } = require('child_process');
const path = require('path');

const removeIgnoredFiles = async (files) => {
const eslintIgnorePath = path.resolve('.eslintignore'); // Pointing to the root .eslintignore
const eslint = new ESLint({ ignorePath: eslintIgnorePath });

const isIgnored = await Promise.all(
files.map(async (file) => {
const ignored = await eslint.isPathIgnored(file);
return ignored;
}),
);

const filteredFiles = files.filter((_, i) => !isIgnored[i]);
return filteredFiles;
};

module.exports = {
'**/*.ts': async (files) => {
const filesToLint = await removeIgnoredFiles(files);

if (filesToLint.length > 0) {
const fileArgs = filesToLint.join(' ');
const command = `pnpm exec eslint ${fileArgs} --fix --max-warnings=0 --ext .ts`;
try {
execSync(command, { stdio: 'inherit' });
process.exit(0);
} catch (error) {
console.error('Linting failed. Commit will be aborted.');
process.exit(1);
}
} else {
console.log('No eligible files to lint. Skipping lint-staged command.');
process.exit(0);
}
},
};
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"vanilla-codemirror6": "pnpm --filter=vanilla-codemirror6",
"vanilla-quill": "pnpm --filter=vanilla-quill",
"vuejs-kanban": "pnpm --filter=vuejs-kanban",
"build:examples": "pnpm --filter './examples/*' run build"
"build:examples": "pnpm --filter './examples/*' run build",
"lint": "eslint . --fix --max-warnings=0 --ext .ts",
"prepare": "husky"
},
"keywords": [],
"author": {
Expand All @@ -25,6 +27,11 @@
},
"license": "Apache-2.0",
"devDependencies": {
"only-allow": "^1.2.1"
"eslint": "^8.19.0",
"husky": "^9.1.5",
"lint-staged": "^15.2.9",
"only-allow": "^1.2.1",
"eslint-plugin-jsdoc": "^39.3.3",
"eslint-plugin-prettier": "^5.0.0"
}
}
7 changes: 0 additions & 7 deletions packages/sdk/.eslintignore

This file was deleted.

50 changes: 2 additions & 48 deletions packages/sdk/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,9 @@
// eslint-disable-next-line no-undef
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'prettier', 'eslint-plugin-tsdoc', 'jsdoc'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
extends: ['../../.eslintrc.js'],
plugins: ['eslint-plugin-tsdoc'],
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['camelCase', 'PascalCase'],
leadingUnderscore: 'allowDouble',
trailingUnderscore: 'allowDouble',
},
],
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': [
'error',
{
types: { null: 'Use undefined instead of null' },
},
],
'@typescript-eslint/array-type': ['error', { default: 'generic' }],
'tsdoc/syntax': 'error',
'object-shorthand': ['error', 'always'],
'no-unreachable': 'error',
'jsdoc/require-jsdoc': [
'error',
{
contexts: ['MethodDefinition:not([accessibility="private"])'],
require: {
ClassDeclaration: true,
},
checkConstructors: false,
enableFixer: false,
},
],
'@typescript-eslint/no-this-alias': [
'error',
{
allowDestructuring: true,
allowedNames: ['node'],
},
],
},
overrides: [
{
Expand Down
10 changes: 0 additions & 10 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"test:bench": "vitest bench",
"test:ci": "vitest run --coverage",
"test:yorkie.dev": "TEST_RPC_ADDR=https://api.yorkie.dev vitest run --coverage",
"lint": "eslint . --fix --max-warnings=0 --ext .ts",
"prepare": "pnpm build"
},
"engines": {
Expand Down Expand Up @@ -53,11 +52,7 @@
"@typescript-eslint/parser": "^6.21.0",
"@vitest/coverage-istanbul": "^0.34.5",
"@vitest/coverage-v8": "^0.34.5",
"eslint": "^8.19.0",
"eslint-plugin-jsdoc": "^39.3.3",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-tsdoc": "^0.2.16",
"husky": "^8.0.3",
"prettier": "^2.7.1",
"ts-node": "^10.9.1",
"typedoc": "^0.25.13",
Expand All @@ -74,10 +69,5 @@
"@connectrpc/connect": "^1.4.0",
"@connectrpc/connect-web": "^1.4.0",
"long": "^5.2.0"
},
"husky": {
"hooks": {
"pre-commit": "pnpm lint"
}
}
}
4 changes: 2 additions & 2 deletions packages/sdk/src/document/crdt/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1371,8 +1371,8 @@ export class CRDTTree extends CRDTElement implements GCParent {
const treePos = node.isText
? { node, offset: 0 }
: parentNode && leftChildNode
? this.toTreePos(parentNode, leftChildNode)
: null;
? this.toTreePos(parentNode, leftChildNode)
: null;

if (treePos) {
index = this.indexTree.indexOf(treePos);
Expand Down
Loading

0 comments on commit 4837c7d

Please sign in to comment.