From ce43a7aa7009649b973ed355987299b762d01d51 Mon Sep 17 00:00:00 2001 From: Jaw <53564781+jaw52@users.noreply.github.com> Date: Thu, 29 Oct 2026 17:47:55 +0800 Subject: [PATCH] chore: add pre-commit hook with simple-git-hooks and lint-staged (#252) Run oxlint --fix and oxfmt on staged files before each commit, and rustfmt on staged Rust files. simple-git-hooks installs the hook from its postinstall, allowed in pnpm-workspace.yaml. Co-authored-by: Claude Opus 5.5 --- package.json | 10 +++++++ pnpm-lock.yaml | 68 +++++++++++++++++++++++++++++++++++---------- pnpm-workspace.yaml | 2 ++ 3 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 pnpm-workspace.yaml diff --git a/package.json b/package.json index a9f1ba86..07f53c43 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,14 @@ "perf": "node perf/run.ts", "perf:rust": "node perf/rust.ts" }, + "simple-git-hooks": { + "pre-commit": "pnpm lint-staged" + }, + "lint-staged": { + "*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}": "oxlint --fix --no-error-on-unmatched-pattern", + "*": "oxfmt --no-error-on-unmatched-pattern", + "*.rs": "rustfmt --edition 2024" + }, "dependencies": { "@codemirror/autocomplete": "^6.20.3", "@codemirror/commands": "^6.11.1", @@ -71,8 +79,10 @@ "@types/react-dom": "^19.1.6", "@vitejs/plugin-react": "^6.0.2", "jsdom": "^30.1.3", + "lint-staged": "^17.6.0", "oxfmt": "^0.74.0", "oxlint": "^1.89.0", + "simple-git-hooks": "^2.14.0", "tsrs": "^0.20.0-ts7.1.0-beta", "typescript": "~6.0.3", "vite": "^8.0.16", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8606c3d3..d2c577df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -116,7 +116,7 @@ importers: version: 2.12.3 '@testing-library/jest-dom': specifier: ^7.0.1 - version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5))) + version: 7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))) '@testing-library/react': specifier: ^16.3.3 version: 16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) @@ -137,16 +137,22 @@ importers: version: 19.3.0(@types/react@19.3.0) '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.1.2(vite@8.3.4(@types/node@26.6.5)) + version: 6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) jsdom: specifier: ^30.1.3 version: 30.1.3 + lint-staged: + specifier: ^17.6.0 + version: 17.6.0 oxfmt: specifier: ^0.74.0 version: 0.74.0 oxlint: specifier: ^1.89.0 version: 1.89.0 + simple-git-hooks: + specifier: ^2.14.0 + version: 2.14.0 tsrs: specifier: ^0.20.0-ts7.1.0-beta version: 0.20.0-ts7.1.0-beta @@ -155,10 +161,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.16 - version: 8.3.4(@types/node@26.6.5) + version: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) vitest: specifier: ^5.0.5 - version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)) + version: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) packages: @@ -1581,6 +1587,11 @@ packages: resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} + lint-staged@17.6.0: + resolution: {integrity: sha512-nOhBfYkZEwkFtNzD5pK9s9LkcWoxJ+whLzEnhqi9nl7zTB5n7tg8+9iYgMGx2Wm3VlLu8cbNj0RACzY+nWi5iQ==} + engines: {node: '>=22.22.1'} + hasBin: true + lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -1748,6 +1759,10 @@ packages: scheduler@0.28.0: resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==} + simple-git-hooks@2.14.0: + resolution: {integrity: sha512-kkTORPAuxQz2g1QUuN0J8yGWT28tjGBfPOdJ4xT7Vbeu30veKUZQIoID2qGgCDAakaQn59UeZJJ4cFGB8PVP2A==} + hasBin: true + source-map-js@1.2.2: resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} @@ -1755,6 +1770,10 @@ packages: std-env@4.3.0: resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -1936,6 +1955,11 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + zustand@5.0.15: resolution: {integrity: sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A==} engines: {node: '>=12.20.0'} @@ -2698,7 +2722,7 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)))': + '@testing-library/jest-dom@7.0.1(@testing-library/dom@10.4.2)(vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)))': dependencies: '@adobe/css-tools': 4.5.0 '@testing-library/dom': 10.4.2 @@ -2708,7 +2732,7 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 optionalDependencies: - vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)) + vitest: 5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) '@testing-library/react@16.3.3(@testing-library/dom@10.4.2)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1)': dependencies: @@ -2899,19 +2923,19 @@ snapshots: d3-selection: 3.0.0 d3-transition: 3.0.1(d3-selection@3.0.0) - '@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5))': + '@vitejs/plugin-react@6.1.2(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.3.4(@types/node@26.6.5) + vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) - '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5))': + '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.5 estree-walker: 3.0.3 magic-string: 1.4.3 optionalDependencies: - vite: 8.3.4(@types/node@26.6.5) + vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) '@vitest/spy@5.0.5': {} @@ -3331,6 +3355,14 @@ snapshots: lightningcss-win32-arm64-msvc: 1.33.0 lightningcss-win32-x64-msvc: 1.33.0 + lint-staged@17.6.0: + dependencies: + picomatch: 4.0.7 + string-argv: 0.3.2 + tinyexec: 1.3.1 + optionalDependencies: + yaml: 2.9.1 + lodash-es@4.18.1: {} lru-cache@11.5.3: {} @@ -3525,10 +3557,14 @@ snapshots: scheduler@0.28.0: {} + simple-git-hooks@2.14.0: {} + source-map-js@1.2.2: {} std-env@4.3.0: {} + string-argv@0.3.2: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -3582,7 +3618,7 @@ snapshots: uuid@14.0.3: {} - vite@8.3.4(@types/node@26.6.5): + vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -3592,11 +3628,12 @@ snapshots: optionalDependencies: '@types/node': 26.6.5 fsevents: 2.3.3 + yaml: 2.9.1 - vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)): + vitest@5.0.5(@types/node@26.6.5)(jsdom@30.1.3)(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)) + '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@26.6.5)(yaml@2.9.1)) chai: 6.3.0 es-module-lexer: 2.3.2 expect-type: 1.4.0 @@ -3607,7 +3644,7 @@ snapshots: tinybench: 6.2.2 tinyexec: 1.3.1 tinyglobby: 0.2.17 - vite: 8.3.4(@types/node@26.6.5) + vite: 8.3.4(@types/node@26.6.5)(yaml@2.9.1) why-is-node-running: 3.2.1 optionalDependencies: '@types/node': 26.6.5 @@ -3639,6 +3676,9 @@ snapshots: xmlchars@2.2.0: {} + yaml@2.9.1: + optional: true + zustand@5.0.15(@types/react@19.3.0)(immer@11.1.21)(react@19.3.1): optionalDependencies: '@types/react': 19.3.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..b05c3b25 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +allowBuilds: + simple-git-hooks: true