Skip to content
This repository has been archived by the owner on Jul 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #204 from astrodevs-labs/feature/180-auto-generate…
Browse files Browse the repository at this point in the history
…d-user-docs/190-expose-rules-doc-with-argument-staging

190 - Expose rules doc with argument
  • Loading branch information
ByFishh authored Nov 19, 2023
2 parents 7d9d61e + 10dbf42 commit 1b3c0c3
Show file tree
Hide file tree
Showing 34 changed files with 830 additions and 5 deletions.
1 change: 1 addition & 0 deletions toolchains/solidity/core/crates/linter-cli/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Options:
-i, --init Initialize rules file
-h, --help Print help information
-V, --version Print version information
-d, --documentation Exposes rules documentation
```

## Configuration
Expand Down
25 changes: 25 additions & 0 deletions toolchains/solidity/core/crates/linter-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ struct Args {
help = "Initialize rules file"
)]
init: bool,

#[arg(
short = 'd',
long = "documentation",
default_value = "false",
help = "exposes rules documentation"
)]
documentation: bool,
}

fn print_result(results: Vec<LintResult>) {
Expand Down Expand Up @@ -80,12 +88,29 @@ fn main() -> Result<(), SolidHunterError> {
println!();
}

if args.documentation {
println!("These are all rules documentations");
let linter: SolidLinter = SolidLinter::new_fileless();

let json = serde_json::to_string_pretty(&linter.get_documentation());
match json {
Ok(j) => {
println!("{}", j);
}
Err(e) => {
println!("{}", e);
}
}
return Ok(());
}

if args.verbose {
println!("Verbose output enabled");
println!("Project path: {:?}", args.path);
println!("Exclude path: {:?}", args.ignore_path);
println!("Using rules file: {}", args.rules_file);
println!("Verbose output: {}", args.verbose);
println!("Documentation output: {}", args.documentation);
}

if args.init {
Expand Down
8 changes: 8 additions & 0 deletions toolchains/solidity/core/crates/linter-lib/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ impl SolidLinter {
Ok(())
}

pub fn get_documentation(&self) -> Vec<RuleDocumentation> {
let mut res = Vec::new();
for rule in &self.rules {
res.push(rule.get_documentation())
}
res
}

fn _file_exists(&self, path: &str) -> bool {
for file in &self.files {
if file.path == path {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,48 @@ impl RuleType for CustomErrors {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "Enforces the use of Custom Errors over Require and Revert statements"
.to_string(),
category: "best-practises".to_string(),
example_config: "{\"id\": \"custom-errors\", \"severity\": \"WARNING\"}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/custom_errors.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/CustomErrors".to_string(),
options: vec![],
examples: Examples {
good: vec![
Example {
description: "Use Custom Errors".to_string(),
code: "revert CustomErrorFunction();".to_string(),
},
Example {
description: "Use of Custom Errors with arguments".to_string(),
code: "revert CustomErrorFunction({ msg: \"Insufficient Balance\" });"
.to_string(),
},
],
bad: vec![
Example {
description: "Use of require statement".to_string(),
code: "require(userBalance >= availableAmount, \"Insufficient Balance\");"
.to_string(),
},
Example {
description: "Use of plain revert statement".to_string(),
code: "revert();".to_string(),
},
Example {
description: "Use of revert statement with message".to_string(),
code: "revert(\"Insufficient Balance\");".to_string(),
},
],
},
}
}
}

impl CustomErrors {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,54 @@ impl RuleType for ExplicitTypes {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description:
"Forbid or enforce explicit types (like uint256) that have an alias (like uint)."
.to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"explicit-types\", \"severity\": \"WARNING\", \"data\": \"explicit\"}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/explicit_types.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/ExplicitTypes".to_string(),
options: vec![Options {
description: "Options need to be one of \"explicit\", \"implicit\"".to_string(),
default: "explicit".to_string(),
}],
examples: Examples {
good: vec![
Example {
description: "If explicit is selected".to_string(),
code: "uint256 public variableName".to_string(),
},
Example {
description: "If implicit is selected".to_string(),
code: "uint public variableName".to_string(),
},
Example {
description: "If explicit is selected".to_string(),
code: "uint256 public variableName = uint256(5)".to_string(),
},
],
bad: vec![
Example {
description: "If explicit is selected".to_string(),
code: "uint public variableName".to_string(),
},
Example {
description: "If implicit is selected".to_string(),
code: "uint256 public variableName".to_string(),
},
Example {
description: "At any setting".to_string(),
code: "uint public variableName = uint256(5)".to_string(),
},
],
},
}
}
}

impl ExplicitTypes {
Expand All @@ -134,7 +182,6 @@ impl ExplicitTypes {
let rule = ExplicitTypes { rule: value, data };
Box::new(rule)
}

pub(crate) fn create_default() -> RuleEntry {
RuleEntry {
id: RULE_ID.to_string(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ impl RuleType for FunctionMaxLines {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description:
"Function body contains \"count\" lines but allowed no more than maxlines."
.to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"function-max-lines\", \"severity\": \"WARNING\", \"data\": 20}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/function_max_lines.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/FunctionMaxLines".to_string(),
options: vec![Options {
description: "Maximum allowed lines count per function ".to_string(),
default: "50".to_string(),
}],
examples: Examples {
good: vec![],
bad: vec![],
},
}
}
}

// returns a struct containing the line number of the start and end of the function if it is too long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ impl RuleType for MaxLineLength {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "Line length must be no more than maxlen.".to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"max-line-length\", \"severity\": \"WARNING\", \"data\": 80}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/max_line_length.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/MaxLineLength".to_string(),
options: vec![Options {
description: "Maximum allowed number of characters per line".to_string(),
default: "120".to_string(),
}],
examples: Examples {
good: vec![],
bad: vec![],
},
}
}
}

impl MaxLineLength {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ impl RuleType for MaxStatesCount {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "Contract has \"some count\" states declarations but allowed no more than maxstates.".to_string(),
category: "best-practices".to_string(),
example_config: " {\"id\": \"max-states-count\", \"severity\": \"WARNING\", \"data\": [15]}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/max_states_count.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/MaxStatesCount".to_string(),
options: vec![Options{description: "Maximum allowed states declarations".to_string(),
default: "15".to_string(),}],
examples: Examples {
good: vec![],
bad: vec![],
},
}
}
}

impl MaxStatesCount {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use osmium_libs_solidity_ast_extractor::*;

use crate::linter::SolidFile;
use crate::rules::types::{RuleEntry, RuleType};
use crate::rules::types::{Example, Examples, RuleDocumentation, RuleEntry, RuleType};
use crate::types::{LintDiag, Position, Range, Severity};

// global
Expand Down Expand Up @@ -91,6 +91,29 @@ impl RuleType for NoConsole {

res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements.".to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"no-console\", \"severity\": \"WARNING\"}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/no_console.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/NoConsole".to_string(),
options: vec![],
examples: Examples {
good: vec![],
bad: vec![Example{description: "No console.logX statements".to_string(),
code: "console.log('test').".to_string()},
Example{description: "No hardhat/console.sol import statements".to_string(),
code: "import 'hardhat/console.sol';".to_string()},
Example{description: "No forge-std console.sol & console2.sol import statements".to_string(),
code: "import 'forge-std/consoleN.sol';".to_string()},
],
},
}
}
}

impl NoConsole {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,47 @@ impl RuleType for NoEmptyBlock {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "Code block has zero statements inside. Exceptions apply.".to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"no-empty-block\", \"severity\": \"WARNING\"}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/no_empty_block.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/NoEmptyBlock".to_string(),
options: vec![],
examples: Examples {
good: vec![
Example {
description: "Empty fallback function".to_string(),
code: "fallback() external {}".to_string(),
},
Example {
description: "Empty constructor with member initialization list"
.to_string(),
code: "constructor(uint param) Foo(param) Bar(param*2) { }".to_string(),
},
],
bad: vec![
Example {
description: "Empty block on if statement".to_string(),
code: "if (condition) { }".to_string(),
},
Example {
description: "Empty contract".to_string(),
code: "contract Foo { }".to_string(),
},
Example {
description: "Empty block in constructor without parent initialization"
.to_string(),
code: "constructor() { }".to_string(),
},
],
},
}
}
}

fn check_empty_block(file: &SolidFile) -> Vec<Option<Range>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,46 @@ impl RuleType for NoGlobalImport {
}
res
}

fn get_documentation(&self) -> RuleDocumentation {
RuleDocumentation {
id: RULE_ID.to_string(),
severity: DEFAULT_SEVERITY,
description: "Import statement includes an entire file instead of selected symbols."
.to_string(),
category: "best-practices".to_string(),
example_config: "{\"id\": \"no-global-import\", \"severity\": \"WARNING\"}".to_string(),
source_link: "https://github.com/astrodevs-labs/osmium/blob/dev/toolchains/solidity/core/crates/linter-lib/src/rules/best_practices/no_global_import.rs".to_string(),
test_link: "https://github.com/astrodevs-labs/osmium/tree/dev/toolchains/solidity/core/crates/linter-lib/testdata/NoGlobalImport".to_string(),
options: vec![],
examples: Examples {
good: vec![
Example {
description: "import names explicitly".to_string(),
code: "import {A} from \"./A.sol\"".to_string(),
},
Example {
description: "import entire file into a name".to_string(),
code: "import \"./A.sol\" as A".to_string(),
},
Example {
description: "import entire file into a name".to_string(),
code: "import * as A from \"./A.sol\"".to_string(),
},
],
bad: vec![
Example {
description: "import all members from a file".to_string(),
code: "import * from \"foo.sol\";".to_string(),
},
Example {
description: "import an entire file".to_string(),
code: "import \"foo.sol\"".to_string(),
},
],
},
}
}
}

fn check_global_import(file: &SolidFile) -> Vec<Option<Range>> {
Expand Down
Loading

0 comments on commit 1b3c0c3

Please sign in to comment.