linthis 0.0.6__tar.gz → 0.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {linthis-0.0.6 → linthis-0.0.7}/.github/workflows/release.yml +2 -1
  2. {linthis-0.0.6 → linthis-0.0.7}/Cargo.lock +1 -1
  3. {linthis-0.0.6 → linthis-0.0.7}/Cargo.toml +1 -1
  4. {linthis-0.0.6 → linthis-0.0.7}/PKG-INFO +57 -11
  5. {linthis-0.0.6 → linthis-0.0.7}/README.md +54 -8
  6. linthis-0.0.7/docs/GLOBAL_HOOKS.md +373 -0
  7. {linthis-0.0.6 → linthis-0.0.7}/pyproject.toml +1 -1
  8. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/cpp.rs +45 -1
  9. {linthis-0.0.6 → linthis-0.0.7}/src/lib.rs +4 -1
  10. {linthis-0.0.6 → linthis-0.0.7}/src/main.rs +835 -150
  11. {linthis-0.0.6 → linthis-0.0.7}/src/utils/types.rs +7 -1
  12. {linthis-0.0.6 → linthis-0.0.7}/src/utils/walker.rs +1 -1
  13. {linthis-0.0.6 → linthis-0.0.7}/.gitignore +0 -0
  14. {linthis-0.0.6 → linthis-0.0.7}/CHANGELOG.md +0 -0
  15. {linthis-0.0.6 → linthis-0.0.7}/defaults/.clang-tidy +0 -0
  16. {linthis-0.0.6 → linthis-0.0.7}/defaults/config.toml +0 -0
  17. {linthis-0.0.6 → linthis-0.0.7}/dev.sh +0 -0
  18. {linthis-0.0.6 → linthis-0.0.7}/docs/AUTO_SYNC.md +0 -0
  19. {linthis-0.0.6 → linthis-0.0.7}/docs/SELF_UPDATE.md +0 -0
  20. {linthis-0.0.6 → linthis-0.0.7}/docs/config-cli-design.md +0 -0
  21. {linthis-0.0.6 → linthis-0.0.7}/docs/init-hooks-design.md +0 -0
  22. {linthis-0.0.6 → linthis-0.0.7}/docs/plan-ruff-integration.md +0 -0
  23. {linthis-0.0.6 → linthis-0.0.7}/docs/tasks.md +0 -0
  24. {linthis-0.0.6 → linthis-0.0.7}/scripts/release.sh +0 -0
  25. {linthis-0.0.6 → linthis-0.0.7}/src/benchmark.rs +0 -0
  26. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/go.rs +0 -0
  27. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/java.rs +0 -0
  28. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/mod.rs +0 -0
  29. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/python.rs +0 -0
  30. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/rust.rs +0 -0
  31. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/traits.rs +0 -0
  32. {linthis-0.0.6 → linthis-0.0.7}/src/checkers/typescript.rs +0 -0
  33. {linthis-0.0.6 → linthis-0.0.7}/src/config/cli.rs +0 -0
  34. {linthis-0.0.6 → linthis-0.0.7}/src/config/mod.rs +0 -0
  35. {linthis-0.0.6 → linthis-0.0.7}/src/fixers/cpplint.rs +0 -0
  36. {linthis-0.0.6 → linthis-0.0.7}/src/fixers/mod.rs +0 -0
  37. {linthis-0.0.6 → linthis-0.0.7}/src/fixers/source.rs +0 -0
  38. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/cpp.rs +0 -0
  39. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/go.rs +0 -0
  40. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/java.rs +0 -0
  41. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/mod.rs +0 -0
  42. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/python.rs +0 -0
  43. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/rust.rs +0 -0
  44. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/traits.rs +0 -0
  45. {linthis-0.0.6 → linthis-0.0.7}/src/formatters/typescript.rs +0 -0
  46. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/auto_sync.rs +0 -0
  47. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/cache.rs +0 -0
  48. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/config_manager.rs +0 -0
  49. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/fetcher.rs +0 -0
  50. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/loader.rs +0 -0
  51. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/manifest.rs +0 -0
  52. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/mod.rs +0 -0
  53. {linthis-0.0.6 → linthis-0.0.7}/src/plugin/registry.rs +0 -0
  54. {linthis-0.0.6 → linthis-0.0.7}/src/presets/mod.rs +0 -0
  55. {linthis-0.0.6 → linthis-0.0.7}/src/self_update.rs +0 -0
  56. {linthis-0.0.6 → linthis-0.0.7}/src/utils/language.rs +0 -0
  57. {linthis-0.0.6 → linthis-0.0.7}/src/utils/mod.rs +0 -0
  58. {linthis-0.0.6 → linthis-0.0.7}/src/utils/output.rs +0 -0
  59. {linthis-0.0.6 → linthis-0.0.7}/src/utils/unicode.rs +0 -0
  60. {linthis-0.0.6 → linthis-0.0.7}/test-plugin-check/README.md +0 -0
  61. {linthis-0.0.6 → linthis-0.0.7}/test-plugin-check/linthis-plugin.toml +0 -0
  62. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/test-plugin/linthis-plugin.toml +0 -0
  63. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/test-plugin/python/ruff.toml +0 -0
  64. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/test-plugin/rust/clippy.toml +0 -0
  65. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/test-plugin/rust/rustfmt.toml +0 -0
  66. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/us1/good.rs +0 -0
  67. {linthis-0.0.6 → linthis-0.0.7}/tests/fixtures/us1/unformatted.rs +0 -0
  68. {linthis-0.0.6 → linthis-0.0.7}/tests/integration/mod.rs +0 -0
