diff --git a/.clippy.toml b/.clippy.toml index e88edc91..1d4c5dc6 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1,5 +1,4 @@ -msrv = "1.70.0" # 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 24414f38..c1844208 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: '252 days', // 6 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 d70ff498..6c1a79c6 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -48,14 +48,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 ccee1fef..07c70eeb 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 7611247c..95b13b4f 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.70.0" + 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.70" # 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.70" # 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 04625584..e7a50fbb 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 6eb6ca19..1b000abf 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 a442b177..1cb2ec2d 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 12f75859..8e58d9ec 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.lock b/Cargo.lock index d8098f26..eb5c5631 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "automod" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf3ee19dbc0a46d740f6f0926bde8c50f02bdbc7b536842da28f6ac56513a8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.63", +] + [[package]] name = "backtrace" version = "0.3.66" @@ -178,7 +189,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.99", ] [[package]] @@ -625,7 +636,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.99", "version_check", ] @@ -642,18 +653,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.43" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -779,7 +790,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.99", ] [[package]] @@ -805,7 +816,7 @@ checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.99", ] [[package]] @@ -816,7 +827,7 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.99", ] [[package]] @@ -858,6 +869,7 @@ dependencies = [ "anstream", "anstyle", "anstyle-svg", + "automod", "backtrace", "content_inspector", "document-features", @@ -902,6 +914,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -970,6 +993,7 @@ name = "trycmd" version = "0.15.1" dependencies = [ "anstream", + "automod", "escargot", "glob", "humantime", diff --git a/Cargo.toml b/Cargo.toml index 906867b5..d005b7a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,75 @@ 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" +# 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 = "trycmd" version = "0.15.1" @@ -65,6 +134,7 @@ name = "trycmd-schema" required-features = ["schema"] [dependencies] +automod = "1.0.14" snapbox = { path = "crates/snapbox", version = "0.5.9", default-features = false, features = ["cmd"] } anstream = { version = "0.6.7", optional = true } @@ -80,3 +150,6 @@ escargot = { version = "0.5.7", optional = true } schemars = { version = "0.8.3", features = ["preserve_order"], optional = true } serde_json = { version = "1.0", optional = true } + +[lints] +workspace = true diff --git a/crates/snapbox-macros/Cargo.toml b/crates/snapbox-macros/Cargo.toml index 9b34b223..4477e09e 100644 --- a/crates/snapbox-macros/Cargo.toml +++ b/crates/snapbox-macros/Cargo.toml @@ -25,3 +25,6 @@ debug = [] [dependencies] anstream = { version = "0.6.7", optional = true } + +[lints] +workspace = true diff --git a/crates/snapbox-macros/src/lib.rs b/crates/snapbox-macros/src/lib.rs index 1bc98f7b..2eddb8fd 100644 --- a/crates/snapbox-macros/src/lib.rs +++ b/crates/snapbox-macros/src/lib.rs @@ -1,4 +1,6 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![warn(clippy::print_stderr)] +#![warn(clippy::print_stdout)] #[cfg(feature = "color")] pub use anstream::eprint; diff --git a/crates/snapbox/Cargo.toml b/crates/snapbox/Cargo.toml index 46ac93e6..63db1805 100644 --- a/crates/snapbox/Cargo.toml +++ b/crates/snapbox/Cargo.toml @@ -101,6 +101,12 @@ windows-sys = { version = "0.52.0", features = ["Win32_Foundation"], optional = [target.'cfg(unix)'.dependencies] libc = { version = "0.2.137", optional = true } +[dev-dependencies] +automod = "1.0.14" + [[example]] name = "diff" required-features = ["diff"] + +[lints] +workspace = true diff --git a/crates/snapbox/src/lib.rs b/crates/snapbox/src/lib.rs index 561d2a0a..ce9fb75b 100644 --- a/crates/snapbox/src/lib.rs +++ b/crates/snapbox/src/lib.rs @@ -92,6 +92,8 @@ //! [trycmd]: https://docs.rs/trycmd #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![warn(clippy::print_stderr)] +#![warn(clippy::print_stdout)] mod action; mod assert; diff --git a/crates/snapbox/tests/assert.rs b/crates/snapbox/tests/testsuite/assert.rs similarity index 86% rename from crates/snapbox/tests/assert.rs rename to crates/snapbox/tests/testsuite/assert.rs index 82dcc6c1..4c9bad6d 100644 --- a/crates/snapbox/tests/assert.rs +++ b/crates/snapbox/tests/testsuite/assert.rs @@ -36,5 +36,5 @@ line1 #[test] fn test_expect_file() { - assert_eq(file!["../README.md"], include_str!("../README.md")) + assert_eq(file!["../../README.md"], include_str!("../../README.md")) } diff --git a/crates/snapbox/tests/cmd.rs b/crates/snapbox/tests/testsuite/cmd.rs similarity index 100% rename from crates/snapbox/tests/cmd.rs rename to crates/snapbox/tests/testsuite/cmd.rs diff --git a/crates/snapbox/tests/testsuite/main.rs b/crates/snapbox/tests/testsuite/main.rs new file mode 100644 index 00000000..44413747 --- /dev/null +++ b/crates/snapbox/tests/testsuite/main.rs @@ -0,0 +1 @@ +automod::dir!("tests/testsuite"); diff --git a/src/lib.rs b/src/lib.rs index a74e572d..70d9848a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -226,10 +226,8 @@ //! [commandspec]: https://crates.io/crates/commandspec #![cfg_attr(docsrs, feature(doc_auto_cfg))] -// Doesn't distinguish between incidental sharing vs essential sharing -#![allow(clippy::branches_sharing_code)] -// Forces indentation that may not represent the logic -#![allow(clippy::collapsible_else_if)] +#![warn(clippy::print_stderr)] +#![warn(clippy::print_stdout)] pub mod cargo; pub mod schema; diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs new file mode 100644 index 00000000..44413747 --- /dev/null +++ b/tests/testsuite/main.rs @@ -0,0 +1 @@ +automod::dir!("tests/testsuite"); diff --git a/tests/schema.rs b/tests/testsuite/schema.rs similarity index 77% rename from tests/schema.rs rename to tests/testsuite/schema.rs index e462c4a7..72de3899 100644 --- a/tests/schema.rs +++ b/tests/testsuite/schema.rs @@ -5,5 +5,5 @@ fn dump_schema() { snapbox::cmd::Command::new(bin_path) .assert() .success() - .stdout_eq(snapbox::file!["../schema.json"]); + .stdout_eq(snapbox::file!["../../schema.json"]); }