Skip to content

Commit 5785a58

Browse files
Merge pull request #741 from protofire/fix-allow-scoped-packages
fix: scoped packs for shareable configs
2 parents f16f7b4 + 6962269 commit 5785a58

File tree

33 files changed

+454
-21
lines changed

33 files changed

+454
-21
lines changed

.github/workflows/E2E.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ jobs:
4040

4141
- name: Check solhint version
4242
run: solhint --version
43+
44+
- name: Debug fixtures presence
45+
run: |
46+
ls -R e2e/14-shareable-config/filesystem01/project || true
47+
ls -R e2e/14-shareable-config/filesystem04/project || true
4348
4449
- name: Run E2E Tests
4550
run: npm run ci:e2e

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
# ignore all node_modules by default
12
node_modules/
3+
24
/.idea/
35
test2.sol
46
convertLib.sol
@@ -12,3 +14,9 @@ _temp/
1214
.env
1315
**/.DS_Store
1416
solhint*.tgz
17+
18+
# Exception on E2E fixtures' node_modules (they are part of the test data)
19+
# only allow .js and .json files in those node_modules
20+
!e2e/**/node_modules/**/*.js
21+
!e2e/**/node_modules/**/*.json
22+

docs/shareable-configs.md

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,122 @@ Shareable configs are configurations that you can use and extend from. They can
44

55
To use a shareable config, you have to add it to your Solhint configuration:
66

7-
```
7+
```json
8+
{
89
"extends": ["solhint:recommended", "protofire"]
10+
}
11+
```
12+
13+
This example shows the two types of shareable configs that you can use:
14+
15+
- **Built-in Solhint configs**, which start with `solhint:` (e.g. `solhint:recommended`, `solhint:all`)
16+
- **Shareable configs installed from npm**
17+
18+
19+
## Using npm shareable configs
20+
21+
Unscoped shareable configs are npm packages prefixed with `solhint-config-`.
22+
23+
For example, this configuration:
24+
25+
```json
26+
{
27+
"extends": ["protofire"]
28+
}
29+
```
30+
31+
Will load the package:
32+
33+
```
34+
solhint-config-protofire
35+
```
36+
37+
which must be installed beforehand:
38+
39+
```
40+
npm install solhint-config-protofire
41+
```
42+
43+
You can also reference the full package name explicitly:
44+
45+
```json
46+
{
47+
"extends": ["solhint-config-protofire"]
48+
}
49+
```
50+
51+
Shareable configs are resolved from the project's `node_modules` directory (the current working directory), even when Solhint is installed globally.
52+
53+
54+
## Scoped shareable configs
55+
56+
Solhint also supports **scoped** shareable configs.
57+
58+
Given the npm package:
59+
60+
```
61+
@scope/solhint-config-myconfig
62+
```
63+
64+
You can use it in your configuration as:
65+
66+
```json
67+
{
68+
"extends": ["@scope/solhint-config-myconfig"]
69+
}
70+
```
71+
72+
For convenience, Solhint also supports the ESLint-style shorthand:
73+
74+
```json
75+
{
76+
"extends": ["@scope/myconfig"]
77+
}
978
```
1079

11-
This example shows the two types of shareable configs that you can use: the ones included with Solhint, that start with `solhint:`, and the ones that you can install from npm. The latter are packages that are prefixed with `solhint-config-`, so in this case the package would be installed doing `npm install solhint-config-protofire` but used as just `protofire` when adding it.
80+
Which resolves to:
81+
82+
```
83+
@scope/solhint-config-myconfig
84+
```
85+
86+
Note: Only package-level scoped configs are supported (`@scope/name`). Deep paths such as `@scope/name/extra` are not supported.
87+
1288

1389
## Creating your own shareable config
1490

1591
Shareable configs are regular npm packages. There are only two conditions:
1692

17-
- The name of the package must start with `solhint-config-`
18-
- The package must export a regular object with the same structure as a regular configuration object (i.e. the one in your `.solhint.json`).
93+
- The package name must start with `solhint-config-`
94+
(for scoped packages: `@scope/solhint-config-*`)
95+
- The package must export a regular object with the same structure as a standard Solhint configuration (i.e. the one in your `.solhint.json`)
1996

2097
For example, a very minimal `index.js` in this package could be:
2198

22-
```javascript
99+
```js
23100
module.exports = {
24101
rules: {
25102
'max-line-length': 80
26103
}
27104
}
28105
```
29106

30-
After creating this package you can publish it to npm to make it available for everyone.
107+
After creating this package, you can publish it to npm to make it available for everyone.
108+
109+
110+
## Configuration inheritance
111+
112+
Solhint supports **hierarchical configuration**.
113+
114+
When linting a file, configurations are merged in the following order:
115+
116+
1. The project root configuration
117+
2. Each parent directory configuration
118+
3. The directory containing the file (**highest precedence**)
119+
120+
For each configuration file, any `extends` entries are resolved first, and then all configurations are merged according to directory hierarchy.
121+
122+
Rules and settings defined in deeper directories **override** those from higher-level directories and from extended configs.
123+
124+
In short:
125+
**`extends` are resolved first, directory hierarchy is applied after, and the closest config always wins.**
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["@test/demo"]
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
contract A {
5+
function f() public {}
6+
}

e2e/14-shareable-config/filesystem01/project/node_modules/@test/solhint-config-demo/index.js

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["@test/base"]
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"rules": {
3+
"max-line-length": ["error", 80]
4+
}
5+
}
6+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
contract A { function f() public { uint x = 1; uint y = 2; uint z = 3; uint w = 4; } function g() public { } }

e2e/14-shareable-config/filesystem02/project/node_modules/@test/solhint-config-base/index.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)