Skip to content

Commit a1b72f2

Browse files
Merge pull request #162 from BitGo/BTC-2650.git-hooks
feat: add pre-commit hooks with lint-staged
2 parents 924b7f0 + 2505123 commit a1b72f2

15 files changed

Lines changed: 862 additions & 51 deletions

File tree

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lint-staged

README.md

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,28 @@
22

33
This repo is the home of BitGo's WASM libraries.
44

5-
65
# Dependencies
76

87
- [Rust](https://www.rust-lang.org/) nightly
98
- [wasm-pack](https://rustwasm.github.io/wasm-pack/) (install with `cargo install wasm-pack`)
109
- [Node.js](https://nodejs.org/en/)
1110

11+
# Developer Setup
12+
13+
```bash
14+
npm install
15+
```
16+
17+
This will:
18+
19+
- Install all dependencies
20+
- Set up pre-commit hooks via Husky
21+
22+
Pre-commit hooks automatically run on staged files:
23+
24+
- **JS/TS**: Prettier formatting + ESLint
25+
- **Rust**: `cargo fmt` + `cargo clippy`
26+
1227
# Package Management
1328

1429
This monorepo uses [Lerna](https://lerna.js.org/) for managing package versions and publishing to npm.
@@ -44,7 +59,6 @@ npx lerna changed
4459

4560
# Packages
4661

47-
4862
## wasm-utxo
4963

5064
This is a wrapper around the
@@ -56,5 +70,4 @@ compiled to WebAssembly.
5670

5771
A live playground for the wasm-utxo crate.
5872

59-
Go to https://bitgo.github.io/wasm-utxo to see a live demo of the wasm-utxo library in action. *WIP*
60-
73+
Go to https://bitgo.github.io/wasm-utxo to see a live demo of the wasm-utxo library in action. _WIP_

lint-staged.config.mjs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { existsSync } from "fs";
2+
3+
const IGNORED_PATTERNS = [
4+
"node_modules",
5+
"/dist/",
6+
"/target/",
7+
"/pkg/",
8+
"/js/wasm/",
9+
"/bundler-test/",
10+
];
11+
12+
function filterIgnored(filenames) {
13+
return filenames.filter((f) => !IGNORED_PATTERNS.some((p) => f.includes(p)));
14+
}
15+
16+
/** Extract package name from a file path like packages/wasm-utxo/src/foo.rs */
17+
function getPackageName(filepath) {
18+
const match = filepath.match(/packages\/([^/]+)\//);
19+
return match?.[1];
20+
}
21+
22+
/** Group files by their package name */
23+
function groupByPackage(filenames) {
24+
const groups = new Map();
25+
for (const f of filenames) {
26+
const pkg = getPackageName(f);
27+
if (!pkg) continue;
28+
if (!groups.has(pkg)) groups.set(pkg, []);
29+
groups.get(pkg).push(f);
30+
}
31+
return groups;
32+
}
33+
34+
export default {
35+
"*.{js,ts,tsx,mjs,cjs}": (filenames) => {
36+
const filtered = filterIgnored(filenames);
37+
if (filtered.length === 0) return [];
38+
39+
const commands = [`prettier --write ${filtered.join(" ")}`];
40+
41+
for (const [pkg, files] of groupByPackage(filtered)) {
42+
const configPath = `packages/${pkg}/eslint.config.js`;
43+
if (existsSync(configPath)) {
44+
commands.push(`npx eslint -c ${configPath} --fix ${files.join(" ")}`);
45+
}
46+
}
47+
48+
return commands;
49+
},
50+
51+
"*.{json,yaml,yml,md}": (filenames) => {
52+
const filtered = filterIgnored(filenames);
53+
if (filtered.length === 0) return [];
54+
return [`prettier --write ${filtered.join(" ")}`];
55+
},
56+
57+
"*.rs": (filenames) => {
58+
const filtered = filterIgnored(filenames);
59+
if (filtered.length === 0) return [];
60+
61+
const commands = [];
62+
for (const pkg of new Set(filtered.map(getPackageName).filter(Boolean))) {
63+
const manifest = `packages/${pkg}/Cargo.toml`;
64+
if (existsSync(manifest)) {
65+
commands.push(`cargo fmt --manifest-path ${manifest}`);
66+
commands.push(
67+
`cargo clippy --manifest-path ${manifest} --all-targets --all-features -- -D warnings`,
68+
);
69+
}
70+
}
71+
return commands;
72+
},
73+
};

0 commit comments

Comments
 (0)