Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 0 additions & 78 deletions .circleci/config.yml

This file was deleted.

13 changes: 0 additions & 13 deletions .eslintrc.js

This file was deleted.

30 changes: 30 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Lint

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
with:
version: 8

- name: Setup Node.js
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: '22'

- name: Install dependencies
run: pnpm install

- name: Run linter
run: pnpm lint
20 changes: 20 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"arrowParens": 'avoid',
"bracketSameLine": false,
"bracketSpacing": false,
"embeddedLanguageFormatting": 'auto',
"endOfLine": 'lf',
"htmlWhitespaceSensitivity": 'css',
"insertPragma": false,
"jsxSingleQuote": false,
"printWidth": 80,
"proseWrap": 'always',
"quoteProps": 'as-needed',
"requirePragma": false,
"semi": false,
"singleAttributePerLine": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": 'all',
"useTabs": false,
}
136 changes: 136 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Development Documentation

## Linting

2026 update: The project is now using ESLint 9 and the flat config format. As we
update things from the old config we will update this document to reflect the
changes. Once the code base is stable and things work, we can delete some of the
historical documentation. But for now this document can help us track design
decisions and changes made.

### Overview

The project uses a native ESLint configuration that was migrated from
kcd-scripts. The setup supports both CommonJS source files and ES module test
files, using ESLint 9's flat config format.

### What changed

Previously, the project used `kcd-scripts` for linting configuration. Because
that project is no longer actively maintained, we migrated to a native ESLint
setup that replicates the same behavior.

**Migration details:**

- Replaced `kcd-scripts lint` with native ESLint
- Created `eslint.config.mjs` using ESLint 9 flat config format
- Extracted rules from `eslint-config-kentcdodds` to create a simplified,
maintainable config. This included removing a lot of the custom rules and
leaning more on the recommended rules.
- Preserved some custom rule overrides from the original setup
- Supports both CommonJS (source files) and ES modules (test files)

Note: We should consider refacting the project to use ES modules instead of
CommonJS (if everyone supports that) in the future for consistency.

### How to run the linter

To check for linting errors you can run:

```bash
pnpm lint
```

ESlint can automatically fix some errors. to fix errors automatically run:

```bash
pnpm lint --fix
```

The `--fix` flag will automatically fix many common issues like:

- Jest method aliases (e.g., `toThrowError()` → `toThrow()`)
- Unused eslint-disable directives
- Some formatting issues

**Note:** Some errors require manual fixes (e.g., unused variables, tests
without assertions).

### Pre-commit hooks

The project uses Husky to run pre-commit hooks that automatically lint and fix
staged files before each commit.

**How it works:**

1. When you run `git commit`, Husky intercepts the commit
2. The pre-commit hook runs `lint-staged`
3. `lint-staged` runs `eslint --fix` on all staged JavaScript/TypeScript files
4. If linting passes, the commit proceeds; if it fails, the commit is blocked

What this means... this workflow ensures that code is automatically linted and fixed before it's committed to version control.


If you are encountering issues with the pre-commit hook, you can run the following command to manually lint and fix the files:

```bash
pnpm lint --fix
```
Or if it's really problematic, you can skip verification and commit anyway with the `--no-verify` flag.

```bash
git commit --no-verify
```

If you do this please ping one of the maintainers in the PR that you open so they can help you fix the issues!

**Configuration:**

- Husky configuration is in `package.json` under the `husky.hooks.pre-commit`
field
- `lint-staged` configuration is in `package.json` under the `lint-staged`
field
- The setup uses the native ESLint configuration (`eslint.config.mjs`)

**Note:** Previously, the project used `kcd-scripts pre-commit` which handled
both hook management and linting. We migrated to using `lint-staged` directly
with our native ESLint config to avoid version conflicts.

### Dependencies

The following packages are used for linting:

