ci

CI for all possible combinations of features in Cargo.toml.
git clone https://git.philomathiclife.com/repos/ci
Log | Files | Refs | README

commit 02766aa6bec6691733a816f139c4481d06136062
parent 8e3e5829b00974dd113cc245d0c297ee6f108b5e
Author: Zack Newman <zack@philomathiclife.com>
Date:   Mon, 23 Jun 2025 12:35:28 -0600

more lints

Diffstat:
MCargo.toml | 40++++++++++++++++++++++++++++++++--------
Msrc/args.rs | 14+++++++-------
Msrc/manifest.rs | 14+++++++-------
3 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -7,24 +7,52 @@ edition = "2024" keywords = ["cargo", "ci", "rust"] license = "MIT OR Apache-2.0" name = "ci" +publish = false readme = "README.md" repository = "https://git.philomathiclife.com/repos/ci/" rust-version = "1.86.0" -version = "0.3.0" +version = "0.3.1" [lints.rust] -unknown_lints = { level = "deny", priority = -1 } +ambiguous_negative_literals = { level = "deny", priority = -1 } +closure_returning_async_block = { level = "deny", priority = -1 } +deref_into_dyn_supertrait = { level = "deny", priority = -1 } +ffi_unwind_calls = { level = "deny", priority = -1 } future_incompatible = { level = "deny", priority = -1 } +impl_trait_redundant_captures = { level = "deny", priority = -1 } +keyword-idents = { level = "deny", priority = -1 } let_underscore = { level = "deny", priority = -1 } +linker_messages = { level = "deny", priority = -1 } +macro_use_extern_crate = { level = "deny", priority = -1 } +meta_variable_misuse = { level = "deny", priority = -1 } +missing_copy_implementations = { level = "deny", priority = -1 } +missing_debug_implementations = { level = "deny", priority = -1 } missing_docs = { level = "deny", priority = -1 } +non_ascii_idents = { level = "deny", priority = -1 } nonstandard_style = { level = "deny", priority = -1 } +redundant_imports = { level = "deny", priority = -1 } +redundant_lifetimes = { level = "deny", priority = -1 } refining_impl_trait = { level = "deny", priority = -1 } rust_2018_compatibility = { level = "deny", priority = -1 } rust_2018_idioms = { level = "deny", priority = -1 } rust_2021_compatibility = { level = "deny", priority = -1 } rust_2024_compatibility = { level = "deny", priority = -1 } +single_use_lifetimes = { level = "deny", priority = -1 } +trivial_casts = { level = "deny", priority = -1 } +trivial_numeric_casts = { level = "deny", priority = -1 } +unit_bindings = { level = "deny", priority = -1 } +unknown_lints = { level = "deny", priority = -1 } +unnameable_types = { level = "deny", priority = -1 } +unreachable_pub = { level = "deny", priority = -1 } unsafe_code = { level = "deny", priority = -1 } +unstable_features = { level = "deny", priority = -1 } unused = { level = "deny", priority = -1 } +unused_crate_dependencies = { level = "deny", priority = -1 } +unused_import_braces = { level = "deny", priority = -1 } +unused_lifetimes = { level = "deny", priority = -1 } +unused_qualifications = { level = "deny", priority = -1 } +unused_results = { level = "deny", priority = -1 } +variant_size_differences = { level = "deny", priority = -1 } warnings = { level = "deny", priority = -1 } [lints.clippy] @@ -41,25 +69,21 @@ suspicious = { level = "deny", priority = -1 } # Noisy, opinionated, and likely don't prevent bugs or improve APIs. arbitrary_source_item_ordering = "allow" blanket_clippy_restriction_lints = "allow" -exhaustive_enums = "allow" -exhaustive_structs = "allow" implicit_return = "allow" min_ident_chars = "allow" missing_trait_methods = "allow" -multiple_crate_versions = "allow" pub_with_shorthand = "allow" -pub_use = "allow" question_mark_used = "allow" ref_patterns = "allow" +redundant_pub_crate = "allow" return_and_then = "allow" -self_named_module_files = "allow" single_call_fn = "allow" single_char_lifetime_names = "allow" unseparated_literal_suffix = "allow" [dependencies] serde = { version = "1.0.219", default-features = false } -toml = { version = "0.8.20", default-features = false, features = ["parse"] } +toml = { version = "0.8.23", default-features = false, features = ["parse"] } [profile.release] lto = true diff --git a/src/args.rs b/src/args.rs @@ -11,7 +11,7 @@ use std::{ }; /// Error returned when parsing arguments passed to the application. #[derive(Clone, Debug)] -pub enum ArgsErr { +pub(crate) enum ArgsErr { /// Error when no arguments exist. NoArgs, /// Error when an invalid option is passed. The contained [`String`] is the value of the invalid option. @@ -42,7 +42,7 @@ impl Display for ArgsErr { impl Error for ArgsErr {} /// The options passed to the application. #[derive(Clone, Copy, Debug)] -pub enum Opts { +pub(crate) enum Opts { /// Variant when no arguments were passed. /// /// The first contained `bool` is `true` iff `--color always` should be used; otherwise `--color never` is used. @@ -70,7 +70,7 @@ pub enum Opts { IncludeIgnoredTests(bool), } /// Kind of successful completion of a command. -pub enum Success { +pub(crate) enum Success { /// Ran normally without errors. Normal, /// Erred due to [`compile_error`]. @@ -155,7 +155,7 @@ impl Opts { cmd.push(' '); cmd }); - cmd.pop(); + _ = cmd.pop(); cmd } /// Runs `cargo` with argument based on `self` and features of `features` returning `Ok(Success::Normal)` iff @@ -167,7 +167,7 @@ impl Opts { /// due to a lack of library target; in which case, the second `bool` becomes `true`. #[expect(clippy::else_if_without_else, reason = "don't want it")] #[expect(clippy::too_many_lines, reason = "not too many")] - pub fn run_cmd( + pub(crate) fn run_cmd( &mut self, features: &str, err_msgs: &mut HashSet<String>, @@ -234,7 +234,7 @@ impl Opts { } else { return String::from_utf8(output.stderr).map_err(E::Utf8).map( |msg| { - err_msgs.insert(msg); + _ = err_msgs.insert(msg); Success::Normal }, ); @@ -315,7 +315,7 @@ impl Opts { } /// Returns `Opts` and the directory `ci` should run in based on arguments passed to the application. #[expect(clippy::redundant_else, reason = "when else-if is used, prefer else")] - pub fn from_args() -> Result<(Self, Option<PathBuf>), E> { + pub(crate) fn from_args() -> Result<(Self, Option<PathBuf>), E> { let mut args = env::args(); if args.next().is_none() { return Err(E::Args(ArgsErr::NoArgs)); diff --git a/src/manifest.rs b/src/manifest.rs @@ -8,11 +8,11 @@ impl ImpliedFeatures { /// Returns `true` iff any feature in the `ImpliedFeatures` graph is `feature`. fn contains(&self, feature: &str, features: &Features) -> bool { /// Recursively iterates the features in `left` and checks if one is `feature`. - fn recurse<'a: 'e, 'b, 'c: 'e, 'd, 'e>( + fn recurse<'a>( left: &'a ImpliedFeatures, - feature: &'b str, - features: &'c Features, - cycle_detection: &'d mut HashSet<&'e str>, + feature: &str, + features: &'a Features, + cycle_detection: &mut HashSet<&'a str>, ) -> Result<(), ()> { left.0.iter().try_fold((), |(), feat| { if feat == feature || !cycle_detection.insert(feat) { @@ -48,7 +48,7 @@ impl<'de> Deserialize<'de> for ImpliedFeatures { { let mut feats = HashSet::with_capacity(seq.size_hint().unwrap_or_default()); while let Some(val) = seq.next_element::<String>()? { - feats.insert(val); + _ = feats.insert(val); } Ok(ImpliedFeatures(feats)) } @@ -122,7 +122,7 @@ impl Features { }); // Remove the trailing comma. // Note a trailing comma exist iff `feat_combo` is not empty. When empty, this does nothing. - feat_combo.pop(); + _ = feat_combo.pop(); feats.push(feat_combo); feats }) @@ -276,6 +276,6 @@ impl<'de> Deserialize<'de> for Manifest { } } /// Returns possible combinations of features. -pub fn from_toml(val: &str) -> Result<Vec<String>, TomlErr> { +pub(crate) fn from_toml(val: &str) -> Result<Vec<String>, TomlErr> { toml::from_str::<Manifest>(val).map(|man| man.0.powerset()) }