Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/Cargo.lock
|
||||||
170
Cargo.toml
Normal file
170
Cargo.toml
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
[package]
|
||||||
|
name = "clippy-lints"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = { version = "1.*", default-features = false }
|
||||||
|
clap = { version = "4.*", default-features = false, features = [
|
||||||
|
"derive",
|
||||||
|
"help",
|
||||||
|
"std",
|
||||||
|
"suggestions",
|
||||||
|
"usage",
|
||||||
|
] }
|
||||||
|
serde = { version = "1.*", default-features = false, features = ["derive"] }
|
||||||
|
ureq = { version = "2.*", default-features = false, features = ["json", "tls"] }
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
# enabled groups
|
||||||
|
correctness = { level = "deny", priority = -1 }
|
||||||
|
suspicious = { level = "warn", priority = -1 }
|
||||||
|
style = { level = "warn", priority = -1 }
|
||||||
|
complexity = { level = "warn", priority = -1 }
|
||||||
|
perf = { level = "warn", priority = -1 }
|
||||||
|
cargo = { level = "warn", priority = -1 }
|
||||||
|
pedantic = { level = "warn", priority = -1 }
|
||||||
|
nursery = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
|
# pedantic overrides
|
||||||
|
too_many_lines = "allow"
|
||||||
|
must_use_candidate = "allow"
|
||||||
|
map_unwrap_or = "allow"
|
||||||
|
missing_errors_doc = "allow"
|
||||||
|
if_not_else = "allow"
|
||||||
|
|
||||||
|
# nursery overrides
|
||||||
|
missing_const_for_fn = "allow"
|
||||||
|
option_if_let_else = "allow"
|
||||||
|
|
||||||
|
# complexity overrides
|
||||||
|
too_many_arguments = "allow"
|
||||||
|
|
||||||
|
# style overrides
|
||||||
|
new_without_default = "allow"
|
||||||
|
|
||||||
|
# cargo overrides
|
||||||
|
multiple_crate_versions = "allow"
|
||||||
|
cargo_common_metadata = "allow"
|
||||||
|
|
||||||
|
# selected restrictions
|
||||||
|
allow_attributes = "warn"
|
||||||
|
allow_attributes_without_reason = "warn"
|
||||||
|
arithmetic_side_effects = "warn"
|
||||||
|
as_conversions = "warn"
|
||||||
|
assertions_on_result_states = "warn"
|
||||||
|
cfg_not_test = "warn"
|
||||||
|
clone_on_ref_ptr = "warn"
|
||||||
|
create_dir = "warn"
|
||||||
|
dbg_macro = "warn"
|
||||||
|
decimal_literal_representation = "warn"
|
||||||
|
default_numeric_fallback = "warn"
|
||||||
|
deref_by_slicing = "warn"
|
||||||
|
disallowed_script_idents = "warn"
|
||||||
|
else_if_without_else = "warn"
|
||||||
|
empty_drop = "warn"
|
||||||
|
empty_enum_variants_with_brackets = "warn"
|
||||||
|
empty_structs_with_brackets = "warn"
|
||||||
|
exit = "warn"
|
||||||
|
filetype_is_file = "warn"
|
||||||
|
float_arithmetic = "warn"
|
||||||
|
float_cmp_const = "warn"
|
||||||
|
fn_to_numeric_cast_any = "warn"
|
||||||
|
format_push_string = "warn"
|
||||||
|
get_unwrap = "warn"
|
||||||
|
indexing_slicing = "warn"
|
||||||
|
infinite_loop = "warn"
|
||||||
|
inline_asm_x86_att_syntax = "warn"
|
||||||
|
inline_asm_x86_intel_syntax = "warn"
|
||||||
|
integer_division = "warn"
|
||||||
|
iter_over_hash_type = "warn"
|
||||||
|
large_include_file = "warn"
|
||||||
|
let_underscore_must_use = "warn"
|
||||||
|
let_underscore_untyped = "warn"
|
||||||
|
little_endian_bytes = "warn"
|
||||||
|
lossy_float_literal = "warn"
|
||||||
|
map_err_ignore = "warn"
|
||||||
|
mem_forget = "warn"
|
||||||
|
missing_assert_message = "warn"
|
||||||
|
missing_asserts_for_indexing = "warn"
|
||||||
|
mixed_read_write_in_expression = "warn"
|
||||||
|
modulo_arithmetic = "warn"
|
||||||
|
multiple_inherent_impl = "warn"
|
||||||
|
multiple_unsafe_ops_per_block = "warn"
|
||||||
|
mutex_atomic = "warn"
|
||||||
|
panic = "warn"
|
||||||
|
partial_pub_fields = "warn"
|
||||||
|
pattern_type_mismatch = "warn"
|
||||||
|
print_stderr = "warn"
|
||||||
|
print_stdout = "warn"
|
||||||
|
pub_without_shorthand = "warn"
|
||||||
|
rc_buffer = "warn"
|
||||||
|
rc_mutex = "warn"
|
||||||
|
redundant_type_annotations = "warn"
|
||||||
|
renamed_function_params = "warn"
|
||||||
|
rest_pat_in_fully_bound_structs = "warn"
|
||||||
|
same_name_method = "warn"
|
||||||
|
self_named_module_files = "warn"
|
||||||
|
semicolon_inside_block = "warn"
|
||||||
|
str_to_string = "warn"
|
||||||
|
string_add = "warn"
|
||||||
|
string_lit_chars_any = "warn"
|
||||||
|
string_slice = "warn"
|
||||||
|
string_to_string = "warn"
|
||||||
|
suspicious_xor_used_as_pow = "warn"
|
||||||
|
tests_outside_test_module = "warn"
|
||||||
|
todo = "warn"
|
||||||
|
try_err = "warn"
|
||||||
|
undocumented_unsafe_blocks = "warn"
|
||||||
|
unimplemented = "warn"
|
||||||
|
unnecessary_safety_comment = "warn"
|
||||||
|
unnecessary_safety_doc = "warn"
|
||||||
|
unnecessary_self_imports = "warn"
|
||||||
|
unneeded_field_pattern = "warn"
|
||||||
|
unseparated_literal_suffix = "warn"
|
||||||
|
unused_result_ok = "warn"
|
||||||
|
unwrap_used = "warn"
|
||||||
|
use_debug = "warn"
|
||||||
|
verbose_file_reads = "warn"
|
||||||
|
|
||||||
|
# restrictions explicit allows
|
||||||
|
absolute_paths = "allow"
|
||||||
|
alloc_instead_of_core = "allow"
|
||||||
|
as_underscore = "allow"
|
||||||
|
big_endian_bytes = "allow"
|
||||||
|
default_union_representation = "allow"
|
||||||
|
error_impl_error = "allow"
|
||||||
|
exhaustive_enums = "allow"
|
||||||
|
exhaustive_structs = "allow"
|
||||||
|
expect_used = "allow"
|
||||||
|
field_scoped_visibility_modifiers = "allow"
|
||||||
|
host_endian_bytes = "allow"
|
||||||
|
if_then_some_else_none = "allow"
|
||||||
|
impl_trait_in_params = "allow"
|
||||||
|
implicit_return = "allow"
|
||||||
|
integer_division_remainder_used = "allow"
|
||||||
|
min_ident_chars = "allow"
|
||||||
|
missing_docs_in_private_items = "allow"
|
||||||
|
missing_inline_in_public_items = "allow"
|
||||||
|
missing_trait_methods = "allow"
|
||||||
|
mod_module_files = "allow"
|
||||||
|
needless_raw_strings = "allow"
|
||||||
|
non_ascii_literal = "allow"
|
||||||
|
panic_in_result_fn = "allow"
|
||||||
|
pathbuf_init_then_push = "allow"
|
||||||
|
pub_use = "allow"
|
||||||
|
pub_with_shorthand = "allow"
|
||||||
|
question_mark_used = "allow"
|
||||||
|
ref_patterns = "allow"
|
||||||
|
semicolon_outside_block = "allow"
|
||||||
|
separated_literal_suffix = "allow"
|
||||||
|
shadow_reuse = "allow"
|
||||||
|
shadow_same = "allow"
|
||||||
|
shadow_unrelated = "allow"
|
||||||
|
single_call_fn = "allow"
|
||||||
|
single_char_lifetime_names = "allow"
|
||||||
|
std_instead_of_alloc = "allow"
|
||||||
|
std_instead_of_core = "allow"
|
||||||
|
unreachable = "allow"
|
||||||
|
unwrap_in_result = "allow"
|
||||||
|
wildcard_enum_match_arm = "allow"
|
||||||
25
Makefile
Normal file
25
Makefile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.PHONY: check
|
||||||
|
check: | fmt lint test
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
docs:
|
||||||
|
cargo watch -- cargo doc
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
cargo hack --feature-powerset --no-dev-deps check
|
||||||
|
cargo test --workspace --color=always
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint:
|
||||||
|
cargo clippy --workspace --tests --color=always
|
||||||
|
|
||||||
|
.PHONY: fmt
|
||||||
|
fmt:
|
||||||
|
cargo fmt
|
||||||
|
find -name '*.md' | xargs --no-run-if-empty prettier --print-width 80 --prose-wrap always --write
|
||||||
|
find -name '*.toml' | xargs --no-run-if-empty taplo format
|
||||||
|
|
||||||
|
.PHONY: build-static
|
||||||
|
build-static:
|
||||||
|
cargo build --target x86_64-unknown-linux-musl --no-default-features --release --workspace
|
||||||
505
src/main.rs
Normal file
505
src/main.rs
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
use std::fmt::{self, Write as _};
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use clap::{Parser, ValueEnum};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
enum LintGroup {
|
||||||
|
Cargo,
|
||||||
|
Complexity,
|
||||||
|
Correctness,
|
||||||
|
Nursery,
|
||||||
|
Pedantic,
|
||||||
|
Perf,
|
||||||
|
Restriction,
|
||||||
|
Style,
|
||||||
|
Suspicious,
|
||||||
|
Deprecated,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, ValueEnum)]
|
||||||
|
enum Profile {
|
||||||
|
Publish,
|
||||||
|
Personal,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(long)]
|
||||||
|
profile: Profile,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
workspace: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LintGroup {
|
||||||
|
fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Cargo => "cargo",
|
||||||
|
Self::Complexity => "complexity",
|
||||||
|
Self::Correctness => "correctness",
|
||||||
|
Self::Nursery => "nursery",
|
||||||
|
Self::Pedantic => "pedantic",
|
||||||
|
Self::Perf => "perf",
|
||||||
|
Self::Restriction => "restriction",
|
||||||
|
Self::Style => "style",
|
||||||
|
Self::Suspicious => "suspicious",
|
||||||
|
Self::Deprecated => "deprecated",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LintGroup {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
enum LintLevel {
|
||||||
|
Allow,
|
||||||
|
Warn,
|
||||||
|
Deny,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LintLevel {
|
||||||
|
fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Allow => "allow",
|
||||||
|
Self::Warn => "warn",
|
||||||
|
Self::Deny => "deny",
|
||||||
|
Self::None => "none",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
#[expect(dead_code, reason = "this is an external data definition")]
|
||||||
|
struct Lint {
|
||||||
|
id: LintId,
|
||||||
|
group: LintGroup,
|
||||||
|
#[serde(rename = "level")]
|
||||||
|
default_level: LintLevel,
|
||||||
|
version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
enum PrioritySetting {
|
||||||
|
Explicit(isize),
|
||||||
|
Unspecified,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
|
||||||
|
struct LintId(String);
|
||||||
|
|
||||||
|
impl fmt::Display for LintId {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LintList(Vec<LintId>);
|
||||||
|
|
||||||
|
impl From<Vec<&str>> for LintList {
|
||||||
|
fn from(value: Vec<&str>) -> Self {
|
||||||
|
Self(value.into_iter().map(|s| LintId(s.to_owned())).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SingleLintConfig {
|
||||||
|
lint: LintId,
|
||||||
|
priority: PrioritySetting,
|
||||||
|
level: LintLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct GroupConfig {
|
||||||
|
group: LintGroup,
|
||||||
|
priority: PrioritySetting,
|
||||||
|
level: LintLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Setting {
|
||||||
|
Single(SingleLintConfig),
|
||||||
|
Group(GroupConfig),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
enum ExhaustiveGroupClassification {
|
||||||
|
Default,
|
||||||
|
Exception,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ExhausiveGroup {
|
||||||
|
defaults: Vec<Setting>,
|
||||||
|
exceptions: Vec<Setting>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Exceptions {
|
||||||
|
level: LintLevel,
|
||||||
|
lints: LintList,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Setting {
|
||||||
|
fn set_group(group: LintGroup, priority: PrioritySetting, level: LintLevel) -> Self {
|
||||||
|
Self::Group(GroupConfig {
|
||||||
|
group,
|
||||||
|
priority,
|
||||||
|
level,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn warn_group(group: LintGroup, priority: PrioritySetting) -> Self {
|
||||||
|
Self::set_group(group, priority, LintLevel::Warn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deny_group(group: LintGroup, priority: PrioritySetting) -> Self {
|
||||||
|
Self::set_group(group, priority, LintLevel::Deny)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allow(response: &Response, group: LintGroup, lints: &[&str]) -> Result<Vec<Self>> {
|
||||||
|
lints
|
||||||
|
.iter()
|
||||||
|
.map(|lint| {
|
||||||
|
let lint = LintId((*lint).to_owned());
|
||||||
|
let found = response.0.iter().find(|r| r.id == lint && r.group == group);
|
||||||
|
if found.is_none() {
|
||||||
|
Err(anyhow!("lint {} not in group {}", lint, group.as_str()))
|
||||||
|
} else {
|
||||||
|
Ok(Self::Single(SingleLintConfig {
|
||||||
|
lint,
|
||||||
|
priority: PrioritySetting::Unspecified,
|
||||||
|
level: LintLevel::Allow,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_group_exhaustive(
|
||||||
|
response: &Response,
|
||||||
|
group: LintGroup,
|
||||||
|
default_level: LintLevel,
|
||||||
|
exceptions: &Exceptions,
|
||||||
|
) -> Result<ExhausiveGroup> {
|
||||||
|
let all_lints_in_group: Vec<LintId> = response
|
||||||
|
.0
|
||||||
|
.iter()
|
||||||
|
.filter_map(|lint| {
|
||||||
|
if lint.group == group {
|
||||||
|
Some(lint.id.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if let Some(err) = exceptions.lints.0.iter().find_map(|lint| {
|
||||||
|
if !all_lints_in_group.contains(lint) {
|
||||||
|
Some(anyhow!("lint {lint} not part of group {group}"))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
return Err(err);
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(all_lints_in_group
|
||||||
|
.into_iter()
|
||||||
|
.map(|lint| {
|
||||||
|
if exceptions.lints.0.contains(&lint) {
|
||||||
|
(
|
||||||
|
ExhaustiveGroupClassification::Exception,
|
||||||
|
Self::Single(SingleLintConfig {
|
||||||
|
lint,
|
||||||
|
priority: PrioritySetting::Unspecified,
|
||||||
|
level: exceptions.level,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
ExhaustiveGroupClassification::Default,
|
||||||
|
Self::Single(SingleLintConfig {
|
||||||
|
lint,
|
||||||
|
priority: PrioritySetting::Unspecified,
|
||||||
|
level: default_level,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fold(
|
||||||
|
ExhausiveGroup {
|
||||||
|
defaults: Vec::new(),
|
||||||
|
exceptions: Vec::new(),
|
||||||
|
},
|
||||||
|
|mut acc, (classification, setting)| {
|
||||||
|
match classification {
|
||||||
|
ExhaustiveGroupClassification::Default => acc.defaults.push(setting),
|
||||||
|
ExhaustiveGroupClassification::Exception => acc.exceptions.push(setting),
|
||||||
|
};
|
||||||
|
acc
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ConfigGroup {
|
||||||
|
comment: Option<String>,
|
||||||
|
settings: Vec<Setting>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Config(Vec<ConfigGroup>);
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
fn to_toml(&self, args: &Args) -> String {
|
||||||
|
let mut output = if args.workspace {
|
||||||
|
String::from("[workspace.lints.clippy]\n")
|
||||||
|
} else {
|
||||||
|
String::from("[lints.clippy]\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut iter_group = self.0.iter().peekable();
|
||||||
|
|
||||||
|
while let Some(group) = iter_group.next() {
|
||||||
|
let last_group = iter_group.peek().is_none();
|
||||||
|
if let Some(ref comment) = group.comment {
|
||||||
|
writeln!(output, "# {comment}").expect("writing to string succeeds");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut iter_setting = group.settings.iter().peekable();
|
||||||
|
while let Some(setting) = iter_setting.next() {
|
||||||
|
let last_setting = iter_setting.peek().is_none();
|
||||||
|
match *setting {
|
||||||
|
Setting::Single(ref single_lint_config) => match single_lint_config.priority {
|
||||||
|
PrioritySetting::Explicit(priority) => write!(
|
||||||
|
output,
|
||||||
|
"{} = {{ level = \"{}\", priority = {} }}",
|
||||||
|
single_lint_config.lint.0,
|
||||||
|
single_lint_config.level.as_str(),
|
||||||
|
priority
|
||||||
|
)
|
||||||
|
.expect("writing to string succeeds"),
|
||||||
|
PrioritySetting::Unspecified => write!(
|
||||||
|
output,
|
||||||
|
"{} = \"{}\"",
|
||||||
|
single_lint_config.lint.0,
|
||||||
|
single_lint_config.level.as_str()
|
||||||
|
)
|
||||||
|
.expect("writing to string succeeds"),
|
||||||
|
},
|
||||||
|
Setting::Group(ref group_config) => match group_config.priority {
|
||||||
|
PrioritySetting::Explicit(priority) => write!(
|
||||||
|
output,
|
||||||
|
"{} = {{ level = \"{}\", priority = {} }}",
|
||||||
|
group_config.group.as_str(),
|
||||||
|
group_config.level.as_str(),
|
||||||
|
priority
|
||||||
|
)
|
||||||
|
.expect("writing to string succeeds"),
|
||||||
|
PrioritySetting::Unspecified => write!(
|
||||||
|
output,
|
||||||
|
"{} = \"{}\"",
|
||||||
|
group_config.group.as_str(),
|
||||||
|
group_config.level.as_str(),
|
||||||
|
)
|
||||||
|
.expect("writing to string succeeds"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if !last_setting {
|
||||||
|
output.push('\n');
|
||||||
|
}
|
||||||
|
if last_setting && !last_group {
|
||||||
|
output.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !last_group {
|
||||||
|
output.push('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Response(Vec<Lint>);
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let response: Response = ureq::get("https://rust-lang.github.io/rust-clippy/stable/lints.json")
|
||||||
|
.call()?
|
||||||
|
.into_json()?;
|
||||||
|
|
||||||
|
let restriction_group = Setting::split_group_exhaustive(
|
||||||
|
&response,
|
||||||
|
LintGroup::Restriction,
|
||||||
|
LintLevel::Allow,
|
||||||
|
&Exceptions {
|
||||||
|
level: LintLevel::Warn,
|
||||||
|
lints: vec![
|
||||||
|
"allow_attributes",
|
||||||
|
"allow_attributes_without_reason",
|
||||||
|
"arithmetic_side_effects",
|
||||||
|
"as_conversions",
|
||||||
|
"assertions_on_result_states",
|
||||||
|
"cfg_not_test",
|
||||||
|
"clone_on_ref_ptr",
|
||||||
|
"create_dir",
|
||||||
|
"dbg_macro",
|
||||||
|
"decimal_literal_representation",
|
||||||
|
"default_numeric_fallback",
|
||||||
|
"deref_by_slicing",
|
||||||
|
"disallowed_script_idents",
|
||||||
|
"else_if_without_else",
|
||||||
|
"empty_drop",
|
||||||
|
"empty_enum_variants_with_brackets",
|
||||||
|
"empty_structs_with_brackets",
|
||||||
|
"exit",
|
||||||
|
"filetype_is_file",
|
||||||
|
"float_arithmetic",
|
||||||
|
"float_cmp_const",
|
||||||
|
"fn_to_numeric_cast_any",
|
||||||
|
"format_push_string",
|
||||||
|
"get_unwrap",
|
||||||
|
"indexing_slicing",
|
||||||
|
"infinite_loop",
|
||||||
|
"inline_asm_x86_att_syntax",
|
||||||
|
"inline_asm_x86_intel_syntax",
|
||||||
|
"integer_division",
|
||||||
|
"iter_over_hash_type",
|
||||||
|
"large_include_file",
|
||||||
|
"let_underscore_must_use",
|
||||||
|
"let_underscore_untyped",
|
||||||
|
"little_endian_bytes",
|
||||||
|
"lossy_float_literal",
|
||||||
|
"map_err_ignore",
|
||||||
|
"mem_forget",
|
||||||
|
"missing_assert_message",
|
||||||
|
"missing_asserts_for_indexing",
|
||||||
|
"mixed_read_write_in_expression",
|
||||||
|
"modulo_arithmetic",
|
||||||
|
"multiple_inherent_impl",
|
||||||
|
"multiple_unsafe_ops_per_block",
|
||||||
|
"mutex_atomic",
|
||||||
|
"panic",
|
||||||
|
"partial_pub_fields",
|
||||||
|
"pattern_type_mismatch",
|
||||||
|
"print_stderr",
|
||||||
|
"print_stdout",
|
||||||
|
"pub_without_shorthand",
|
||||||
|
"rc_buffer",
|
||||||
|
"rc_mutex",
|
||||||
|
"redundant_type_annotations",
|
||||||
|
"renamed_function_params",
|
||||||
|
"rest_pat_in_fully_bound_structs",
|
||||||
|
"same_name_method",
|
||||||
|
"self_named_module_files",
|
||||||
|
"semicolon_inside_block",
|
||||||
|
"str_to_string",
|
||||||
|
"string_add",
|
||||||
|
"string_lit_chars_any",
|
||||||
|
"string_slice",
|
||||||
|
"string_to_string",
|
||||||
|
"suspicious_xor_used_as_pow",
|
||||||
|
"tests_outside_test_module",
|
||||||
|
"todo",
|
||||||
|
"try_err",
|
||||||
|
"undocumented_unsafe_blocks",
|
||||||
|
"unimplemented",
|
||||||
|
"unnecessary_safety_comment",
|
||||||
|
"unnecessary_safety_doc",
|
||||||
|
"unnecessary_self_imports",
|
||||||
|
"unneeded_field_pattern",
|
||||||
|
"unseparated_literal_suffix",
|
||||||
|
"unused_result_ok",
|
||||||
|
"unwrap_used",
|
||||||
|
"use_debug",
|
||||||
|
"verbose_file_reads",
|
||||||
|
]
|
||||||
|
.into(),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let config = Config(vec![
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("enabled groups".to_owned()),
|
||||||
|
settings: vec![
|
||||||
|
Setting::deny_group(LintGroup::Correctness, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Suspicious, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Style, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Complexity, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Perf, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Cargo, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Pedantic, PrioritySetting::Explicit(-1)),
|
||||||
|
Setting::warn_group(LintGroup::Nursery, PrioritySetting::Explicit(-1)),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("pedantic overrides".to_owned()),
|
||||||
|
settings: Setting::allow(
|
||||||
|
&response,
|
||||||
|
LintGroup::Pedantic,
|
||||||
|
&[
|
||||||
|
"too_many_lines",
|
||||||
|
"must_use_candidate",
|
||||||
|
"map_unwrap_or",
|
||||||
|
"missing_errors_doc",
|
||||||
|
"if_not_else",
|
||||||
|
],
|
||||||
|
)?,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("nursery overrides".to_owned()),
|
||||||
|
settings: Setting::allow(
|
||||||
|
&response,
|
||||||
|
LintGroup::Nursery,
|
||||||
|
&["missing_const_for_fn", "option_if_let_else"],
|
||||||
|
)?,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("complexity overrides".to_owned()),
|
||||||
|
settings: Setting::allow(&response, LintGroup::Complexity, &["too_many_arguments"])?,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("style overrides".to_owned()),
|
||||||
|
settings: Setting::allow(&response, LintGroup::Style, &["new_without_default"])?,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("cargo overrides".to_owned()),
|
||||||
|
settings: Setting::allow(&response, LintGroup::Cargo, &{
|
||||||
|
let mut v = vec!["multiple_crate_versions"];
|
||||||
|
match args.profile {
|
||||||
|
Profile::Publish => (),
|
||||||
|
Profile::Personal => v.push("cargo_common_metadata"),
|
||||||
|
}
|
||||||
|
v
|
||||||
|
})?,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("selected restrictions".to_owned()),
|
||||||
|
settings: restriction_group.exceptions,
|
||||||
|
},
|
||||||
|
ConfigGroup {
|
||||||
|
comment: Some("restrictions explicit allows".to_owned()),
|
||||||
|
settings: restriction_group.defaults,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
let output = config.to_toml(&args);
|
||||||
|
|
||||||
|
#[expect(clippy::print_stdout, reason = "this is the main program output")]
|
||||||
|
{
|
||||||
|
println!("{output}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user