Skip to content

Commit 921ef78

Browse files
committed
Add linting via pre-commit
Use the pre-commit framework to check cmake, clang-format, spellcheck, git, and shell scripts.
1 parent f7f4cf6 commit 921ef78

10 files changed

+284
-1
lines changed

.cmake-format.json

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"parse": {
3+
"additional_commands": {
4+
"foo": {
5+
"flags": [
6+
"BAR",
7+
"BAZ"
8+
],
9+
"kwargs": {
10+
"HEADERS": "*",
11+
"SOURCES": "*",
12+
"DEPENDS": "*"
13+
}
14+
}
15+
},
16+
"override_spec": {},
17+
"vartags": [],
18+
"proptags": []
19+
},
20+
"format": {
21+
"disable": false,
22+
"line_width": 80,
23+
"tab_size": 2,
24+
"use_tabchars": false,
25+
"fractional_tab_policy": "use-space",
26+
"max_subgroups_hwrap": 2,
27+
"max_pargs_hwrap": 6,
28+
"max_rows_cmdline": 2,
29+
"separate_ctrl_name_with_space": false,
30+
"separate_fn_name_with_space": false,
31+
"dangle_parens": false,
32+
"dangle_align": "prefix",
33+
"min_prefix_chars": 4,
34+
"max_prefix_chars": 10,
35+
"max_lines_hwrap": 2,
36+
"line_ending": "unix",
37+
"command_case": "canonical",
38+
"keyword_case": "unchanged",
39+
"always_wrap": [],
40+
"enable_sort": true,
41+
"autosort": false,
42+
"require_valid_layout": false,
43+
"layout_passes": {}
44+
},
45+
"markup": {
46+
"bullet_char": "*",
47+
"enum_char": ".",
48+
"first_comment_is_literal": false,
49+
"literal_comment_pattern": null,
50+
"fence_pattern": "^\\s*([`~]{3}[`~]*)(.*)$",
51+
"ruler_pattern": "^\\s*[^\\w\\s]{3}.*[^\\w\\s]{3}$",
52+
"explicit_trailing_pattern": "#<",
53+
"hashruler_min_length": 10,
54+
"canonicalize_hashrulers": true,
55+
"enable_markup": true
56+
},
57+
"lint": {
58+
"disabled_codes": [],
59+
"function_pattern": "[0-9a-z_]+",
60+
"macro_pattern": "[0-9A-Z_]+",
61+
"global_var_pattern": "[A-Z][0-9A-Z_]+",
62+
"internal_var_pattern": "_[A-Z][0-9A-Z_]+",
63+
"local_var_pattern": "[a-z][a-z0-9_]+",
64+
"private_var_pattern": "_[0-9a-z_]+",
65+
"public_var_pattern": "[A-Z][0-9A-Z_]+",
66+
"argument_var_pattern": "[a-z][a-z0-9_]+",
67+
"keyword_pattern": "[A-Z][0-9A-Z_]+",
68+
"max_conditionals_custom_parser": 2,
69+
"min_statement_spacing": 1,
70+
"max_statement_spacing": 2,
71+
"max_returns": 6,
72+
"max_branches": 12,
73+
"max_arguments": 5,
74+
"max_localvars": 15,
75+
"max_statements": 50
76+
},
77+
"encode": {
78+
"emit_byteorder_mark": false,
79+
"input_encoding": "utf-8",
80+
"output_encoding": "utf-8"
81+
},
82+
"misc": {
83+
"per_command": {}
84+
}
85+
}

.codespell_ignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
copyable
2+
falsy
3+
pullrequest
4+
unexpect

