Skip to content

Commit 306145c

Browse files
authored
Linter: Split ink_linting into two libraries (#2032)
* feat(linter): Split `ink_linting` into two libraries Split `ink_linting` to `ink_linting_mandatory` and `ink_linting`. Mandatory lints will be integrated in the `cargo-build` build process in use-ink/cargo-contract#1412. Extra lints are optional and could be run by the contract developer to highlight possible issues with secure coding style and to check the compliance with best practices. For more information about this design decision, see: use-ink/cargo-contract#1412 (comment). Closes #2006 * chore: Update CHANGELOG * feat: Run linting tests in github-actions * fix(ci): Add caching for `linting` builds * fix(ci): gh-actions syntax * fix(ci) * fix(ci): Remove `--locked` flag for linting This is necessary, because the lockfile needs to be updated since we run build with a different `rust-toolchain.yml`.
1 parent ec9b925 commit 306145c

28 files changed

+224
-92
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ jobs:
228228
for crate in ${ALSO_WASM_CRATES}; do
229229
cargo check --verbose --no-default-features --target wasm32-unknown-unknown \
230230
--manifest-path ./crates/${crate}/Cargo.toml;
231-
done
231+
done
232232
233233
- name: Check RISCV
234234
if: ${{ matrix.type == 'RISCV' }}
@@ -238,7 +238,7 @@ jobs:
238238
for crate in ${ALSO_WASM_CRATES}; do
239239
cargo check --verbose --no-default-features --target $RISCV_TARGET -Zbuild-std="core,alloc" \
240240
--manifest-path ./crates/${crate}/Cargo.toml;
241-
done
241+
done
242242
243243
dylint:
244244
runs-on: ubuntu-latest
@@ -336,7 +336,9 @@ jobs:
336336
- name: Cache
337337
uses: Swatinem/rust-cache@v2
338338
with:
339-
cache-directories: ${{ env.CARGO_TARGET_DIR }}
339+
cache-directories: |
340+
${{ env.CARGO_TARGET_DIR }}
341+
${{ env.CARGO_TARGET_DIR }}/linting
340342
341343
- name: Rust Info
342344
uses: ./.github/rust-info
@@ -353,6 +355,7 @@ jobs:
353355
run: |
354356
cargo test --verbose --all-features --no-fail-fast --workspace --locked
355357
cargo test --verbose --all-features --no-fail-fast --workspace --doc --locked
358+
pushd linting && cargo test --verbose --all-features --no-fail-fast --workspace && popd
356359
357360
docs:
358361
runs-on: ubuntu-latest

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- Support multiple chain extensions - [#1958](https://github.com/paritytech/ink/pull/1958)
2929
- New example of how to use multiple chain extensions in one contract.
3030
- Affects the usage of the `#[ink::chain_extension]` macro and the definition of the chain extension.
31+
- Split up `ink_linting` to mandatory and extra libraries - [#2032](https://github.com/paritytech/ink/pull/2032)
3132

3233

3334
## Version 5.0.0-alpha

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ members = [
1818
]
1919
exclude = [
2020
"integration-tests",
21+
"linting",
2122
]
2223

2324
[workspace.package]

linting/Cargo.toml

Lines changed: 9 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,12 @@
1-
[package]
2-
name = "ink_linting"
3-
version = "5.0.0-rc"
4-
authors = ["Parity Technologies <[email protected]>"]
5-
edition = "2021"
6-
publish = false
7-
8-
license = "Apache-2.0"
9-
readme = "README.md"
10-
repository = "https://github.com/paritytech/ink"
11-
documentation = "https://docs.rs/ink_linting"
12-
homepage = "https://github.com/paritytech/ink"
13-
description = "Linting tool for ink! smart contracts."
14-
keywords = ["parity", "blockchain", "ink", "smart contracts", "substrate"]
15-
include = ["Cargo.toml", "*.rs", "LICENSE"]
16-
17-
[lib]
18-
crate-type = ["cdylib"]
19-
20-
[dependencies]
21-
clippy_utils = { git = "https://github.com/rust-lang/rust-clippy", rev = "1d334696587ac22b3a9e651e7ac684ac9e0697b2" }
22-
dylint_linting = "2.1.12"
23-
if_chain = "1.0.2"
24-
log = "0.4.14"
25-
regex = "1.5.4"
26-
27-
[dev-dependencies]
28-
dylint_testing = "2.1.12"
29-
30-
# The following are ink! dependencies, they are only required for the `ui` tests.
31-
ink_env = { path = "../crates/env", default-features = false }
32-
ink = { path = "../crates/ink", default-features = false, features = ["std"] }
33-
ink_metadata = { path = "../crates/metadata", default-features = false }
34-
ink_primitives = { path = "../crates/primitives", default-features = false }
35-
ink_storage = { path = "../crates/storage", default-features = false }
36-
scale = { package = "parity-scale-codec", version = "3.4", default-features = false, features = ["derive"] }
37-
scale-info = { version = "2.6", default-features = false, features = ["derive"] }
38-
39-
# For the moment we have to include the tests as examples and
40-
# then use `dylint_testing::ui_test_examples`.
41-
#
42-
# The reason is that the `dylint_testing` API currently does not
43-
# provide any other option to run the tests on those files
44-
# *while giving us the option to specify the dependencies*.
45-
#
46-
# Those files require the ink! dependencies though, by having
47-
# them as examples here, they inherit the `dev-dependencies`.
48-
[[example]]
49-
name = "primitive_topic_pass"
50-
path = "ui/pass/primitive_topic.rs"
51-
[[example]]
52-
name = "primitive_topic_fail"
53-
path = "ui/fail/primitive_topic.rs"
54-
[[example]]
55-
name = "storage_never_freed_pass"
56-
path = "ui/pass/storage_never_freed.rs"
57-
[[example]]
58-
name = "storage_never_freed_fail"
59-
path = "ui/fail/storage_never_freed.rs"
60-
[[example]]
61-
name = "strict_balance_equality_pass"
62-
path = "ui/pass/strict_balance_equality.rs"
63-
[[example]]
64-
name = "strict_balance_equality_fail"
65-
path = "ui/fail/strict_balance_equality.rs"
66-
[[example]]
67-
name = "no_main_pass"
68-
path = "ui/pass/no_main.rs"
69-
70-
[package.metadata.rust-analyzer]
71-
rustc_private = true
72-
731
[workspace]
2+
resolver = "2"
3+
members = [
4+
"mandatory",
5+
"extra",
6+
]
747

75-
[features]
76-
default = ["std"]
77-
std = [
78-
"ink_metadata/std",
79-
"ink_env/std",
80-
"ink_storage/std",
81-
"ink_primitives/std",
82-
"scale/std",
83-
"scale-info/std",
8+
[workspace.metadata.dylint]
9+
libraries = [
10+
{ path = "mandatory" },
11+
{ path = "extra" },
8412
]
85-
ink-as-dependency = []

linting/README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
# ink! linting rules
22

33
This crate uses [`dylint`](https://github.com/trailofbits/dylint) to define custom
4-
linting rules for [ink!](https://github.com/paritytech/ink);
4+
linting rules for [ink!](https://github.com/paritytech/ink).
55

66
It is not part of the workspace because it needs a custom linker to be built.
77

88
The lints are written against a fixed toolchain version because they are using unstable
9-
APIs. This is why we have a toolchain file here.
9+
APIs. This is why we have [a toolchain file](./rust-toolchain.toml) here.
1010

11-
You can use it by running `cargo dylint` after adding this to your `Cargo.toml`:
11+
This crate contains two libraries:
12+
* [`mandatory`](./mandatory) lints are integrated into the ink! smart contracts' build process, adding custom compilation errors to `cargo-build`.
13+
* [`extra`](./extra) lints are designed to check for secure coding style in smart contracts and highlight potential issues. These are optional and intended for use by the contract developer to improve the security properties of their project.
14+
15+
You can use them by running `cargo dylint` after adding this to your `Cargo.toml`:
1216

1317
```toml
1418
[workspace.metadata.dylint]
1519
libraries = [
16-
{ git = "https://github.com/paritytech/ink.git", pattern = "linting/" },
20+
{ git = "https://github.com/paritytech/ink.git", pattern = "linting/mandatory" },
21+
{ git = "https://github.com/paritytech/ink.git", pattern = "linting/extra" },
1722
]
1823
```

linting/extra/Cargo.toml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
[package]
2+
name = "ink_linting"
3+
version = "5.0.0-rc"
4+
authors = ["Parity Technologies <[email protected]>"]
5+
edition = "2021"
6+
publish = false
7+
8+
license = "Apache-2.0"
9+
readme = "README.md"
10+
repository = "https://github.com/paritytech/ink"
11+
documentation = "https://docs.rs/ink_linting"
12+
homepage = "https://github.com/paritytech/ink"
13+
description = "Extra linting rules for ink! smart contracts"
14+
keywords = ["parity", "blockchain", "ink", "smart contracts", "substrate"]
15+
include = ["Cargo.toml", "*.rs", "LICENSE"]
16+
17+
[lib]
18+
crate-type = ["cdylib"]
19+
20+
[dependencies]
21+
clippy_utils = { git = "https://github.com/rust-lang/rust-clippy", rev = "1d334696587ac22b3a9e651e7ac684ac9e0697b2" }
22+
dylint_linting = "2.1.12"
23+
if_chain = "1.0.2"
24+
log = "0.4.14"
25+
regex = "1.5.4"
26+
27+
[dev-dependencies]
28+
dylint_testing = "2.1.12"
29+
# The following are ink! dependencies, they are only required for the `ui` tests.
30+
ink_env = { path = "../../crates/env", default-features = false }
31+
ink = { path = "../../crates/ink", default-features = false, features = ["std"] }
32+
ink_metadata = { path = "../../crates/metadata", default-features = false }
33+
ink_primitives = { path = "../../crates/primitives", default-features = false }
34+
ink_storage = { path = "../../crates/storage", default-features = false }
35+
scale = { package = "parity-scale-codec", version = "3.4", default-features = false, features = ["derive"] }
36+
scale-info = { version = "2.6", default-features = false, features = ["derive"] }
37+
38+
# For the moment we have to include the tests as examples and
39+
# then use `dylint_testing::ui_test_examples`.
40+
#
41+
# The reason is that the `dylint_testing` API currently does not
42+
# provide any other option to run the tests on those files
43+
# *while giving us the option to specify the dependencies*.
44+
#
45+
# Those files require the ink! dependencies though, by having
46+
# them as examples here, they inherit the `dev-dependencies`.
47+
[[example]]
48+
name = "primitive_topic_pass"
49+
path = "ui/pass/primitive_topic.rs"
50+
[[example]]
51+
name = "primitive_topic_fail"
52+
path = "ui/fail/primitive_topic.rs"
53+
[[example]]
54+
name = "storage_never_freed_pass"
55+
path = "ui/pass/storage_never_freed.rs"
56+
[[example]]
57+
name = "storage_never_freed_fail"
58+
path = "ui/fail/storage_never_freed.rs"
59+
[[example]]
60+
name = "strict_balance_equality_pass"
61+
path = "ui/pass/strict_balance_equality.rs"
62+
[[example]]
63+
name = "strict_balance_equality_fail"
64+
path = "ui/fail/strict_balance_equality.rs"
65+
66+
[package.metadata.rust-analyzer]
67+
rustc_private = true
68+
69+
[features]
70+
default = ["std"]
71+
std = [
72+
"ink_metadata/std",
73+
"ink_env/std",
74+
"ink_storage/std",
75+
"ink_primitives/std",
76+
"scale/std",
77+
"scale-info/std",
78+
]
79+
ink-as-dependency = []

linting/extra/LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../LICENSE

linting/extra/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Extra ink! linting rules
2+
These lints are designed to check for secure coding style in smart contracts and highlight potential issues. These are optional and intended for use by the contract developer to improve the security properties of their project.
File renamed without changes.

linting/src/lib.rs renamed to linting/extra/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ extern crate rustc_session;
3232
extern crate rustc_span;
3333

3434
mod ink_utils;
35-
mod no_main;
3635
mod primitive_topic;
3736
mod storage_never_freed;
3837
mod strict_balance_equality;
@@ -47,13 +46,11 @@ pub fn register_lints(
4746
primitive_topic::PRIMITIVE_TOPIC,
4847
storage_never_freed::STORAGE_NEVER_FREED,
4948
strict_balance_equality::STRICT_BALANCE_EQUALITY,
50-
no_main::NO_MAIN,
5149
]);
5250
lint_store.register_late_pass(|_| Box::new(primitive_topic::PrimitiveTopic));
5351
lint_store.register_late_pass(|_| Box::new(storage_never_freed::StorageNeverFreed));
5452
lint_store
5553
.register_late_pass(|_| Box::new(strict_balance_equality::StrictBalanceEquality));
56-
lint_store.register_early_pass(|| Box::new(no_main::NoMain));
5754
}
5855

5956
#[test]

0 commit comments

Comments
 (0)