Skip to content

Commit 2fc8b33

Browse files
Merge pull request #687 from protofire/develop
MERGE: develop into master v5.2.0
2 parents 233e423 + 4f7dc7f commit 2fc8b33

File tree

66 files changed

+2256
-255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2256
-255
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## [5.2.0] - 2025-06-27
2+
### Fixed
3+
- `imports-order` interference with `no-unused-imports` [#684](https://github.com/protofire/solhint/pull/684)
4+
5+
### Added
6+
- Added `cache` flag allowing to skip already evaluated files if no error was thrown and file did not change - [#685](https://github.com/protofire/solhint/pull/685)
7+
- Added multi-directory config support by hierarchy - [#678](https://github.com/protofire/solhint/pull/678)
8+
- Added better error handling on invalid configs - [#683](https://github.com/protofire/solhint/pull/683)
9+
10+
11+
Thanks to [@smol-ninja](https://github.com/smol-ninja) - [@PaulRBerg](https://github.com/PaulRBerg) [@lechpzn](https://github.com/lechpzn), [@otc-png](https://github.com/otc-png), [@MamunC0der](https://github.com/MamunC0der), [@kks-code](https://github.com/kks-code), [@RidaMichofi](https://github.com/RidaMichofi)
12+
13+
For making the time of proposing rules, pointing out typos, broken links, unused code, copyright, small reviews, etc. We really appreciate your contributions!
14+
15+
<br><br>
16+
117
## [5.1.0] - 2025-05-05
218
### Added
319
- Argument to avoid discord poster - [#646](https://github.com/protofire/solhint/pull/646)

README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,17 @@ Options:
6262
-V, --version output the version number
6363
-f, --formatter [name] report formatter name (stylish, table, tap, unix, json, compact, sarif)
6464
-w, --max-warnings [maxWarningsNumber] number of allowed warnings, works in quiet mode as well
65-
-c, --config [file_name] file to use as your .solhint.json
65+
-c, --config [file_name] file to use as your rules configuration file (not compatible with multiple configs)
6666
-q, --quiet report errors only - default: false
6767
--ignore-path [file_name] file to use as your .solhintignore
6868
--fix automatically fix problems and show report
69+
--cache only lint files that changed since last run
70+
--cache-location path to the cache file
6971
--noPrompt do not suggest to backup files when any `fix` option is selected
7072
--init create configuration file for solhint
7173
--disc do not check for solhint updates
7274
--save save report to file on current folder
75+
--noPoster remove discord poster
7376
-h, --help output usage information
7477
7578
Commands:
@@ -98,7 +101,7 @@ This option currently works on:
98101

99102
You can use a `.solhint.json` file to configure Solhint for the whole project.
100103

101-
To generate a new sample `.solhint.json` file in current folder you can do:
104+
To generate a new sample `.solhint.json` file in current folder you can do:
102105

103106
```sh
104107
solhint --init
@@ -111,9 +114,37 @@ This file has the following format:
111114
"extends": "solhint:recommended"
112115
}
113116
```
114-
### Note
117+
### Note 1
115118
The `solhint:default` configuration contains only two rules: max-line-length & no-console
116119
It is now deprecated since version 5.1.0
120+
<br>
121+
122+
### Note 2
123+
Multiple configs files can be used at once. All config files should be named `.solhint.json`.
124+
If not done like this, multiple hierarchy configuration will not work.
125+
Solhint will go though all config files automatically.
126+
127+
Given this structure:
128+
```
129+
Project ROOT =>
130+
/contracts
131+
---> RootAndContractRules.sol
132+
---> .solhint.json
133+
134+
/src
135+
--->RootRules.sol
136+
--->interfaces/
137+
------->InterfaceRules.sol
138+
------->solhint.json
139+
140+
.solhint.json
141+
```
142+
- Solhint config located on `root` will be the main one.
143+
- When analyzing `RootRules.sol`, `root` file config will be used that file.
144+
- `InterfaceRules.sol` will be using the one inside its own folder taking precedence over the `root` folder one.
145+
- Rules not present in `interfaces/` folder and present in `root` will be active.
146+
- Rules not present in `root` folder and present in `interfaces/` folder will be active.
147+
- If rule is present in both files, the closest to the analyzed file will take precedence. Meaning when analyzing `InterfaceRules.sol` the config file located in `Interfaces/` will be used with the remaining rules of the `root` one.
117148
<br><br>
118149

119150

@@ -138,6 +169,25 @@ node_modules/
138169
additional-tests.sol
139170
```
140171

172+
### Cache
173+
Solhint supports a caching mechanism using the `--cache` flag to avoid re-linting files that haven't changed.
174+
When enabled, Solhint stores a hash of each file's content and effective configuration, skipping analysis if neither has changed.
175+
By default, the cache is saved in `.solhintcache.json` in the current working directory.
176+
You can customize this location using the `--cache-location option`. If no location is specified, the file will be stored in:
177+
`node_modules/.cache/solhint/.solhint-cache.json`
178+
179+
Warning:
180+
When using `cache` flag. If a file was analyzed with not error for a certain config, the hash will be stored. If the file is not changed but the config file (`.solhint.json`) has some new rules, the file will not be analyzed.
181+
To analyze it again, remove `cache` option.
182+
183+
Example:
184+
```
185+
solhint contracts/**/*.sol --cache
186+
solhint Foo.sol --cache --cache-location tmp/my-cache.json
187+
```
188+
189+
190+
141191
### Extendable rulesets
142192

143193
The rulesets provided by solhint are the following:

conf/rulesets/solhint-all.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ module.exports = Object.freeze({
6161
},
6262
],
6363
'use-forbidden-name': 'warn',
64-
'var-name-mixedcase': 'warn',
64+
'var-name-mixedcase': [
65+
'warn',
66+
{
67+
prefixForImmutables: 'IMM_',
68+
},
69+
],
6570
'imports-on-top': 'warn',
6671
'imports-order': 'warn',
6772
ordering: 'warn',

conf/rulesets/solhint-recommended.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ module.exports = Object.freeze({
3434
},
3535
],
3636
'use-forbidden-name': 'warn',
37-
'var-name-mixedcase': 'warn',
37+
'var-name-mixedcase': [
38+
'warn',
39+
{
40+
prefixForImmutables: 'IMM_',
41+
},
42+
],
3843
'imports-on-top': 'warn',
3944
'visibility-modifier-order': 'warn',
4045
'avoid-call-value': 'warn',

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM node:20-alpine
22
LABEL maintainer="diego.bale@protofire.io"
3-
ENV VERSION=5.1.0
3+
ENV VERSION=5.2.0
44

55
RUN npm install -g solhint@"$VERSION"

docs/rules.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ title: "Rule Index of Solhint"
88

99
| Rule Id | Error | Recommended | Deprecated |
1010
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | ---------- |
11-
| [code-complexity](./rules/best-practices/code-complexity.md) | Function has cyclomatic complexity "current" but allowed no more than maxcompl. | | |
11+
| [code-complexity](./rules/best-practices/code-complexity.md) | Function has cyclomatic complexity "current" but allowed no more than configured max complexity. | | |
1212
| [explicit-types](./rules/best-practices/explicit-types.md) | Forbid or enforce explicit types (like uint256) that have an alias (like uint). | $~~~~~~~~$✔️ | |
1313
| [function-max-lines](./rules/best-practices/function-max-lines.md) | Function body contains "count" lines but allowed no more than maxlines. | | |
14-
| [max-line-length](./rules/best-practices/max-line-length.md) | Line length must be no more than maxlen. | | |
15-
| [max-states-count](./rules/best-practices/max-states-count.md) | Contract has "some count" states declarations but allowed no more than maxstates. | $~~~~~~~~$✔️ | |
14+
| [max-line-length](./rules/best-practices/max-line-length.md) | Line length should not exceed configured number of characters. | | |
15+
| [max-states-count](./rules/best-practices/max-states-count.md) | Contract has "some count" states declarations but allowed no more than defined max states. | $~~~~~~~~$✔️ | |
1616
| [no-console](./rules/best-practices/no-console.md) | No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements. | $~~~~~~~~$✔️ | |
1717
| [no-empty-blocks](./rules/best-practices/no-empty-blocks.md) | Code block has zero statements inside. Exceptions apply. | $~~~~~~~~$✔️ | |
1818
| [no-global-import](./rules/best-practices/no-global-import.md) | Import statement includes an entire file instead of selected symbols. | $~~~~~~~~$✔️ | |
@@ -42,7 +42,7 @@ title: "Rule Index of Solhint"
4242
| [named-parameters-mapping](./rules/naming/named-parameters-mapping.md) | Solidity v0.8.18 introduced named parameters on the mappings definition. | | |
4343
| [private-vars-leading-underscore](./rules/naming/private-vars-leading-underscore.md) | Non-external functions and state variables should start with a single underscore. Others, shouldn't | | |
4444
| [use-forbidden-name](./rules/naming/use-forbidden-name.md) | Avoid to use letters 'I', 'l', 'O' as identifiers. | $~~~~~~~~$✔️ | |
45-
| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable names must be in mixedCase. (Does not check IMMUTABLES, use immutable-vars-naming) | $~~~~~~~~$✔️ | |
45+
| [var-name-mixedcase](./rules/naming/var-name-mixedcase.md) | Variable names must be in mixedCase. (Does not check IMMUTABLES nor CONSTANTS (use inherent rules for that) | $~~~~~~~~$✔️ | |
4646
| [imports-on-top](./rules/order/imports-on-top.md) | Import statements must be on top. | $~~~~~~~~$✔️ | |
4747
| [imports-order](./rules/naming/imports-order.md) | Order the imports of the contract to follow a certain hierarchy (read "Notes section") | | |
4848
| [ordering](./rules/order/ordering.md) | Check order of elements in file and inside each contract, according to the style guide | | |
@@ -85,7 +85,7 @@ title: "Rule Index of Solhint"
8585
| [avoid-throw](./rules/security/avoid-throw.md) | "throw" is deprecated, avoid to use it. | $~~~~~~~~$✔️ | |
8686
| [avoid-tx-origin](./rules/security/avoid-tx-origin.md) | Avoid to use tx.origin. | $~~~~~~~~$✔️ | |
8787
| [check-send-result](./rules/security/check-send-result.md) | Check result of "send" call. | $~~~~~~~~$✔️ | |
88-
| [compiler-version](./rules/security/compiler-version.md) | Compiler version must satisfy a semver requirement. | $~~~~~~~~$✔️ | |
88+
| [compiler-version](./rules/security/compiler-version.md) | Compiler version must satisfy a semver requirement at least ^0.8.24. | $~~~~~~~~$✔️ | |
8989
| [func-visibility](./rules/security/func-visibility.md) | Explicitly mark visibility in function. | $~~~~~~~~$✔️ | |
9090
| [multiple-sends](./rules/security/multiple-sends.md) | Avoid multiple calls of "send" method in single transaction. | $~~~~~~~~$✔️ | |
9191
| [no-complex-fallback](./rules/security/no-complex-fallback.md) | Fallback function must be simple. | $~~~~~~~~$✔️ | |

docs/rules/best-practices/code-complexity.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ title: "code-complexity | Solhint"
99
![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow)
1010

1111
## Description
12-
Function has cyclomatic complexity "current" but allowed no more than maxcompl.
12+
Function has cyclomatic complexity "current" but allowed no more than configured max complexity.
1313

1414
## Options
1515
This rule accepts an array of options:
1616

1717
| Index | Description | Default Value |
1818
| ----- | ----------------------------------------------------- | ------------- |
1919
| 0 | Rule severity. Must be one of "error", "warn", "off". | warn |
20-
| 1 | Maximum allowed cyclomatic complexity | 7 |
20+
| 1 | Function cyclomatic complexity reached. | 7 |
2121

2222

2323
### Example Config

docs/rules/best-practices/max-line-length.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ title: "max-line-length | Solhint"
1111
1212

1313
## Description
14-
Line length must be no more than maxlen.
14+
Line length should not exceed configured number of characters.
1515

1616
## Options
1717
This rule accepts an array of options:
1818

19-
| Index | Description | Default Value |
20-
| ----- | ----------------------------------------------------- | ------------- |
21-
| 0 | Rule severity. Must be one of "error", "warn", "off". | error |
22-
| 1 | Maximum allowed number of characters per line | 120 |
19+
| Index | Description | Default Value |
20+
| ----- | -------------------------------------------------------------- | ------------- |
21+
| 0 | Rule severity. Must be one of "error", "warn", "off". | error |
22+
| 1 | Line length should not exceed configured number of characters. | 120 |
2323

2424

2525
### Example Config

docs/rules/best-practices/max-states-count.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ title: "max-states-count | Solhint"
1212
1313

1414
## Description
15-
Contract has "some count" states declarations but allowed no more than maxstates.
15+
Contract has "some count" states declarations but allowed no more than defined max states.
1616

1717
## Options
1818
This rule accepts an array of options:

docs/rules/gas-consumption/gas-custom-errors.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,19 @@ revert CustomErrorFunction({ msg: "Insufficient Balance" });
4747
#### Use of Require with Custom Error with arguments
4848

4949
```solidity
50-
require(success, CustomErrorFunction({ msg: "Insufficient Balance" });
50+
require(success, CustomErrorFunction({ msg: "Insufficient Balance" }));
5151
```
5252

5353
#### Use of Require with function call and Custom Error
5454

5555
```solidity
56-
require(isAuthorized(account), CustomErrorFunction();
56+
require(isAuthorized(account), CustomErrorFunction());
5757
```
5858

5959
#### Use of Require with binary comparison and Custom Error
6060

6161
```solidity
62-
require(a > b, CustomErrorFunction();
62+
require(a > b, CustomErrorFunction());
6363
```
6464

6565
### 👎 Examples of **incorrect** code for this rule

0 commit comments

Comments
 (0)