.pre-commit-config.yaml

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# See https://pre-commit.com for more information
2+
# See https://pre-commit.com/hooks.html for more hooks
3+
repos:
4+
- repo: https://github.com/pre-commit/pre-commit-hooks
5+
rev: v4.6.0
6+
hooks:
7+
- id: check-added-large-files
8+
- id: check-case-conflict
9+
- id: check-executables-have-shebangs
10+
- id: check-json
11+
- id: check-merge-conflict
12+
- id: check-symlinks
13+
- id: check-toml
14+
- id: check-xml
15+
- id: check-yaml
16+
- id: detect-private-key
17+
- id: end-of-file-fixer
18+
exclude: '^(.*\.svg)$'
19+
- id: mixed-line-ending
20+
args: ['--fix=lf']
21+
exclude: '^(.*\.svg)$'
22+
- id: trailing-whitespace
23+
exclude: '^(|.*\.svg)$'
24+
- id: fix-byte-order-marker
25+
- id: no-commit-to-branch
26+
- id: requirements-txt-fixer
27+
28+
- repo: local
29+
hooks:
30+
- id: clang-format-fix
31+
name: clang-format-fix
32+
entry: clang-format-18
33+
types_or: [c++, c]
34+
language: python
35+
args: ['-i']
36+
stages: [manual]
37+
38+
- repo: https://github.com/pocc/pre-commit-hooks
39+
rev: v1.3.5
40+
hooks:
41+
- id: clang-format
42+
additional_dependencies: ['clang-format==18.1.8']
43+
# - id: oclint
44+
# - id: cppcheck
45+
# - id: cpplint
46+
- repo: https://github.com/pocc/pre-commit-hooks
47+
rev: v1.3.5
48+
hooks:
49+
- id: clang-tidy
50+
stages: [manual]
51+
52+
- repo: https://github.com/codespell-project/codespell
53+
rev: v2.2.6
54+
hooks:
55+
- id: codespell
56+
args: ['-I', '.codespell_ignore', '--uri-ignore-words-list']
57+
exclude: |
58+
(?x)^(
59+
papers/.*
60+
)$
61+
62+
# CMake formatting
63+
- repo: https://github.com/cheshirekow/cmake-format-precommit
64+
rev: "v0.6.13"
65+
hooks:
66+
- id: cmake-format
67+
additional_dependencies: [pyyaml]
68+
- id: cmake-lint
69+
70+
- repo: https://github.com/jorisroovers/gitlint
71+
rev: v0.19.1
72+
hooks:
73+
- id: gitlint
74+
- id: gitlint-ci
75+
76+
- repo: https://github.com/shellcheck-py/shellcheck-py
77+
rev: v0.10.0.1
78+
hooks:
79+
- id: shellcheck
80+
81+
exclude: 'vendor'

.shellcheckrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# shellcheck
22
# allow for non-alphanumeric filenames
3-
disable=SC2038
3+
disable=SC2038

Makefile

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,67 @@ env:
9191
papers:
9292
$(MAKE) -C papers papers
9393