@@ -36,7 +36,7 @@ jobs:
36
36
  with:
37
37
  target: ${{ matrix.target }}
38
38
  args: --release --locked --out dist
39
- manylinux: '2_17'
39
+ manylinux: '2_28'
40
40
  - name: Upload wheels
41
41
  uses: actions/upload-artifact@v4
42
42
  with:
@@ -239,6 +239,7 @@ jobs:
239
239
  name: Publish to crates.io
240
240
  runs-on: ubuntu-latest
241
241
  if: startsWith(github.ref, 'refs/tags/')
242
+ needs: [linux, windows, macos, sdist]
242
243
  steps:
243
244
  - uses: actions/checkout@v4
244
245
  - uses: dtolnay/rust-toolchain@stable
@@ -497,7 +497,7 @@ dependencies = [
497
497
 
498
498
  [[package]]
499
499
  name = "linthis"
500
- version = "0.0.6"
500
+ version = "0.0.7"
501
501
  dependencies = [
502
502
  "anyhow",
503
503
  "chrono",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "linthis"
3
- version = "0.0.6"
3
+ version = "0.0.7"
4
4
  edition = "2021"
5
5
  authors = ["zhlinh"]
6
6
  description = "A fast, cross-platform multi-language linter and formatter"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: linthis
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -16,9 +16,9 @@ Author: zhlinh
16
16
  License: MIT
17
17
  Requires-Python: >=3.8
18
18
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
19
- Project-URL: Repository, https://github.com/zhlinh/linthis
20
- Project-URL: Homepage, https://github.com/zhlinh/linthis
21
19
  Project-URL: Documentation, https://docs.rs/linthis
20
+ Project-URL: Homepage, https://github.com/zhlinh/linthis
21
+ Project-URL: Repository, https://github.com/zhlinh/linthis
22
22
 
23
23
  # linthis
24
24
 
@@ -76,14 +76,17 @@ linthis init
76
76
  # Create global configuration file
77
77
  linthis init -g
78
78
 
79
- # Initialize with pre-commit hooks
80
- linthis init --hook prek
81
- linthis init --hook pre-commit
82
- linthis init --hook git
79
+ # Create global git hook template (for all new repos)
80
+ linthis init -g --hook-type git
81
+
82
+ # Initialize with pre-commit hooks (project-level)
83
+ linthis init --hook-type prek
84
+ linthis init --hook-type pre-commit
85
+ linthis init --hook-type git
83
86
 
84
87
  # Force overwrite existing files
85
88
  linthis init --force
86
- linthis init --hook prek -f
89
+ linthis init --hook-type prek -f
87
90
  ```
88
91
 
89
92
  ### Basic Usage
@@ -506,7 +509,45 @@ All modifications preserve TOML file format and comments.
506
509
 
507
510
  ### Pre-commit Hook
508
511
 
509
- #### Method 1: Using prek (Recommended, Faster)
512
+ #### Method 1: Global Hook Template (One-time Setup)
513
+
514
+ Set up a global Git hook template that applies to all new repositories:
515
+
516
+ ```bash
517
+ # Create global hook template
518
+ linthis init -g --hook-type git
519
+
520
+ # All new repos will automatically include the hook
521
+ git init new-project
522
+ cd new-project
523
+ # .git/hooks/pre-commit is already set up!
524
+ ```
525
+
526
+ For existing repositories:
527
+ ```bash
528
+ cd existing-project
529
+ git init # Re-apply template
530
+ ```
531
+
532
+ **Features:**
533
+ - 🎯 **Smart Detection**: Only runs if project has linthis config
534
+ - 🔗 **Hook Chaining**: Supports `.git/hooks/pre-commit.local` for project-specific hooks
535
+ - 🚫 **Zero Interference**: Projects without linthis config are not affected
536
+ - ⚡ **One-time Setup**: Works for all your new repositories
537
+
538
+ **Pros:**
539
+ - One-time setup for all your projects
540
+ - No need to configure hooks per project
541
+ - Perfect for personal development
542
+ - Won't interfere with other projects or hook tools
543
+
544
+ **Cons:**
545
+ - Not shared with team members
546
+ - Requires manual setup on each machine
547
+
548
+ See [Global Hooks Guide](docs/GLOBAL_HOOKS.md) for details.
549
+
550
+ #### Method 2: Using prek (Recommended for Teams)
510
551
 
511
552
  [prek](https://prek.j178.dev) is a high-performance Git hooks manager written in Rust, fully compatible with pre-commit config format but much faster.
512
553
 
@@ -540,7 +581,7 @@ Install hook:
540
581
  prek install
541
582
  ```
542
583
 
543
- #### Method 2: Traditional Git Hook
584
+ #### Method 3: Traditional Git Hook (Project-level)
544
585
 
545
586
  Add to `.git/hooks/pre-commit`:
546
587
 
@@ -549,7 +590,12 @@ Add to `.git/hooks/pre-commit`:
549
590
  linthis --staged --check-only
550
591
  ```
551
592
 
552
- #### Method 3: Using pre-commit Framework
593
+ Or use linthis to create it automatically:
594
+ ```bash
595
+ linthis init --hook-type git
596
+ ```
597
+
598
+ #### Method 4: Using pre-commit Framework
553
599
 
554
600
  Using the [pre-commit](https://pre-commit.com/) framework:
555
601
 
@@ -54,14 +54,17 @@ linthis init
54
54
  # Create global configuration file
55
55
  linthis init -g
56
56
 
57
- # Initialize with pre-commit hooks
58
- linthis init --hook prek
59
- linthis init --hook pre-commit
60
- linthis init --hook git
57
+ # Create global git hook template (for all new repos)
58
+ linthis init -g --hook-type git
59
+
60
+ # Initialize with pre-commit hooks (project-level)
61
+ linthis init --hook-type prek
62
+ linthis init --hook-type pre-commit
63
+ linthis init --hook-type git
61
64
 
62
65
  # Force overwrite existing files
63
66
  linthis init --force
64
- linthis init --hook prek -f
67
+ linthis init --hook-type prek -f
65
68
  ```
66
69
 
67
70
  ### Basic Usage
@@ -484,7 +487,45 @@ All modifications preserve TOML file format and comments.
484
487
 
485
488
  ### Pre-commit Hook
486
489
 
487
- #### Method 1: Using prek (Recommended, Faster)
490
+ #### Method 1: Global Hook Template (One-time Setup)
491
+
492
+ Set up a global Git hook template that applies to all new repositories:
493
+
494
+ ```bash
495
+ # Create global hook template
496
+ linthis init -g --hook-type git
497
+
498
+ # All new repos will automatically include the hook
499
+ git init new-project
500
+ cd new-project
501
+ # .git/hooks/pre-commit is already set up!
502
+ ```
503
+
504
+ For existing repositories:
505
+ ```bash
506
+ cd existing-project
507
+ git init # Re-apply template
508
+ ```
509
+
510
+ **Features:**
511
+ - 🎯 **Smart Detection**: Only runs if project has linthis config
512
+ - 🔗 **Hook Chaining**: Supports `.git/hooks/pre-commit.local` for project-specific hooks
513
+ - 🚫 **Zero Interference**: Projects without linthis config are not affected
514
+ - ⚡ **One-time Setup**: Works for all your new repositories
515
+
516
+ **Pros:**
517
+ - One-time setup for all your projects
518
+ - No need to configure hooks per project
519
+ - Perfect for personal development
520
+ - Won't interfere with other projects or hook tools
521
+
522
+ **Cons:**
523
+ - Not shared with team members
524
+ - Requires manual setup on each machine
525
+
526
+ See [Global Hooks Guide](docs/GLOBAL_HOOKS.md) for details.
527
+
528
+ #### Method 2: Using prek (Recommended for Teams)
488
529
 
489
530
  [prek](https://prek.j178.dev) is a high-performance Git hooks manager written in Rust, fully compatible with pre-commit config format but much faster.
490
531
 
@@ -518,7 +559,7 @@ Install hook:
518
559
  prek install
519
560
  ```
520
561
 
521
- #### Method 2: Traditional Git Hook
562
+ #### Method 3: Traditional Git Hook (Project-level)
522
563
 
523
564
  Add to `.git/hooks/pre-commit`:
524
565
 
@@ -527,7 +568,12 @@ Add to `.git/hooks/pre-commit`:
527
568
  linthis --staged --check-only
528
569
  ```
529
570
 
530
- #### Method 3: Using pre-commit Framework
571
+ Or use linthis to create it automatically:
572
+ ```bash
573
+ linthis init --hook-type git
574
+ ```
575
+
576
+ #### Method 4: Using pre-commit Framework
531
577
 
532
578
  Using the [pre-commit](https://pre-commit.com/) framework:
533
579
 
@@ -0,0 +1,373 @@
1
+ # 全局 Git Hook 模板
2
+
3
+ ## 概述
4
+
5
+ linthis 支持创建全局 Git hook 模板,让所有新创建的 Git 仓库自动包含 linthis pre-commit hook,实现"一次配置,终身受益"。
6
+
7
+ ## 快速开始
8
+
9
+ ### 1. 创建全局 hook 模板
10
+
11
+ ```bash
12
+ # 创建全局配置 + Git hook 模板
13
+ linthis init -g --hook-type git
14
+
15
+ # 或者简写(-g 默认创建 git hook 模板)
16
+ linthis init -g
17
+ ```
18
+
19
+ 输出:
20
+ ```
21
+ ✓ Created /Users/username/.linthis/config.toml
22
+ ✓ Created /Users/username/.linthis/.git-template/hooks/pre-commit
23
+ ✓ Configured git global template: init.templateDir
24
+ All new repositories will include this hook
25
+
26
+ Next steps:
27
+ • New repositories will automatically include the linthis hook
28
+ • For existing repositories, run: git init
29
+ • Or manually copy the hook to .git/hooks/pre-commit
30
+ ```
31
+
32
+ ### 2. 自动生效
33
+
34
+ 创建新仓库时,hook 会自动包含:
35
+
36
+ ```bash
37
+ # 创建新仓库
38
+ mkdir my-project
39
+ cd my-project
40
+ git init
41
+
42
+ # hook 已经自动创建
43
+ ls .git/hooks/pre-commit # ✓ 存在
44
+ ```
45
+
46
+ ### 3. 应用到现有仓库
47
+
48
+ 对于已存在的仓库,运行 `git init` 重新应用模板:
49
+
50
+ ```bash
51
+ cd existing-project
52
+ git init # 会复制模板中的 hooks
53
+ ```
54
+
55
+ ## 详细说明
56
+
57
+ ### 目录结构
58
+
59
+ 全局 hook 模板存放在:
60
+ ```
61
+ ~/.linthis/
62
+ ├── config.toml # 全局配置
63
+ └── .git-template/ # Git 模板目录
64
+ └── hooks/
65
+ └── pre-commit # pre-commit hook 模板
66
+ ```
67
+
68
+ ### Git 配置
69
+
70
+ linthis 会自动配置 Git 全局设置:
71
+
72
+ ```bash
73
+ # 查看配置
74
+ git config --global --get init.templateDir
75
+ # 输出: /Users/username/.linthis/.git-template
76
+ ```
77
+
78
+ 这个配置让 `git init` 和 `git clone` 自动应用模板。
79
+
80
+ ### Hook 内容
81
+
82
+ 默认创建的 hook 内容:
83
+
84
+ ```bash
85
+ #!/bin/sh
86
+ # linthis pre-commit hook (global template)
87
+ linthis -s -c -f -w
88
+ ```
89
+
90
+ 参数说明:
91
+ - `-s`: 仅检查暂存文件
92
+ - `-c`: 运行检查
93
+ - `-f`: 运行格式化
94
+ - `-w`: 警告视为错误(严格模式)
95
+
96
+ ## 高级用法
97
+
98
+ ### 自定义 Hook 行为
99
+
100
+ #### 仅检查模式
101
+
102
+ ```bash
103
+ linthis init -g --hook-type git --hook-check-only
104
+ ```
105
+
106
+ 生成的 hook:
107
+ ```bash
108
+ #!/bin/sh
109
+ # linthis pre-commit hook (global template)
110
+ linthis -s -c -w
111
+ ```
112
+
113
+ #### 仅格式化模式
114
+
115
+ ```bash
116
+ linthis init -g --hook-type git --hook-format-only
117
+ ```
118
+
119
+ 生成的 hook:
120
+ ```bash
121
+ #!/bin/sh
122
+ # linthis pre-commit hook (global template)
123
+ linthis -s -f -w
124
+ ```
125
+
126
+ ### 强制覆盖
127
+
128
+ 如果模板已存在,使用 `--force` 覆盖:
129
+
130
+ ```bash
131
+ linthis init -g --hook-type git --force
132
+ ```
133
+
134
+ ### 禁用 Hook 创建
135
+
136
+ 只创建全局配置,不创建 hook 模板:
137
+
138
+ ```bash
139
+ linthis init -g --no-hook
140
+ ```
141
+
142
+ ## 与项目级 Hook 的区别
143
+
144
+ | 特性 | 全局模板 (`-g`) | 项目级 Hook |
145
+ |------|----------------|-------------|
146
+ | 作用范围 | 所有新仓库 | 当前项目 |
147
+ | 配置位置 | `~/.linthis/.git-template/` | `.git/hooks/` |
148
+ | 可提交到仓库 | ❌ 否 | ❌ 否(.git 不被跟踪) |
149
+ | 团队共享 | ❌ 否 | 需要 prek/pre-commit |
150
+ | 适用场景 | 个人开发环境 | 单个项目 |
151
+
152
+ ## 团队协作建议
153
+
154
+ ### 个人开发者
155
+
156
+ 使用全局模板:
157
+ ```bash
158
+ linthis init -g
159
+ ```
160
+
161
+ ### 团队项目
162
+
163
+ 使用 prek 或 pre-commit(配置可提交):
164
+
165
+ ```bash
166
+ # 在项目目录
167
+ linthis init --hook-type prek
168
+ # 或
169
+ linthis init --hook-type pre-commit
170
+ ```
171
+
172
+ 这样配置文件可以提交到仓库,团队成员共享。
173
+
174
+ ## 常见问题
175
+
176
+ ### Q1: 如何卸载全局 hook 模板?
177
+
178
+ ```bash
179
+ # 删除模板目录
180
+ rm -rf ~/.linthis/.git-template
181
+
182
+ # 取消 git 配置
183
+ git config --global --unset init.templateDir
184
+ ```
185
+
186
+ ### Q2: 现有仓库不想使用这个 hook 怎么办?
187
+
188
+ **方法 1**(推荐):不创建 linthis 配置文件
189
+
190
+ Hook 会自动检测,如果项目没有 linthis 配置文件,就不会运行 linthis。
191
+
192
+ **方法 2**:删除 hook
193
+
194
+ ```bash
195
+ # 删除项目中的 hook
196
+ cd my-project
197
+ rm .git/hooks/pre-commit
198
+ ```
199
+
200
+ ### Q3: 可以同时使用全局模板和项目级 prek 吗?
201
+
202
+ 可以,但不推荐。建议:
203
+ - 个人项目:使用全局模板
204
+ - 团队项目:使用项目级 prek/pre-commit
205
+
206
+ ### Q4: hook 不执行怎么办?
207
+
208
+ 检查权限:
209
+ ```bash
210
+ ls -l ~/.linthis/.git-template/hooks/pre-commit
211
+ # 应该显示 -rwxr-xr-x (可执行)
212
+
213
+ # 如果不可执行,手动设置
214
+ chmod +x ~/.linthis/.git-template/hooks/pre-commit
215
+ ```
216
+
217
+ ### Q5: 为什么 `-g --hook-type prek` 会警告?
218
+
219
+ 全局模板只支持 git hook 类型,因为:
220
+ - prek/pre-commit 需要在项目目录运行 `prek install`
221
+ - 它们的配置文件(.pre-commit-config.yaml)是项目级的
222
+
223
+ 如果需要 prek/pre-commit,请在项目目录使用:
224
+ ```bash
225
+ linthis init --hook-type prek
226
+ ```
227
+
228
+ ### Q6: 如何与其他 hook 工具(husky、pre-commit)共存?
229
+
230
+ **方案 1**:使用 `.git/hooks/pre-commit.local`
231
+
232
+ 全局 hook 会自动链式调用 `.local` 文件:
233
+
234
+ ```bash
235
+ # 将其他工具的命令放到 .local 文件
236
+ cat > .git/hooks/pre-commit.local << 'EOF'
237
+ #!/bin/sh
238
+ # 运行其他检查
239
+ npm run lint
240
+ pytest
241
+ EOF
242
+ chmod +x .git/hooks/pre-commit.local
243
+ ```
244
+
245
+ 执行顺序:
246
+ 1. linthis(如果有配置)
247
+ 2. .local 中的命令
248
+
249
+ **方案 2**:禁用全局 hook,使用工具自己的 hook
250
+
251
+ ```bash
252
+ # 项目中不创建 linthis 配置
253
+ # 全局 hook 会自动跳过,不影响其他工具
254
+ ```
255
+
256
+ ### Q7: 会不会影响不使用 linthis 的项目?
257
+
258
+ **不会!** Hook 使用智能检测:
259
+
260
+ - 只有存在 linthis 配置文件时才运行
261
+ - 没有配置文件的项目完全不受影响
262
+ - 测试验证:创建新项目不添加 linthis 配置,hook 不会执行任何 linthis 命令
263
+
264
+ ## 智能执行机制
265
+
266
+ 全局 hook 模板使用**智能条件执行**,不会干扰其他项目:
267
+
268
+ ### 工作流程
269
+
270
+ 1. **创建模板**:linthis 在 `~/.linthis/.git-template/hooks/` 创建智能 pre-commit
271
+ 2. **配置 Git**:设置 `git config --global init.templateDir`
272
+ 3. **自动应用**:`git init` 时 Git 会复制模板目录的内容到 `.git/`
273
+ 4. **Hook 执行**:提交时 Git 自动运行 `.git/hooks/pre-commit`
274
+
275
+ ### 智能检测逻辑
276
+
277
+ Hook 会按以下顺序执行:
278
+
279
+ ```bash
280
+ 1. 检查项目是否有 linthis 配置文件:
281
+ - .linthis/config.toml
282
+ - .linthis.toml
283
+ - linthis.toml
284
+
285
+ 2. 如果有配置 → 运行 linthis
286
+ 如果没有配置 → 跳过 linthis(不影响项目)
287
+
288
+ 3. 检查是否有项目特定 hook:
289
+ - .git/hooks/pre-commit.local
290
+
291
+ 4. 如果存在 → 链式调用执行
292
+ ```
293
+
294
+ ### Hook 源码
295
+
296
+ 生成的智能 hook 内容:
297
+
298
+ ```bash
299
+ #!/bin/sh
300
+ # linthis pre-commit hook (global template)
301
+ # This hook is installed globally and will only run if the project uses linthis
302
+
303
+ # Check if this project uses linthis
304
+ if [ -f ".linthis/config.toml" ] || [ -f ".linthis.toml" ] || [ -f "linthis.toml" ]; then
305
+ # Run linthis for this project
306
+ linthis -s -c -f -w || exit 1
307
+ fi
308
+
309
+ # Chain to project-specific hook if it exists
310
+ # This allows projects to have their own hooks alongside linthis
311
+ if [ -f ".git/hooks/pre-commit.local" ]; then
312
+ .git/hooks/pre-commit.local || exit 1
313
+ fi
314
+ ```
315
+
316
+ ### 场景示例
317
+
318
+ #### 场景 1:使用 linthis 的项目
319
+
320
+ ```bash
321
+ my-rust-project/
322
+ ├── .linthis/
323
+ │ └── config.toml # ✓ 有配置文件
324
+ └── .git/
325
+ └── hooks/
326
+ └── pre-commit # 会运行 linthis
327
+ ```
328
+
329
+ **结果**:提交时自动运行 linthis 检查和格式化
330
+
331
+ #### 场景 2:不使用 linthis 的项目
332
+
333
+ ```bash
334
+ other-project/
335
+ └── .git/
336
+ └── hooks/
337
+ └── pre-commit # ✗ 没有 linthis 配置
338
+ ```
339
+
340
+ **结果**:hook 跳过 linthis,不影响项目
341
+
342
+ #### 场景 3:有额外 hook 需求的项目
343
+
344
+ ```bash
345
+ complex-project/
346
+ ├── .linthis/
347
+ │ └── config.toml # ✓ 有配置文件
348
+ └── .git/
349
+ └── hooks/
350
+ ├── pre-commit # 运行 linthis
351
+ └── pre-commit.local # 然后运行这个
352
+ ```
353
+
354
+ **结果**:先运行 linthis,再运行项目特定的检查
355
+
356
+ #### 场景 4:使用其他 hook 工具的项目
357
+
358
+ 如果项目使用 husky、pre-commit 等工具:
359
+
360
+ ```bash
361
+ # 方案 1:移除全局 hook,使用工具自己的 hook
362
+ rm .git/hooks/pre-commit
363
+ # 然后 husky/pre-commit 会创建自己的 hook
364
+
365
+ # 方案 2:将工具的命令放到 pre-commit.local
366
+ mv .git/hooks/pre-commit .git/hooks/pre-commit.backup
367
+ # 创建 pre-commit.local 调用其他工具
368
+ ```
369
+
370
+ ## 参考
371
+
372
+ - [Git 文档 - init.templateDir](https://git-scm.com/docs/git-init#_template_directory)
373
+ - [linthis Hook 集成设计](./init-hooks-design.md)
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "linthis"
7
- version = "0.0.6"
7
+ version = "0.0.7"
8
8
  description = "A fast, cross-platform multi-language linter and formatter"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -51,14 +51,36 @@ impl CppChecker {
51
51
  // Try to load cpplint config from linthis config files
52
52
  let (cpp_config, oc_config) = Self::load_cpplint_configs();
53
53
 
54
+ // Load clang-tidy config from linthis plugin configs
55
+ let clang_tidy_config = Self::find_plugin_clang_tidy_config();
56
+
54
57
  Self {
55
- config_path: None,
58
+ config_path: clang_tidy_config,
56
59
  compile_commands_dir: None,
57
60
  cpplint_cpp_config: cpp_config,
58
61
  cpplint_oc_config: oc_config,
59
62
  }
60
63
  }
61
64
 
65
+ /// Find clang-tidy config from linthis plugin configs
66
+ fn find_plugin_clang_tidy_config() -> Option<PathBuf> {
67
+ let project_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
68
+
69
+ // Check for cpp config first
70
+ let cpp_clang_tidy = project_dir.join(".linthis/configs/cpp/.clang-tidy");
71
+ if cpp_clang_tidy.exists() {
72
+ return Some(cpp_clang_tidy);
73
+ }
74
+
75
+ // Check for oc config as fallback
76
+ let oc_clang_tidy = project_dir.join(".linthis/configs/oc/.clang-tidy");
77
+ if oc_clang_tidy.exists() {
78
+ return Some(oc_clang_tidy);
79
+ }
80
+
81
+ None
82
+ }
83
+
62
84
  /// Load cpplint configs from linthis configuration
63
85
  fn load_cpplint_configs() -> (CpplintConfig, CpplintConfig) {
64
86
  use crate::config::Config;
@@ -371,6 +393,11 @@ impl CppChecker {
371
393
 
372
394
  /// Run clang-tidy on a file (check only, no fix)
373
395
  fn run_clang_tidy(&self, path: &Path) -> Result<Vec<LintIssue>> {
396
+ // Skip clang-tidy if LINTHIS_SKIP_CLANG_TIDY env var is set
397
+ if std::env::var("LINTHIS_SKIP_CLANG_TIDY").is_ok() {
398
+ return Ok(vec![]);
399
+ }
400
+
374
401
  let mut cmd = Command::new("clang-tidy");
375
402
  cmd.arg(path);
376
403
 
@@ -468,6 +495,23 @@ impl CppChecker {
468
495
  }
469
496
 
470
497
  let file_path_parsed = std::path::PathBuf::from(parts[0]);
498
+
499
+ // Filter out issues from third_party and other excluded directories
500
+ // Check both the parsed path and individual components
501
+ let path_str = file_path_parsed.to_string_lossy();
502
+ if path_str.contains("third_party")
503
+ || path_str.contains("thirdparty")
504
+ || path_str.contains("third-party")
505
+ || path_str.contains("3rdparty")
506
+ || path_str.contains("3rd_party")
507
+ || path_str.contains("3rd-party")
508
+ || path_str.contains("external")
509
+ || path_str.contains("externals")
510
+ || path_str.contains("vendor")
511
+ || path_str.contains("node_modules") {
512
+ return None;
513
+ }
514
+
471
515
  let line_num = parts[1].trim().parse::<usize>().ok()?;
472
516
  let col = parts[2].trim().parse::<usize>().ok();
473
517