diff --git a/.clippy.toml b/.clippy.toml index 68e430e..027eef4 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1,5 +1,5 @@ -msrv = "1.74" # MSRV warn-on-all-wildcard-imports = true +allow-print-in-tests = true allow-expect-in-tests = true allow-unwrap-in-tests = true allow-dbg-in-tests = true diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 1725e3e..c184420 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -3,6 +3,7 @@ 'before 5am on the first day of the month', ], semanticCommits: 'enabled', + commitMessageLowerCase: 'never', configMigration: true, dependencyDashboard: true, customManagers: [ @@ -17,29 +18,28 @@ '^\\.github/workflows/rust-next.yml$', ], matchStrings: [ - 'MSRV.*?(?\\d+\\.\\d+(\\.\\d+)?)', - '(?\\d+\\.\\d+(\\.\\d+)?).*?MSRV', + 'STABLE.*?(?\\d+\\.\\d+(\\.\\d+)?)', + '(?\\d+\\.\\d+(\\.\\d+)?).*?STABLE', ], - depNameTemplate: 'rust', + depNameTemplate: 'STABLE', packageNameTemplate: 'rust-lang/rust', datasourceTemplate: 'github-releases', }, ], packageRules: [ { - commitMessageTopic: 'MSRV', + commitMessageTopic: 'Rust Stable', matchManagers: [ 'custom.regex', ], matchPackageNames: [ - 'rust', + 'STABLE', ], - minimumReleaseAge: '126 days', // 3 releases * 6 weeks per release * 7 days per week - internalChecksFilter: 'strict', extractVersion: '^(?\\d+\\.\\d+)', // Drop the patch version schedule: [ '* * * * *', ], + automerge: true, }, // Goals: // - Keep version reqs low, ignoring compatible normal/build dependencies @@ -72,6 +72,7 @@ matchCurrentVersion: '>=1.0.0', matchUpdateTypes: [ 'minor', + 'patch', ], enabled: false, }, @@ -99,6 +100,7 @@ matchCurrentVersion: '>=1.0.0', matchUpdateTypes: [ 'minor', + 'patch', ], automerge: true, groupName: 'compatible (dev)', diff --git a/.github/settings.yml b/.github/settings.yml index ec48d6d..ef0e69d 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -42,14 +42,18 @@ labels: color: '#c2e0c6' description: "Help wanted!" -branches: - - name: main - protection: - required_pull_request_reviews: null - required_conversation_resolution: true - required_status_checks: - # Required. Require branches to be up to date before merging. - strict: false - contexts: ["CI", "Lint Commits", "Spell Check with Typos"] - enforce_admins: false - restrictions: null +# This serves more as documentation. +# Branch protection API was replaced by rulesets but settings isn't updated. +# See https://github.com/repository-settings/app/issues/825 +# +# branches: +# - name: main +# protection: +# required_pull_request_reviews: null +# required_conversation_resolution: true +# required_status_checks: +# # Required. Require branches to be up to date before merging. +# strict: false +# contexts: ["CI", "Spell Check with Typos"] +# enforce_admins: false +# restrictions: null diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index ccee1fe..07c70ee 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -17,6 +17,10 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: security_audit: permissions: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 733906a..95b13b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,21 +14,27 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: ci: permissions: contents: none name: CI - needs: [test, msrv, docs, rustfmt, clippy] + needs: [test, msrv, lockfile, docs, rustfmt, clippy] runs-on: ubuntu-latest + if: "always()" steps: - - name: Done - run: exit 0 + - name: Failed + run: exit 1 + if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')" test: name: Test strategy: matrix: - os: ["ubuntu-latest", "windows-latest", "macos-latest"] + os: ["ubuntu-latest", "windows-latest", "macos-14"] rust: ["stable"] continue-on-error: ${{ matrix.rust != 'stable' }} runs-on: ${{ matrix.os }} @@ -40,16 +46,13 @@ jobs: with: toolchain: ${{ matrix.rust }} - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@cargo-hack - name: Build - run: cargo test --no-run --workspace --all-features - - name: Default features - run: cargo test --workspace - - name: All features - run: cargo test --workspace --all-features - - name: No-default features - run: cargo test --workspace --no-default-features + run: cargo test --workspace --no-run + - name: Test + run: cargo hack test --feature-powerset --workspace msrv: - name: "Check MSRV: 1.74" + name: "Check MSRV" runs-on: ubuntu-latest steps: - name: Checkout repository @@ -57,14 +60,11 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: "1.74" # MSRV + toolchain: stable - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@cargo-hack - name: Default features - run: cargo check --workspace --all-targets - - name: All features - run: cargo check --workspace --all-targets --all-features - - name: No-default features - run: cargo check --workspace --all-targets --no-default-features + run: cargo hack check --feature-powerset --locked --rust-version --ignore-private --workspace --all-targets lockfile: runs-on: ubuntu-latest steps: @@ -76,7 +76,7 @@ jobs: toolchain: stable - uses: Swatinem/rust-cache@v2 - name: "Is lockfile updated?" - run: cargo fetch --locked + run: cargo update --workspace --locked docs: name: Docs runs-on: ubuntu-latest @@ -86,7 +86,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: stable + toolchain: "1.76" # STABLE - uses: Swatinem/rust-cache@v2 - name: Check documentation env: @@ -101,9 +101,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - # Not MSRV because its harder to jump between versions and people are - # more likely to have stable - toolchain: stable + toolchain: "1.76" # STABLE components: rustfmt - uses: Swatinem/rust-cache@v2 - name: Check formatting @@ -119,13 +117,13 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: "1.74" # MSRV + toolchain: "1.76" # STABLE components: clippy - uses: Swatinem/rust-cache@v2 - name: Install SARIF tools - run: cargo install clippy-sarif --version 0.3.4 --locked # Held back due to msrv + run: cargo install clippy-sarif --locked - name: Install SARIF tools - run: cargo install sarif-fmt --version 0.3.4 --locked # Held back due to msrv + run: cargo install sarif-fmt --locked - name: Check run: > cargo clippy --workspace --all-features --all-targets --message-format=json -- -D warnings --allow deprecated @@ -140,3 +138,22 @@ jobs: wait-for-processing: true - name: Report status run: cargo clippy --workspace --all-features --all-targets -- -D warnings --allow deprecated + coverage: + name: Coverage + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + - uses: Swatinem/rust-cache@v2 + - name: Install cargo-tarpaulin + run: cargo install cargo-tarpaulin + - name: Gather coverage + run: cargo tarpaulin --output-dir coverage --out lcov + - name: Publish to Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/committed.yml b/.github/workflows/committed.yml index 0462558..e7a50fb 100644 --- a/.github/workflows/committed.yml +++ b/.github/workflows/committed.yml @@ -11,6 +11,10 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: committed: name: Lint Commits diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 6eb6ca1..1b000ab 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -12,6 +12,10 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: pre-commit: permissions: diff --git a/.github/workflows/rust-next.yml b/.github/workflows/rust-next.yml index f1f6a90..bb14f4e 100644 --- a/.github/workflows/rust-next.yml +++ b/.github/workflows/rust-next.yml @@ -12,12 +12,16 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: test: name: Test strategy: matrix: - os: ["ubuntu-latest", "windows-latest", "macos-latest"] + os: ["ubuntu-latest", "windows-latest", "macos-latest", "macos-14"] rust: ["stable", "beta"] include: - os: ubuntu-latest @@ -32,12 +36,11 @@ jobs: with: toolchain: ${{ matrix.rust }} - uses: Swatinem/rust-cache@v2 - - name: Default features - run: cargo test --workspace - - name: All features - run: cargo test --workspace --all-features - - name: No-default features - run: cargo test --workspace --no-default-features + - uses: taiki-e/install-action@cargo-hack + - name: Build + run: cargo test --workspace --no-run + - name: Test + run: cargo hack test --feature-powerset --workspace latest: name: "Check latest dependencies" runs-on: ubuntu-latest @@ -49,11 +52,10 @@ jobs: with: toolchain: stable - uses: Swatinem/rust-cache@v2 + - uses: taiki-e/install-action@cargo-hack - name: Update dependencues run: cargo update - - name: Default features - run: cargo test --workspace --all-targets - - name: All features - run: cargo test --workspace --all-targets --all-features - - name: No-default features - run: cargo test --workspace --all-targets --no-default-features + - name: Build + run: cargo test --workspace --no-run + - name: Test + run: cargo hack test --feature-powerset --workspace diff --git a/.github/workflows/spelling.yml b/.github/workflows/spelling.yml index 12f7585..8e58d9e 100644 --- a/.github/workflows/spelling.yml +++ b/.github/workflows/spelling.yml @@ -10,6 +10,10 @@ env: CARGO_TERM_COLOR: always CLICOLOR: 1 +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + jobs: spelling: name: Spell Check with Typos diff --git a/Cargo.toml b/Cargo.toml index 33e7574..07117d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,76 @@ include = [ "examples/**/*" ] +[workspace.lints.rust] +rust_2018_idioms = "warn" +unreachable_pub = "warn" +unsafe_op_in_unsafe_fn = "warn" +unused_lifetimes = "warn" +unused_macro_rules = "warn" +unused_qualifications = "warn" + +[workspace.lints.clippy] +bool_assert_comparison = "allow" +branches_sharing_code = "allow" +checked_conversions = "warn" +collapsible_else_if = "allow" +create_dir = "warn" +dbg_macro = "warn" +debug_assert_with_mut_call = "warn" +doc_markdown = "warn" +empty_enum = "warn" +enum_glob_use = "warn" +expl_impl_clone_on_copy = "warn" +explicit_deref_methods = "warn" +explicit_into_iter_loop = "warn" +fallible_impl_from = "warn" +filter_map_next = "warn" +flat_map_option = "warn" +float_cmp_const = "warn" +fn_params_excessive_bools = "warn" +from_iter_instead_of_collect = "warn" +if_same_then_else = "allow" +implicit_clone = "warn" +imprecise_flops = "warn" +inconsistent_struct_constructor = "warn" +inefficient_to_string = "warn" +infinite_loop = "warn" +invalid_upcast_comparisons = "warn" +items_after_statements = "warn" +large_digit_groups = "warn" +large_stack_arrays = "warn" +large_types_passed_by_value = "warn" +let_and_return = "allow" # sometimes good to name what you are returning +linkedlist = "warn" +lossy_float_literal = "warn" +macro_use_imports = "warn" +match_wildcard_for_single_variants = "warn" +mem_forget = "warn" +mutex_integer = "warn" +needless_continue = "warn" +needless_for_each = "warn" +negative_feature_names = "warn" +path_buf_push_overwrite = "warn" +ptr_as_ptr = "warn" +rc_mutex = "warn" +redundant_feature_names = "warn" +ref_option_ref = "warn" +rest_pat_in_fully_bound_structs = "warn" +same_functions_in_if_condition = "warn" +self_named_module_files = "warn" +semicolon_if_nothing_returned = "warn" +single_match_else = "warn" +str_to_string = "warn" +string_add = "warn" +string_add_assign = "warn" +string_lit_as_bytes = "warn" +string_to_string = "warn" +todo = "warn" +trait_duplication_in_bounds = "warn" +verbose_file_reads = "warn" +wildcard_imports = "warn" +zero_sized_map_values = "warn" + [package] name = "git-config-env" version = "0.2.1" @@ -45,3 +115,8 @@ pre-release-replacements = [ [dependencies] winnow = "0.6.0" itertools = "0.12" + +[dev-dependencies] + +[lints] +workspace = true diff --git a/src/env.rs b/src/env.rs index cb2d4fa..b73ddc9 100644 --- a/src/env.rs +++ b/src/env.rs @@ -52,7 +52,7 @@ impl<'e, E: Env> IntoIterator for &'e ConfigEnv { } } -impl std::iter::FromIterator<(K, V)> for ConfigEnv> +impl FromIterator<(K, V)> for ConfigEnv> where K: Into, V: Into, @@ -91,12 +91,12 @@ impl<'e, E: Env> Iterator for ConfigEnvIter<'e, E> { } } -/// Abstract over `std::env` for [ConfigEnv] +/// Abstract over `std::env` for [`ConfigEnv`] pub trait Env { fn var(&self, key: &str) -> Result, std::env::VarError>; } -/// Use `std::env::var` for [ConfigEnv] +/// Use `std::env::var` for [`ConfigEnv`] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct StdEnv; @@ -106,7 +106,7 @@ impl Env for StdEnv { } } -/// No-op env for [ConfigEnv] +/// No-op env for [`ConfigEnv`] #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] pub struct NoEnv; diff --git a/src/lib.rs b/src/lib.rs index 28fd130..8d6fd7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ //! Parse git's env configuration #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![warn(clippy::print_stderr)] +#![warn(clippy::print_stdout)] mod env; mod param; diff --git a/src/param.rs b/src/param.rs index 28b6d30..b7b510b 100644 --- a/src/param.rs +++ b/src/param.rs @@ -4,7 +4,7 @@ use std::borrow::Cow; /// /// These are the `-c` parameters, passed from the `git` process to the subcommand. /// -/// See [parse_parameter] for how to parse the `-c` parameter. +/// See [`parse_parameter`] for how to parse the `-c` parameter. #[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct ConfigParameters { values: String, @@ -34,7 +34,7 @@ impl<'s> IntoIterator for &'s ConfigParameters { /// /// These are the `-c` parameters, passed from the `git` process to the subcommand. /// -/// See [parse_parameter] for how to parse the `-c` parameter. +/// See [`parse_parameter`] for how to parse the `-c` parameter. #[derive(Clone, Default, Debug, PartialEq, Eq)] pub struct ConfigParametersIter<'s> { values: &'s str, @@ -45,7 +45,7 @@ impl<'s> ConfigParametersIter<'s> { Self { values } } - pub fn iter(&self) -> impl Iterator, Cow)> + '_ { + pub fn iter(&self) -> impl Iterator, Cow<'_, str>)> + '_ { None.into_iter() } } @@ -216,7 +216,7 @@ pub fn parse_parameter(arg: &str) -> (&str, Option<&str>) { .unwrap_or((arg, None)) } -fn parse_parameter_cow(arg: Cow) -> (Cow, Option>) { +fn parse_parameter_cow(arg: Cow<'_, str>) -> (Cow<'_, str>, Option>) { match arg { Cow::Borrowed(arg) => { let (key, value) = parse_parameter(arg); diff --git a/src/quote.rs b/src/quote.rs index e68c71b..13b3212 100644 --- a/src/quote.rs +++ b/src/quote.rs @@ -1,9 +1,9 @@ use std::borrow::Cow; use itertools::Itertools; -use winnow::combinator::*; -use winnow::prelude::*; -use winnow::token::*; +use winnow::combinator::{alt, preceded, repeat, terminated}; +use winnow::prelude::{PResult, Parser}; +use winnow::token::{one_of, take_while}; #[derive(Debug)] pub struct QuoteError; @@ -81,7 +81,7 @@ mod test_sq_dequote_step { #[test] fn sq_escaped() { let fixture = "'a'\\''b'"; - let expected: Cow = Cow::Owned("a'b".into()); + let expected: Cow<'_, str> = Cow::Owned("a'b".into()); let (_, actual) = sq_dequote.parse_peek(fixture).unwrap(); assert_eq!(actual, expected); } @@ -89,7 +89,7 @@ mod test_sq_dequote_step { #[test] fn exclamation_escaped() { let fixture = "'a'\\!'b'"; - let expected: Cow = Cow::Owned("a!b".into()); + let expected: Cow<'_, str> = Cow::Owned("a!b".into()); let (_, actual) = sq_dequote.parse_peek(fixture).unwrap(); assert_eq!(actual, expected); }