From f26df422b47f55083a4d70185b47cb4602f292e3 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Thu, 31 Oct 2024 11:00:40 +0000 Subject: [PATCH] ci: split up CI jobs (#52) --- .github/workflows/ci.yml | 57 +++++++++++++ .github/workflows/coverage.yml | 39 +++++++++ .github/workflows/lint.yml | 84 +++++++++++++++++++ .github/workflows/rust.yml | 70 ---------------- Cargo.toml | 14 ++-- Makefile | 8 -- README.md | 147 ++++++++++++++++----------------- justfile | 64 ++++++++++++++ src/lib.rs | 1 + 9 files changed, 321 insertions(+), 163 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/rust.yml delete mode 100644 Makefile create mode 100644 justfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c3e6361 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,57 @@ +name: CI + +on: + pull_request: + types: [opened, synchronize, reopened] + merge_group: + types: [checks_requested] + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + read_msrv: + name: Read MSRV + uses: actions-rust-lang/msrv/.github/workflows/msrv.yml@v0.1.0 + + rust: + needs: read_msrv + + strategy: + fail-fast: false + matrix: + os: + - { name: Linux, runner: ubuntu-latest } + - { name: macOS, runner: macos-latest } + - { name: Windows, runner: windows-latest } + toolchain: + - { name: stable, version: stable } + - { name: msrv, version: "${{ needs.read_msrv.outputs.msrv }}" } + + name: ${{ matrix.os.name }} / ${{ matrix.toolchain.name }} + runs-on: ${{ matrix.os.runner }} + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust (${{ matrix.toolchain.name }}) + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + toolchain: ${{ matrix.toolchain.version }} + + - name: Install just, nextest + uses: taiki-e/install-action@v2.44.25 + with: + tool: just,nextest + + - name: Test + run: just test diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..fce2a78 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,39 @@ +name: Coverage + +on: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: llvm-tools-preview + + - name: Install just & cargo-llvm-cov + uses: taiki-e/install-action@v2.44.5 + with: + tool: just,cargo-llvm-cov + + - name: Generate code coverage + run: just test-coverage-codecov + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4.5.0 + with: + files: codecov.json + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..66e397c --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,84 @@ +name: Lint + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + clippy: + runs-on: ubuntu-latest + + permissions: + contents: read + checks: write + + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: clippy + + - name: Install just, cargo-hack + uses: taiki-e/install-action@v2.44.25 + with: + tool: just,cargo-hack + + - name: Check with Clippy + run: just clippy + + rustfmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust (nightly) + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + toolchain: nightly + components: rustfmt + + - name: Check with Rustfmt + run: cargo fmt -- --check + + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust (nightly) + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + toolchain: nightly + components: rust-docs + + - name: Check for broken intra-doc links + env: + RUSTDOCFLAGS: -D warnings + run: cargo doc --workspace --no-deps --all-features + + sorted-deps: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.10.1 + with: + components: clippy + + - name: Install just, cargo-sort + uses: taiki-e/install-action@v2.44.25 + with: + tool: just,cargo-sort + + - name: Check dependency requirements are sorted lexicographically + run: cargo sort --workspace --check diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 450cb71..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Rust - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -env: - CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240821 - -jobs: - rust: - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.81.0] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust_toolchain }} - components: rustfmt, clippy, llvm-tools-preview - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-test - - name: Install cargo tools - if: steps.cache.outputs.cache-hit != 'true' - run: | - cargo install cargo-sort --locked - - name: Run rust cargo-sort check - # https://github.com/DevinR528/cargo-sort/issues/56 - if: matrix.os != 'windows-latest' - run: | - cargo sort -w -c - - name: Run rust format check - run: | - cargo fmt --all -- --check - - name: Run rust clippy check - run: | - cargo clippy --all-features -- -D warnings - - if: steps.cache.outputs.cache-hit != 'true' - uses: taiki-e/install-action@cargo-llvm-cov - - name: Run rust test with coverage - env: - RUST_BACKTRACE: 1 - run: | - cargo llvm-cov test --all-features - - name: Run rust doc test - env: - RUST_BACKTRACE: 1 - run: | - cargo test --doc --all-features - - uses: codecov/codecov-action@v4 - if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - verbose: true \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index d823249..d6c45fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,14 @@ [package] name = "bytesize" -description = "A utility for human-readable bytes representations. Forked from https://github.com/hyunsik/bytesize ." -version = "1.4.0-dev" +description = "A utility for human-readable byte count representations" +version = "1.3.0" authors = ["Hyunsik Choi ", "MrCroxx "] -edition = "2021" - -homepage = "https://github.com/hyunsik/bytesize/" -documentation = "https://docs.rs/bytesize/" -repository = "https://github.com/hyunsik/bytesize/" -readme = "README.md" keywords = ["byte", "byte-size", "utility", "human-readable", "format"] +categories = ["development-tools", "filesystem"] +repository = "https://github.com/hyunsik/bytesize" license = "Apache-2.0" +edition = "2021" +rust-version = "1.65" [dependencies] arbitrary = { version = "1", features = ["derive"], optional = true } diff --git a/Makefile b/Makefile deleted file mode 100644 index bb8c02e..0000000 --- a/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -SHELL := /bin/bash -.PHONY: all - -all: - cargo sort -w - cargo fmt --all - cargo clippy --all-features - RUST_BACKTRACE=1 cargo test --all-features diff --git a/README.md b/README.md index 965d7ed..8199bc9 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,90 @@ ## ByteSize -[![CI](https://github.com/hyunsik/bytesize/actions/workflows/rust.yml/badge.svg)](https://github.com/hyunsik/bytesize/actions/workflows/rust.yml) +[![CI](https://github.com/hyunsik/bytesize/actions/workflows/ci.yml/badge.svg)](https://github.com/hyunsik/bytesize/actions/workflows/ci.yml) [![Crates.io Version](https://img.shields.io/crates/v/bytesize.svg)](https://crates.io/crates/bytesize) -ByteSize is an utility for human-readable byte count representation. +`ByteSize` is a utility for human-readable byte count representations. Features: -* Pre-defined constants for various size units (e.g., B, Kb, Kib, Mb, Mib, Gb, Gib, ... PB) -* `ByteSize` type which presents size units convertible to different size units. -* Artimetic operations for `ByteSize` -* FromStr impl for `ByteSize`, allowing to parse from string size representations like 1.5KiB and 521TiB. -* Serde support for binary and human-readable deserializers like JSON -[API Documentation](https://docs.rs/bytesize/) +- Pre-defined constants for various size units (e.g., B, Kb, Kib, Mb, Mib, Gb, Gib, ... PB). +- `ByteSize` type which presents size units convertible to different size units. +- Arithmetic operations for `ByteSize`. +- FromStr impl for `ByteSize`, allowing to parse from string size representations like 1.5KiB and 521TiB. +- Serde support for binary and human-readable deserializers like JSON. -## Usage - -Add this to your Cargo.toml: - -```toml -[dependencies] -bytesize = { version = "1.3.0", features = ["serde"]} -``` +[API Documentation](https://docs.rs/bytesize) ## Example ### Human readable representations (SI unit and Binary unit) ```rust - fn assert_display(expected: &str, b: ByteSize) { - assert_eq!(expected, format!("{}", b)); - } - - #[test] - fn test_display() { - assert_display("215 B", ByteSize::b(215)); - assert_display("1.0 KiB", ByteSize::kib(1)); - assert_display("301.0 KiB", ByteSize::kib(301)); - assert_display("419.0 MiB", ByteSize::mib(419)); - assert_display("518.0 GiB", ByteSize::gib(518)); - assert_display("815.0 TiB", ByteSize::tib(815)); - assert_display("609.0 PiB", ByteSize::pib(609)); - } - - #[test] - fn test_display_alignment() { - assert_eq!("|357 B |", format!("|{:10}|", ByteSize(357))); - assert_eq!("| 357 B|", format!("|{:>10}|", ByteSize(357))); - assert_eq!("|357 B |", format!("|{:<10}|", ByteSize(357))); - assert_eq!("| 357 B |", format!("|{:^10}|", ByteSize(357))); - - assert_eq!("|-----357 B|", format!("|{:->10}|", ByteSize(357))); - assert_eq!("|357 B-----|", format!("|{:-<10}|", ByteSize(357))); - assert_eq!("|--357 B---|", format!("|{:-^10}|", ByteSize(357))); - } - - fn assert_to_string(expected: &str, b: ByteSize, si: bool) { - assert_eq!(expected.to_string(), b.to_string_as(si)); - } - - #[test] - fn test_to_string_as() { - assert_to_string("215 B", ByteSize::b(215), true); - assert_to_string("215 B", ByteSize::b(215), false); - - assert_to_string("1.0 KiB", ByteSize::kib(1), true); - assert_to_string("1.0 KB", ByteSize::kib(1), false); - - assert_to_string("293.9 KiB", ByteSize::kb(301), true); - assert_to_string("301.0 KB", ByteSize::kb(301), false); - - assert_to_string("1.0 MiB", ByteSize::mib(1), true); - assert_to_string("1048.6 KB", ByteSize::mib(1), false); - - // a bug case: https://github.com/flang-project/bytesize/issues/8 - assert_to_string("1.9 GiB", ByteSize::mib(1907), true); - assert_to_string("2.0 GB", ByteSize::mib(1908), false); - - assert_to_string("399.6 MiB", ByteSize::mb(419), true); - assert_to_string("419.0 MB", ByteSize::mb(419), false); - - assert_to_string("482.4 GiB", ByteSize::gb(518), true); - assert_to_string("518.0 GB", ByteSize::gb(518), false); - - assert_to_string("741.2 TiB", ByteSize::tb(815), true); - assert_to_string("815.0 TB", ByteSize::tb(815), false); - - assert_to_string("540.9 PiB", ByteSize::pb(609), true); - assert_to_string("609.0 PB", ByteSize::pb(609), false); - } +fn assert_display(expected: &str, b: ByteSize) { + assert_eq!(expected, format!("{}", b)); +} + +#[test] +fn test_display() { + assert_display("215 B", ByteSize::b(215)); + assert_display("1.0 KiB", ByteSize::kib(1)); + assert_display("301.0 KiB", ByteSize::kib(301)); + assert_display("419.0 MiB", ByteSize::mib(419)); + assert_display("518.0 GiB", ByteSize::gib(518)); + assert_display("815.0 TiB", ByteSize::tib(815)); + assert_display("609.0 PiB", ByteSize::pib(609)); +} + +#[test] +fn test_display_alignment() { + assert_eq!("|357 B |", format!("|{:10}|", ByteSize(357))); + assert_eq!("| 357 B|", format!("|{:>10}|", ByteSize(357))); + assert_eq!("|357 B |", format!("|{:<10}|", ByteSize(357))); + assert_eq!("| 357 B |", format!("|{:^10}|", ByteSize(357))); + + assert_eq!("|-----357 B|", format!("|{:->10}|", ByteSize(357))); + assert_eq!("|357 B-----|", format!("|{:-<10}|", ByteSize(357))); + assert_eq!("|--357 B---|", format!("|{:-^10}|", ByteSize(357))); +} + +fn assert_to_string(expected: &str, b: ByteSize, si: bool) { + assert_eq!(expected.to_string(), b.to_string_as(si)); +} + +#[test] +fn test_to_string_as() { + assert_to_string("215 B", ByteSize::b(215), true); + assert_to_string("215 B", ByteSize::b(215), false); + + assert_to_string("1.0 KiB", ByteSize::kib(1), true); + assert_to_string("1.0 KB", ByteSize::kib(1), false); + + assert_to_string("293.9 KiB", ByteSize::kb(301), true); + assert_to_string("301.0 KB", ByteSize::kb(301), false); + + assert_to_string("1.0 MiB", ByteSize::mib(1), true); + assert_to_string("1048.6 KB", ByteSize::mib(1), false); + + // a bug case: https://github.com/flang-project/bytesize/issues/8 + assert_to_string("1.9 GiB", ByteSize::mib(1907), true); + assert_to_string("2.0 GB", ByteSize::mib(1908), false); + + assert_to_string("399.6 MiB", ByteSize::mb(419), true); + assert_to_string("419.0 MB", ByteSize::mb(419), false); + + assert_to_string("482.4 GiB", ByteSize::gb(518), true); + assert_to_string("518.0 GB", ByteSize::gb(518), false); + + assert_to_string("741.2 TiB", ByteSize::tb(815), true); + assert_to_string("815.0 TB", ByteSize::tb(815), false); + + assert_to_string("540.9 PiB", ByteSize::pb(609), true); + assert_to_string("609.0 PB", ByteSize::pb(609), false); +} ``` ### Arithmetic operations + ```rust use bytesize::ByteSize; diff --git a/justfile b/justfile new file mode 100644 index 0000000..8fec6df --- /dev/null +++ b/justfile @@ -0,0 +1,64 @@ +_list: + @just --list + +msrv := ``` + cargo metadata --format-version=1 \ + | jq -r 'first(.packages[] | select(.source == null and .rust_version)) | .rust_version' \ + | sed -E 's/^1\.([0-9]{2})$/1\.\1\.0/' +``` +msrv_rustup := "+" + msrv + +# Check project. +[group("lint")] +check: && clippy + just --unstable --fmt --check + # fd --hidden -e=toml --exec-batch taplo format --check + # fd --hidden -e=toml --exec-batch taplo lint + # fd --hidden --type=file -e=md -e=yml --exec-batch prettier --check + cargo +nightly fmt -- --check + +# Format project. +[group("lint")] +fmt: + just --unstable --fmt + # fd --hidden -e=toml --exec-batch taplo format + # fd --hidden --type=file -e=md -e=yml --exec-batch prettier --write + cargo +nightly fmt + +# Lint workspace with Clippy. +[group("lint")] +clippy: + cargo clippy --workspace --all-targets --no-default-features + cargo clippy --workspace --all-targets --all-features + +# Test workspace. +[group("test")] +test toolchain="": + cargo {{ toolchain }} nextest run --workspace --no-default-features + cargo {{ toolchain }} nextest run --workspace --all-features + cargo {{ toolchain }} test --doc --workspace --all-features + RUSTDOCFLAGS="-D warnings" cargo {{ toolchain }} doc --workspace --no-deps --all-features + +# Downgrade dev-dependencies necessary to run MSRV checks/tests. +[private] +downgrade-msrv: + # "No MSRV downgrades currently necessary" + +# Test workspace using MSRV. +[group("test")] +test-msrv: downgrade-msrv (test msrv_rustup) + +# Test workspace and generate Codecov coverage file +[group("test")] +test-coverage-codecov toolchain="": + cargo {{ toolchain }} llvm-cov --workspace --all-features --codecov --output-path codecov.json + +# Test workspace and generate LCOV coverage file +[group("test")] +test-coverage-lcov toolchain="": + cargo {{ toolchain }} llvm-cov --workspace --all-features --lcov --output-path lcov.info + +# Document crates in workspace. +[group("docs")] +doc *args: + RUSTDOCFLAGS="--cfg=docsrs -Dwarnings" cargo +nightly doc --workspace --all-features {{ args }} diff --git a/src/lib.rs b/src/lib.rs index 2b92059..5d04d38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -390,6 +390,7 @@ mod tests { assert_eq!(x.as_u64(), 2_200_000); } + #[allow(clippy::unnecessary_cast)] #[test] fn test_arithmetic_primitives() { let mut x = ByteSize::mb(1);