94+
PYEXECPATH ?= $(shell which python3.12 || which python3.11 || which python3.10 || which python3.9 || which python3.8 || which python3.7 || which python3)
95+
PYTHON ?= $(shell basename $(PYEXECPATH))
96+
VENV := .venv
97+
ACTIVATE := . $(VENV)/bin/activate &&
98+
PYEXEC := $(ACTIVATE) $(PYTHON)
99+
MARKER=.initialized.venv.stamp
100+
101+
PIP := $(PYEXEC) -m pip
102+
PIP_SYNC := $(PYEXEC) -m piptools sync
103+
PIPTOOLS_COMPILE := $(PYEXEC) -m piptools compile --no-header --strip-extras
104+
105+
PRE_COMMIT := $(ACTIVATE) pre-commit
106+
107+
PHONY: venv
108+
venv: ## Create python virtual env
109+
venv: $(VENV)/$(MARKER)
110+
111+
.PHONY: clean-venv
112+
clean-venv:
113+
clean-venv: ## Delete python virtual env
114+
-rm -rf $(VENV)
115+
116+
realclean: clean-venv
117+
118+
.PHONY: show-venv
119+
show-venv: venv
120+
show-venv: ## Debugging target - show venv details
121+
$(PYEXEC) -c "import sys; print('Python ' + sys.version.replace('\n',''))"
122+
$(PIP) --version
123+
@echo venv: $(VENV)
124+
125+
requirements.txt: requirements.in
126+
$(PIPTOOLS_COMPILE) --output-file=$@ $<
127+
128+
requirements-dev.txt: requirements-dev.in
129+
$(PIPTOOLS_COMPILE) --output-file=$@ $<
130+
131+
$(VENV):
132+
$(PYEXECPATH) -m venv $(VENV)
133+
$(PIP) install --upgrade pip setuptools wheel
134+
$(PIP) install pip-tools
135+
136+
$(VENV)/$(MARKER): requirements.txt requirements-dev.txt | $(VENV)
137+
$(PIP_SYNC) requirements.txt
138+
$(PIP_SYNC) requirements-dev.txt
139+
touch $(VENV)/$(MARKER)
140+
141+
.PHONY: dev-shell
142+
dev-shell: venv
143+
dev-shell: ## Shell with the venv activated
144+
$(ACTIVATE) $(notdir $(SHELL))
145+
146+
.PHONY: bash zsh
147+
bash zsh: venv
148+
bash zsh: ## Run bash or zsh with the venv activated
149+
$(ACTIVATE) exec $@
150+
151+
lint: venv
152+
lint: ## Run all configured tools in pre-commit
153+
$(PRE_COMMIT) run -a
154+
94155
# Help target
95156
.PHONY: help
96157
help: ## Show this help.

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,36 @@ Test project /path/to/Beman.Optional26/.build
237237
No tests were found!!!
238238
```
239239

240+
#### Pre-Commit for Linting
241+
Various linting tools are configured and installed via the [pre-commit](https://pre-commit.com/) framework. This requires a working python environment, but also allows the tools, such as clang-format and cmake-lint, to be versioned on a per project basis rather than being installed globally. Version changes in lint checks often means differences in success or failure between the versions in CI and the versions used by a developer. By using the same configurations, this problem is avoided.
242+
243+
In order to set up a python environment, using a python virtual environment can simplify maintaining different configurations between projects. There is no particular dependency on a particular python3 version.
244+
245+
##### Creating and configuring a venv
246+
```shell
247+
python3 -m venv .venv
248+
. .venv/bin/activate && python3 -m pip install --upgrade pip setuptools wheel
249+
. .venv/bin/activate && python3 -m pip install pip-tools
250+
. .venv/bin/activate && python3 -m piptools sync requirements.txt
251+
. .venv/bin/activate && python3 -m piptools sync requirements-dev.txt
252+
. .venv/bin/activate && exec bash
253+
```
254+
255+
This will create the venv, install the python and python development tools, and run bash with the PATH and other environment variables set to use the venv preferentially.
256+
257+
##### Running the linting tools
258+
```shell
259+
pre-commit run -a
260+
```
261+
262+
This will download and configure the lint tools specified in .pre-commit-config.yaml.
263+
264+
There is also a Makefile that will automate this process and keep everything up to date.
265+
266+
```shell
267+
make lint
268+
```
269+
240270
## Papers
241271

242272
Latest revision(s) of the papers can be built / found at:

requirements-dev.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pre-commit
2+
clang-format==18.1.8

requirements-dev.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cfgv==3.4.0
2+
# via pre-commit
3+
clang-format==18.1.8
4+
# via -r requirements-dev.in
5+
distlib==0.3.8
6+
# via virtualenv
7+
filelock==3.15.4
8+
# via virtualenv
9+
identify==2.6.0
10+
# via pre-commit
11+
nodeenv==1.9.1
12+
# via pre-commit
13+
platformdirs==4.2.2
14+
# via virtualenv
15+
pre-commit==3.7.1
16+
# via -r requirements-dev.in
17+
pyyaml==6.0.1
18+
# via pre-commit
19+
virtualenv==20.26.3
20+
# via pre-commit

requirements.in

Whitespace-only changes.

requirements.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)