diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e5b5b43..75d613a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,13 +169,19 @@ jobs: components: rustfmt, clippy - name: Format if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }} - run: cargo fmt --check + run: cargo fmt --check --all - name: Set up cargo-action-fmt if: ${{ github.event_name == 'pull_request' && matrix.target == 'x86_64-unknown-linux-gnu' }} uses: olix0r/cargo-action-fmt/setup@v2 + - name: Check + if: ${{ github.event_name == 'pull_request' && matrix.target == 'x86_64-unknown-linux-gnu' }} + run: cargo check --all-features --all-targets --workspace --target ${{ matrix.target }} -q --message-format=json | cargo-action-fmt + - name: Check + if: ${{ github.event_name != 'pull_request' || matrix.target != 'x86_64-unknown-linux-gnu' }} + run: cargo check --all-features --all-targets --workspace --target ${{ matrix.target }} - name: Clippy if: ${{ github.event_name == 'pull_request' && matrix.target == 'x86_64-unknown-linux-gnu' }} - run: cargo clippy --all-features --all-targets --target ${{ matrix.target }} -q --message-format=json | cargo-action-fmt + run: cargo clippy --all-features --all-targets --workspace --target ${{ matrix.target }} -q --message-format=json | cargo-action-fmt - name: Clippy if: ${{ github.event_name != 'pull_request' || matrix.target != 'x86_64-unknown-linux-gnu' }} - run: cargo clippy --all-features --all-targets --target ${{ matrix.target }} + run: cargo clippy --all-features --all-targets --workspace --target ${{ matrix.target }} diff --git a/Cargo.toml b/Cargo.toml index d0aba7e..48943b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,13 +35,78 @@ maintenance = { status = "actively-developed" } [lints] workspace = true +[workspace.lints.rust] +explicit_outlives_requirements = "deny" +let-underscore-drop = "deny" +meta-variable-misuse = "deny" +non_ascii_idents = "deny" +non-local-definitions = "deny" +redundant-imports = "deny" +redundant-lifetimes = "deny" +single-use-lifetimes = "deny" +trivial-casts = "deny" +trivial_numeric_casts = "deny" +unit-bindings = "deny" +unnameable-types = "deny" +unsafe-code = "deny" # Will only be allowed in platform-specific modules +unused-import-braces = "deny" +unused-lifetimes = "deny" +unused-macro-rules = "deny" +unused_qualifications = "deny" +variant_size_differences = "deny" + [workspace.lints.clippy] -correctness = "deny" -style = "deny" -complexity = "deny" -perf = "deny" -pedantic = "deny" -cargo = "deny" -suspicious = "warn" -nursery = "warn" -restriction = "allow" +correctness = { level = "deny", priority = -1 } +style = { level = "deny", priority = -1 } +complexity = { level = "deny", priority = -1 } +perf = { level = "deny", priority = -1 } +pedantic = { level = "deny", priority = -1 } +cargo = { level = "deny", priority = -1 } +suspicious = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } + +restriction = { level = "allow", priority = -1 } +allow_attributes = "deny" +as_underscore = "deny" +assertions_on_result_states = "deny" +cfg_not_test = "deny" +clone_on_ref_ptr = "deny" +create_dir = "deny" +dbg_macro = "deny" +empty_drop = "deny" +empty_enum_variants_with_brackets = "deny" +empty_structs_with_brackets = "deny" +exit = "deny" +expect_used = "deny" +float_cmp_const = "deny" +fn_to_numeric_cast_any = "deny" +format_push_string = "deny" +get_unwrap = "deny" +if_then_some_else_none = "deny" +impl_trait_in_params = "deny" +infinite_loop = "deny" +map_with_unused_argument_over_ranges = "deny" +mem_forget = "deny" +missing_assert_message = "deny" +mixed_read_write_in_expression = "deny" +mod_module_files = "deny" +module_name_repetitions = "deny" +multiple_inherent_impl = "deny" +mutex_atomic = "deny" +needless_raw_strings = "deny" +panic = "deny" +rc_buffer = "deny" +rc_mutex = "deny" +redundant_type_annotations = "deny" +ref_patterns = "deny" +renamed_function_params = "deny" +rest_pat_in_fully_bound_structs = "deny" +same_name_method = "deny" +semicolon_outside_block = "deny" +separated_literal_suffix = "deny" +str_to_string = "deny" +unused_result_ok = "deny" +unwrap_used = "deny" +use_debug = "deny" +verbose_file_reads = "deny" +wildcard_enum_match_arm = "deny" \ No newline at end of file diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..c64d65f --- /dev/null +++ b/clippy.toml @@ -0,0 +1,3 @@ +allow-expect-in-tests = true +allow-panic-in-tests = true +allow-unwrap-in-tests = true diff --git a/src/config.rs b/src/config.rs index b5ab255..948d1fd 100644 --- a/src/config.rs +++ b/src/config.rs @@ -213,8 +213,8 @@ mod tests { impl Drop for TempEnvVar { fn drop(&mut self) { - match self.orig_value { - Some(ref orig_value) => env::set_var(&self.key, orig_value), + match &self.orig_value { + Some(orig_value) => env::set_var(&self.key, orig_value), None => env::remove_var(&self.key), } } diff --git a/src/editor.rs b/src/editor.rs index 0cab553..9426321 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -721,7 +721,7 @@ impl Editor { self.file_name = None; } loop { - if let Some(ref mode) = self.prompt_mode { + if let Some(mode) = &self.prompt_mode { set_status!(self, "{}", mode.status_msg()); } self.refresh_screen()?; @@ -740,6 +740,7 @@ impl Editor { } impl Drop for Editor { + #[allow(clippy::expect_used)] /// When the editor is dropped, restore the original terminal mode. fn drop(&mut self) { if let Some(orig_term_mode) = self.orig_term_mode.take() { @@ -792,6 +793,7 @@ impl PromptMode { } match process_prompt_keypress(b, key) { PromptState::Active(query) => { + #[allow(clippy::wildcard_enum_match_arm)] let (last_match, forward) = match key { Key::Arrow(AKey::Right | AKey::Down) | Key::Char(FIND) => (last_match, true), @@ -860,6 +862,7 @@ enum PromptState { /// Process a prompt keypress event and return the new state for the prompt. fn process_prompt_keypress(mut buffer: String, key: &Key) -> PromptState { + #[allow(clippy::wildcard_enum_match_arm)] match key { Key::Char(b'\r') => return PromptState::Completed(buffer), Key::Escape | Key::Char(EXIT) => return PromptState::Cancelled, diff --git a/src/row.rs b/src/row.rs index 6568e04..f7cbe13 100644 --- a/src/row.rs +++ b/src/row.rs @@ -64,8 +64,8 @@ impl Row { // The number of rendered characters let n_rend_chars = if c == '\t' { tab - (rx % tab) } else { c.width().unwrap_or(1) }; self.render.push_str(&(if c == '\t' { " ".repeat(n_rend_chars) } else { c.into() })); - self.cx2rx.extend(std::iter::repeat(rx).take(c.len_utf8())); - self.rx2cx.extend(std::iter::repeat(cx).take(n_rend_chars)); + self.cx2rx.extend(repeat(rx).take(c.len_utf8())); + self.rx2cx.extend(repeat(cx).take(n_rend_chars)); (rx, cx) = (rx + n_rend_chars, cx + c.len_utf8()); } let (..) = (self.cx2rx.push(rx), self.rx2cx.push(cx)); diff --git a/src/terminal.rs b/src/terminal.rs index 753cec9..b09f2a9 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -15,7 +15,7 @@ pub fn get_window_size_using_cursor() -> Result<(usize, usize), Error> { let mut stdin = sys::stdin()?; print!("{REPOSITION_CURSOR_END}{DEVICE_STATUS_REPORT}"); io::stdout().flush()?; - let mut prefix_buffer = [0_u8; 2]; + let mut prefix_buffer = [0u8; 2]; stdin.read_exact(&mut prefix_buffer)?; if prefix_buffer != [b'\x1b', b'['] { return Err(Error::CursorPosition); diff --git a/src/unix.rs b/src/unix.rs index 126c04b..3019be4 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -2,6 +2,7 @@ //! //! UNIX-specific structs and functions. Will be imported as `sys` on UNIX //! systems. +#![allow(unsafe_code)] use std::sync::atomic::{AtomicBool, Ordering::Relaxed}; @@ -40,6 +41,7 @@ static WSC: AtomicBool = AtomicBool::new(false); /// Handle a change in window size. extern "C" fn handle_wsize(_: c_int, _: *mut siginfo_t, _: *mut c_void) { WSC.store(true, Relaxed) } +#[allow(clippy::fn_to_numeric_cast_any)] /// Register a signal handler that sets a global variable when the window size /// changes. After calling this function, use `has_window_size_changed` to query /// the global variable. @@ -51,7 +53,7 @@ pub fn register_winsize_change_signal_handler() -> Result<(), Error> { // have sa_handler field, so we use sa_sigaction instead. (*maybe_sa.as_mut_ptr()).sa_flags = SA_SIGINFO; (*maybe_sa.as_mut_ptr()).sa_sigaction = handle_wsize as sighandler_t; - cerr(libc::sigaction(libc::SIGWINCH, maybe_sa.as_ptr(), std::ptr::null_mut())) + cerr(sigaction(libc::SIGWINCH, maybe_sa.as_ptr(), std::ptr::null_mut())) } } diff --git a/src/wasi.rs b/src/wasi.rs index cc04a5e..545ea6e 100644 --- a/src/wasi.rs +++ b/src/wasi.rs @@ -6,7 +6,7 @@ use crate::Error; pub use crate::xdg::*; -pub struct TermMode {} +pub struct TermMode; /// Return the current window size as (rows, columns). /// By returning an error we cause kibi to fall back to another method of diff --git a/src/windows.rs b/src/windows.rs index 9e0a8f2..749baaf 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -62,6 +62,6 @@ pub fn enable_raw_mode() -> Result { } #[allow(clippy::unnecessary_wraps)] // Result required on other platforms -pub fn stdin() -> std::io::Result { Ok(std::io::stdin()) } +pub fn stdin() -> io::Result { Ok(io::stdin()) } pub fn path(filename: &str) -> std::path::PathBuf { std::path::PathBuf::from(filename) } diff --git a/xtask/src/count_loc.rs b/xtask/src/count_loc.rs index d3a14a6..e96a2da 100644 --- a/xtask/src/count_loc.rs +++ b/xtask/src/count_loc.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use anstream::println; use glob::glob; @@ -23,10 +23,10 @@ pub fn count_loc() -> Result<()> { print_summary(&results, longest_path, &["unix", "wasi", "windows"]) } -/// Filter out lines that contain `clippy` lints and anything after +/// Filter out lines that contain lints and anything after /// `#[cfg(test)]` attributes. -pub fn filter_lines(path: &std::path::PathBuf) -> Result { - let regex = Regex::new(r"^\s*#!?\[(?:allow|warn|deny)\(clippy::")?; +pub fn filter_lines(path: &Path) -> Result { + let regex = Regex::new(r"^\s*#!?\[(?:allow|warn|deny)\(")?; let content = std::fs::read_to_string(path)?; let lines = content .lines() @@ -60,7 +60,7 @@ pub fn print_summary(results: &[(PathBuf, usize)], width: usize, platforms: &[&s Ok(()) } -pub fn filter_count(results: &[(std::path::PathBuf, usize)], pattern: &str) -> usize { +pub fn filter_count(results: &[(PathBuf, usize)], pattern: &str) -> usize { results .iter() .filter(|(path, _)| path.display().to_string().contains(pattern)) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index da95d59..0c3692c 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,4 +1,5 @@ -use std::io::Write; +#![allow(clippy::multiple_crate_versions)] +use std::process::ExitCode; use anstyle::{AnsiColor, Reset, Style}; use clap::{Parser, Subcommand}; @@ -11,12 +12,14 @@ const RESET: Reset = Reset; const RED: Style = AnsiColor::Red.on_default(); const GREEN: Style = AnsiColor::Green.on_default(); -fn main() { +fn main() -> ExitCode { let args = Args::parse(); - if let Err(err) = args.command.execute() { - let _ = std::io::stdout().flush(); - eprintln!("{RED}{err}{RESET}"); - std::process::exit(1); + match args.command.execute() { + Ok(()) => ExitCode::SUCCESS, + Err(err) => { + eprintln!("{RED}{err}{RESET}"); + ExitCode::FAILURE + } } } @@ -34,7 +37,7 @@ enum Command { impl Command { fn execute(&self) -> Result<()> { match self { - Command::CountLoc => count_loc::count_loc(), + Self::CountLoc => count_loc::count_loc(), } } }