- **eslint** — ESLint core (v9.39.2+)
- **@eslint/js** — ESLint recommended rules configuration
- **eslint-plugin-import** — Import/export rules for module resolution and best
practices
- **eslint-plugin-jest** — Jest-specific rules for test files
- **eslint-config-prettier** — Disables ESLint rules that conflict with Prettier
formatting
- **@rushstack/eslint-patch** — Module resolution patch for improved
import/export handling
- **globals** — Provides properly formatted global variables for Node.js and
Jest environments

### Why these packages?

The configuration is based on `eslint-config-kentcdodds`, which provides a
comprehensive set of rules. We extracted the essential parts to create a
maintainable native config that:

- Catches common bugs and errors
- Enforces consistent code style
- Works with both CommonJS and ES modules
- Integrates with Prettier for formatting
- Provides Jest-specific linting for test files

### Configuration file

The ESLint configuration is in `eslint.config.mjs` at the project root. It uses
ESLint 9's flat config format and includes:

- Base rules from `eslint:recommended`
- Import plugin rules
- Jest plugin rules (for test files only)
- Custom overrides for project-specific needs
- Support for both CommonJS and ES module syntax
35 changes: 35 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import js from '@eslint/js'
import {defineConfig, globalIgnores} from 'eslint/config'
import importPlugin from 'eslint-plugin-import'
import jestPlugin from 'eslint-plugin-jest'
import globals from 'globals'

export default defineConfig([
globalIgnores(['coverage/**', 'dist/**', '_law_tests/**']),
{linterOptions: {reportUnusedDisableDirectives: 'error'}},
{
extends: [js.configs.recommended, importPlugin.flatConfigs.recommended],
files: ['**/*.{mjs,js}'],
languageOptions: {
ecmaVersion: 'latest',
globals: globals.node,
},
rules: {
'import/no-unresolved': ['error', {ignore: ['^eslint/', '^prettier$']}],
'import/no-extraneous-dependencies': 'error',
'import/default': 'off',
'import/namespace': 'off',
},
},
{
extends: [jestPlugin.configs['flat/recommended']],
files: ['**/__tests__/**/*.js'],
languageOptions: {
globals: globals.jest,
},
rules: {
'jest/no-disabled-tests': 'error',
'jest/prefer-to-have-length': 'error',
},
},
])
36 changes: 15 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@
"scripts": {
"add-contributor": "kcd-scripts contributors add",
"build": "kcd-scripts build",
"lint": "kcd-scripts lint",
"lint": "eslint .",
"prettier": "prettier -w src/**/*.js",
"test": "NODE_OPTIONS='--experimental-vm-modules' kcd-scripts test --watchAll=false",
"validate": "kcd-scripts validate",
"commit": "git-cz",
"start": "./dist/cli.js",
"dev": "./src/cli.js"
},
"husky": {
"hooks": {
"pre-commit": "NODE_OPTIONS='--experimental-vm-modules' kcd-scripts pre-commit"
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*": "prettier --ignore-unknown --write"
},
"repository": {
"type": "git",
"url": "https://github.com/all-contributors/all-contributors-cli.git"
Expand Down Expand Up @@ -54,30 +57,21 @@
"yargs": "^17.7.2"
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@rushstack/eslint-patch": "^1.15.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.12.1",
"git-cz": "^4.7.6",
"globals": "^17.1.0",
"kcd-scripts": "^6.2.0",
"lint-staged": "^16.2.7",
"nock": "^12.0.0",
"prettier": "^3.8.0",
"semantic-release": "^25.0.2"
},
"optionalDependencies": {
"prettier": "^3"
},
"eslintIgnore": [
"node_modules",
"coverage",
"dist"
],
"eslintConfig": {
"extends": "./node_modules/kcd-scripts/eslint.js",
"rules": {
"camelcase": "off",
"no-process-exit": "off",
"import/extensions": "off",
"func-names": "off",
"consistent-return": "off"
}
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
Expand Down
2 changes: 0 additions & 2 deletions prettier.config.js

This file was deleted.

Loading
Loading