diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..ea4b9e5 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,8 @@ +# See https://help.github.com/articles/about-codeowners/ +# for more info about CODEOWNERS file + +# It uses the same pattern rule for gitignore file +# https://git-scm.com/docs/gitignore#_pattern_format + +# Core +* @nsyzrantsev \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..35695cf --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: + # Maintain dependencies for Cargo + - package-ecosystem: cargo + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + + # Maintain dependencies for GitHub Actions + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 + groups: + minor: + update-types: + - "minor" + patch: + update-types: + - "patch" \ No newline at end of file diff --git a/.github/mergify.yml b/.github/mergify.yml new file mode 100644 index 0000000..ff93477 --- /dev/null +++ b/.github/mergify.yml @@ -0,0 +1,7 @@ +pull_request_rules: + - name: Automatic merge for Dependabot pull requests + conditions: + - author=dependabot[bot] + actions: + merge: + method: squash \ No newline at end of file diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..7d6b881 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,234 @@ +name: Continuous Deployment + +on: + push: + tags: + - "v*.*.*" + +jobs: + generate-changelog: + name: Generate changelog + runs-on: ubuntu-22.04 + outputs: + release_body: ${{ steps.git-cliff.outputs.content }} + steps: + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install git-cliff + uses: actions-rs/cargo@v1 + id: git-cliff + with: + command: install + args: git-cliff + - name: Run git-cliff to generate changelog + run: git-cliff -vv --latest --no-exec --github-repo ${{ github.repository }} --config cliff.toml + id: barkit + + publish-binaries: + name: Publish binaries + needs: generate-changelog + runs-on: ${{ matrix.build.os }} + strategy: + fail-fast: false + matrix: + build: + - { + NAME: linux-x64-glibc, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: x86_64-unknown-linux-gnu, + NPM_PUBLISH: true, + } + - { + NAME: linux-x64-musl, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: x86_64-unknown-linux-musl, + NPM_PUBLISH: false, + } + - { + NAME: linux-x86-glibc, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: i686-unknown-linux-gnu, + NPM_PUBLISH: false, + } + - { + NAME: linux-x86-musl, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: i686-unknown-linux-musl, + NPM_PUBLISH: false, + } + - { + NAME: linux-arm64-glibc, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: aarch64-unknown-linux-gnu, + NPM_PUBLISH: true, + } + - { + NAME: linux-arm64-musl, + OS: ubuntu-22.04, + TOOLCHAIN: stable, + TARGET: aarch64-unknown-linux-musl, + NPM_PUBLISH: false, + } + - { + NAME: win32-x64-mingw, + OS: windows-2022, + TOOLCHAIN: stable, + TARGET: x86_64-pc-windows-gnu, + NPM_PUBLISH: false, + } + - { + NAME: win32-x64-msvc, + OS: windows-2022, + TOOLCHAIN: stable, + TARGET: x86_64-pc-windows-msvc, + NPM_PUBLISH: true, + } + - { + NAME: win32-x86-msvc, + OS: windows-2022, + TOOLCHAIN: stable, + TARGET: i686-pc-windows-msvc, + NPM_PUBLISH: false, + } + - { + NAME: win32-arm64-msvc, + OS: windows-2022, + TOOLCHAIN: stable, + TARGET: aarch64-pc-windows-msvc, + NPM_PUBLISH: true, + } + - { + NAME: darwin-x64, + OS: macos-14, + TOOLCHAIN: stable, + TARGET: x86_64-apple-darwin, + NPM_PUBLISH: true, + } + - { + NAME: darwin-arm64, + OS: macos-14, + TOOLCHAIN: stable, + TARGET: aarch64-apple-darwin, + NPM_PUBLISH: true, + } + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set the release version + shell: bash + run: echo "RELEASE_VERSION=${GITHUB_REF:11}" >> "$GITHUB_ENV" + - name: Install dependencies + shell: bash + run: | + if [[ "${{ matrix.build.NAME }}" == *"-musl" ]]; then + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + --allow-unauthenticated musl-tools + fi + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.build.TOOLCHAIN }} + target: ${{ matrix.build.TARGET }} + override: true + - name: Build (linux/macos) + if: matrix.build.OS != 'windows-2022' + uses: actions-rs/cargo@v1 + with: + use-cross: true + command: build + args: --release --locked --target ${{ matrix.build.TARGET }} + - name: Build (windows) + if: matrix.build.OS == 'windows-2022' + uses: actions-rs/cargo@v1 + with: + command: build + args: --release --locked --target ${{ matrix.build.TARGET }} # --no-default-features + - name: Prepare release assets + shell: bash + run: | + mkdir -p release/ + cp {LICENSE,README.md,CHANGELOG.md} release/ + for bin in 'barkit'; do + if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then + bin="${bin}.exe" + fi + cp "target/${{ matrix.build.TARGET }}/release/${bin}" release/ + done + mv release/ barkit-${{ env.RELEASE_VERSION }}/ + - name: Create release artifacts + shell: bash + run: | + if [ "${{ matrix.build.OS }}" = "windows-2022" ]; then + 7z a -tzip "barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}.zip" \ + barkit-${{ env.RELEASE_VERSION }}/ + else + tar -czvf barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}.tar.gz \ + barkit-${{ env.RELEASE_VERSION }}/ + shasum -a 512 barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}.tar.gz \ + > barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}.tar.gz.sha512 + fi + - name: Sign the release + if: matrix.build.OS == 'ubuntu-22.04' || matrix.build.OS == 'macos-14' + run: | + echo "${{ secrets.GPG_RELEASE_KEY }}" | base64 --decode > private.key + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --pinentry-mode=loopback \ + --passphrase-fd 0 --import private.key + echo "${{ secrets.GPG_PASSPHRASE }}" | gpg --pinentry-mode=loopback \ + --passphrase-fd 0 --detach-sign \ + barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}.tar.gz + - name: Publish to GitHub + if: ${{ !contains(github.ref, '-') }} + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.API_TOKEN }} + file: barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}* + file_glob: true + overwrite: true + tag: ${{ github.ref }} + release_name: "Release v${{ env.RELEASE_VERSION }}" + body: "${{ needs.generate-changelog.outputs.release_body }}" + - name: Publish to GitHub (pre-release) + if: ${{ contains(github.ref, '-') }} + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.API_TOKEN }} + file: barkit-${{ env.RELEASE_VERSION }}-${{ matrix.build.TARGET }}* + file_glob: true + overwrite: true + tag: ${{ github.ref }} + release_name: "Pre-release v${{ env.RELEASE_VERSION }}" + prerelease: true + + publish-crates-io: + name: Publish on crates.io + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set the release version + run: echo "RELEASE_VERSION=${GITHUB_REF:11}" >> "$GITHUB_ENV" + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-unknown-linux-gnu + - name: Publish the barkit-extract binary + run: | + cargo publish --manifest-path barkit-extract/Cargo.toml \ + --locked --token ${{ secrets.CARGO_REGISTRY_TOKEN }} + - name: Publish the barkit binary + run: | + cargo publish --manifest-path Cargo.toml \ + --locked --token ${{ secrets.CARGO_REGISTRY_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1b4ffa1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,128 @@ +name: Continuous Integration + +on: + pull_request: + push: + branches: + - main + schedule: + - cron: "0 0 * * 0" + +permissions: + pull-requests: write + +jobs: + check: + name: Check + runs-on: ubuntu-22.04 + steps: + - name: Install toolchain + uses: dtolnay/rust-toolchain@stable + - name: Checkout + uses: actions/checkout@v4 + - name: Check + uses: actions-rs/cargo@v1 + with: + command: check + args: --locked --verbose + - name: Check without default features + uses: actions-rs/cargo@v1 + with: + command: check + args: --locked --no-default-features --verbose + + typos: + name: Typos + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Check typos + uses: crate-ci/typos@master + + test: + name: Test suite + runs-on: ubuntu-22.04 + steps: + - name: Install toolchain + uses: dtolnay/rust-toolchain@nightly + - name: Checkout + if: github.event_name != 'pull_request' + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Checkout + if: github.event_name == 'pull_request' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: Setup cargo-tarpaulin + uses: taiki-e/install-action@cargo-tarpaulin + - name: Run tests + run: | + cargo test --all --no-default-features \ + -- --skip "repo::test::git_upstream_remote" + - name: Run tests + run: | + cargo tarpaulin --out xml --verbose --all-features \ + -- --skip "repo::test::git_upstream_remote" + - name: Upload reports to codecov + uses: codecov/codecov-action@v4 + with: + name: code-coverage-report + file: cobertura.xml + flags: unit-tests + fail_ci_if_error: true + verbose: true + token: ${{ secrets.CODECOV_TOKEN }} + + clippy: + name: Lints + runs-on: ubuntu-22.04 + steps: + - name: Install toolchain + uses: dtolnay/rust-toolchain@nightly + with: + components: clippy + - name: Checkout + uses: actions/checkout@v4 + - name: Check the lints + uses: actions-rs/cargo@v1 + with: + command: clippy + args: --tests --verbose -- -D warnings + + rustfmt: + name: Formatting + runs-on: ubuntu-22.04 + steps: + - name: Install toolchain + uses: dtolnay/rust-toolchain@nightly + with: + components: rustfmt + - name: Checkout + uses: actions/checkout@v4 + - name: Check the formatting + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check --verbose + + msrv: + name: Check Rust version + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install cargo-binstall + uses: taiki-e/install-action@cargo-binstall + - name: Install cargo-msrv + run: cargo binstall -y cargo-msrv + - name: Run cargo-msrv + shell: bash + run: | + for package in barkit-extract; do + printf "Checking MSRV for %s..." "$package" + cargo msrv --output-format json --path "$package" verify | tail -n 1 | jq --exit-status '.success' + done \ No newline at end of file diff --git a/.gitignore b/.gitignore index 196e176..a3040a7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,6 @@ debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a26daed --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1117 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "barkit" +version = "0.1.0" +dependencies = [ + "barkit-extract", + "clap", +] + +[[package]] +name = "barkit-extract" +version = "0.1.0" +dependencies = [ + "clap", + "console", + "fancy-regex", + "flate2", + "gzp", + "indicatif", + "lz4", + "rayon", + "regex", + "rstest", + "seq_io", + "thiserror", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "buffer-redux" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8acf87c5b9f5897cd3ebb9a327f420e0cae9dd4e5c1d2e36f2c84c571a58f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" + +[[package]] +name = "cc" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys", +] + +[[package]] +name = "core_affinity" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622892f5635ce1fc38c8f16dfc938553ed64af482edb5e150bf4caedbfcb2304" +dependencies = [ + "libc", + "num_cpus", + "winapi", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fancy-regex" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +dependencies = [ + "bit-set", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "libz-sys", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gzp" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c65d1899521a11810501b50b898464d133e1afc96703cff57726964cfa7baf" +dependencies = [ + "byteorder", + "bytes", + "core_affinity", + "flate2", + "flume", + "libdeflater", + "libz-sys", + "num_cpus", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "libdeflate-sys" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f7b0817f85e2ba608892f30fbf4c9d03f3ebf9db0c952d1b7c8f7387b54785" +dependencies = [ + "cc", +] + +[[package]] +name = "libdeflater" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671e63282f642c7bcc7d292b212d5a4739fef02a77fe98429a75d308f96e7931" +dependencies = [ + "libdeflate-sys", +] + +[[package]] +name = "libz-sys" +version = "1.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" +dependencies = [ + "cc", + "cmake", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lz4" +version = "1.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958b4caa893816eea05507c20cfe47574a43d9a697138a7872990bba8a0ece68" +dependencies = [ + "libc", + "lz4-sys", +] + +[[package]] +name = "lz4-sys" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "portable-atomic" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b423f0e62bdd61734b67cd21ff50871dfaeb9cc74f869dcd6af974fbcb19936" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e1711e7d14f74b12a58411c542185ef7fb7f2e7f8ee6e2940a883628522b42" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "seq_io" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b213fabdebb1c56d330d1dbf92cef0257f3873b718eb2202bb73c707197e9c" +dependencies = [ + "buffer-redux", + "crossbeam-utils", + "memchr", + "scoped_threadpool", + "serde", + "serde_derive", +] + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index a4477c3..da0ab88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,23 @@ [package] name = "barkit" -version = "0.1.0" +version = "0.1.0" # managed by release.sh edition = "2021" +authors = ["Nikita Syzrantsev syzrantsev.n@yandex.ru"] +description = "Tool to process barcodes in FASTQ" +license = "GPL-3.0" +readme = "README.md" +homepage = "https://github.com/nsyzrantsev/barkit" +repository = "https://github.com/nsyzrantsev/barkit" +keywords = ["bioinformatics", "sequencing", "barcodes"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [workspace] -members = ["extract"] +members = ["barkit-extract"] [dependencies] clap = { version = "4.5.4", features = ["env", "derive"] } -extract = { path = "extract" } +barkit-extract = { version = "0.1.0", path = "barkit-extract" } [profile.dev] opt-level = 0 diff --git a/README.md b/README.md index d37e05e..8b04636 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,10 @@ BarKit (Barcodes Toolkit) is a toolkit designed for manipulating FASTQ barcodes. -## Building from Source +## Installation ```bash -cargo build --release -sudo mv barkit /usr/local/bin/ +cargo install barkit ``` ## Extract Command diff --git a/barkit-extract/Cargo.toml b/barkit-extract/Cargo.toml new file mode 100644 index 0000000..8d4a3b1 --- /dev/null +++ b/barkit-extract/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "barkit-extract" +version = "0.1.0" # managed by release.sh +edition = "2021" +authors = ["Nikita Syzrantsev syzrantsev.n@yandex.ru"] +description = "Tool to extract barcodes" +license = "GPL-3.0" +readme = "../README.md" +homepage = "https://github.com/nsyzrantsev/barkit" +repository = "https://github.com/nsyzrantsev/barkit" +keywords = ["bioinformatics", "sequencing", "barcodes"] +rust-version = "1.80.0" + +[dependencies] +clap = { version = "4.5.4", features = ["derive", "env"] } +flate2 = "1.0.30" +regex = "1.10.4" +seq_io = "0.3.2" +thiserror = "1.0.61" +rayon = "1.10.0" +fancy-regex = "0.13.0" +lz4 = "1.26.0" +gzp = "0.11.3" +indicatif = "0.17.8" +console = "0.15.8" + +[dev-dependencies] +rstest = "0.22.0" diff --git a/extract/src/barcode.rs b/barkit-extract/src/barcode.rs similarity index 97% rename from extract/src/barcode.rs rename to barkit-extract/src/barcode.rs index 381404d..c332523 100644 --- a/extract/src/barcode.rs +++ b/barkit-extract/src/barcode.rs @@ -33,7 +33,7 @@ const TRANSLATION_TABLE: [u8; 256] = { pub enum BarcodeType { Umi, Sample, - Cell + Cell, } impl fmt::Display for BarcodeType { @@ -84,7 +84,12 @@ impl BarcodeRegex { fn parse_capture_groups(regex: &Regex) -> Result, Error> { let mut capture_groups = Vec::::new(); - for capture_group in regex.capture_names().collect::>().into_iter().flatten() { + for capture_group in regex + .capture_names() + .collect::>() + .into_iter() + .flatten() + { capture_groups.push(BarcodeType::get_barcode_type(capture_group)?) } if capture_groups.is_empty() { diff --git a/extract/src/error.rs b/barkit-extract/src/error.rs similarity index 100% rename from extract/src/error.rs rename to barkit-extract/src/error.rs diff --git a/extract/src/fastq.rs b/barkit-extract/src/fastq.rs similarity index 99% rename from extract/src/fastq.rs rename to barkit-extract/src/fastq.rs index 09c119f..3778398 100644 --- a/extract/src/fastq.rs +++ b/barkit-extract/src/fastq.rs @@ -137,7 +137,7 @@ pub fn create_writer( file: &str, compression: &CompressionType, threads_num: usize, - force: bool + force: bool, ) -> Result { let path = Path::new(file); @@ -146,7 +146,8 @@ pub fn create_writer( return Err(io::Error::new( io::ErrorKind::AlreadyExists, format!("File {} already exists and force is set to false", file), - ).into()); + ) + .into()); } let file = if force { diff --git a/extract/src/lib.rs b/barkit-extract/src/lib.rs similarity index 100% rename from extract/src/lib.rs rename to barkit-extract/src/lib.rs diff --git a/extract/src/logger.rs b/barkit-extract/src/logger.rs similarity index 100% rename from extract/src/logger.rs rename to barkit-extract/src/logger.rs diff --git a/extract/src/pattern.rs b/barkit-extract/src/pattern.rs similarity index 100% rename from extract/src/pattern.rs rename to barkit-extract/src/pattern.rs diff --git a/extract/src/run.rs b/barkit-extract/src/run.rs similarity index 84% rename from extract/src/run.rs rename to barkit-extract/src/run.rs index cde85fa..e26fe0c 100644 --- a/extract/src/run.rs +++ b/barkit-extract/src/run.rs @@ -23,7 +23,7 @@ pub fn run( max_error: usize, output_compression: CompressionType, quiet: bool, - force: bool + force: bool, ) { match (fq2, out_fq2, pattern1, pattern2) { (Some(fq2), Some(out_fq2), pattern1, pattern2) => process_pair_end_fastq( @@ -73,9 +73,8 @@ fn process_single_end_fastq( max_error: usize, output_compression: CompressionType, quiet: bool, - force: bool + force: bool, ) { - let mut reader = fastq::create_reader(&read, threads, max_memory).expect("Failed to create reader"); let writer = fastq::create_writer(&out_read, &output_compression, threads, force) @@ -88,7 +87,8 @@ fn process_single_end_fastq( ); } - let barcode_re = BarcodeRegex::new(&pattern, max_error).expect("Failed to create barcode regex with the provided pattern and max error."); + let barcode_re = BarcodeRegex::new(&pattern, max_error) + .expect("Failed to create barcode regex with the provided pattern and max error."); let progress_bar = match quiet { false => { @@ -101,7 +101,6 @@ fn process_single_end_fastq( true => None, }; - if !quiet { println!( "{} Extracting barcodes from reads...", @@ -133,11 +132,15 @@ fn process_single_end_fastq( let writer = writer.lock().unwrap(); fastq::save_single_end_reads_to_file(result_reads, writer); - if let Some(ref pb) = progress_bar { pb.inc(records.len() as u64) } + if let Some(ref pb) = progress_bar { + pb.inc(records.len() as u64) + } } } - if let Some(pb) = progress_bar { pb.finish_with_message("all reads successfully processed") } + if let Some(pb) = progress_bar { + pb.finish_with_message("all reads successfully processed") + } } #[allow(clippy::too_many_arguments)] @@ -155,12 +158,12 @@ fn process_pair_end_fastq( max_error: usize, output_compression: CompressionType, quiet: bool, - force: bool + force: bool, ) { - let mut reader1 = - fastq::create_reader(&fq1, threads, max_memory).expect("Failed to read input forward reads"); - let mut reader2 = - fastq::create_reader(&fq2, threads, max_memory).expect("Failed to read input reverse reads"); + let mut reader1 = fastq::create_reader(&fq1, threads, max_memory) + .expect("Failed to read input forward reads"); + let mut reader2 = fastq::create_reader(&fq2, threads, max_memory) + .expect("Failed to read input reverse reads"); let writer1 = fastq::create_writer(&out_fq1, &output_compression, threads, force) .expect("Failed to write output forward reads"); @@ -175,11 +178,15 @@ fn process_pair_end_fastq( } let barcode1 = pattern1.as_ref().map(|pat| { - BarcodeRegex::new(pat, max_error).expect("Failed to create barcode regex for pattern1 with the provided pattern and max error") + BarcodeRegex::new(pat, max_error).expect( + "Failed to create barcode regex for pattern1 with the provided pattern and max error", + ) }); let barcode2 = pattern2.as_ref().map(|pat| { - BarcodeRegex::new(pat, max_error).expect("Failed to create barcode regex for pattern2 with the provided pattern and max error") + BarcodeRegex::new(pat, max_error).expect( + "Failed to create barcode regex for pattern2 with the provided pattern and max error", + ) }); let started = Instant::now(); @@ -245,12 +252,16 @@ fn process_pair_end_fastq( let writer2 = writer2.lock().unwrap(); fastq::save_pair_end_reads_to_file(result_read_pairs, writer1, writer2); - if let Some(ref pb) = progress_bar { pb.inc(records1.len() as u64) } + if let Some(ref pb) = progress_bar { + pb.inc(records1.len() as u64) + } } } - if progress_bar.is_some() { println!( - "{} Done in {}", - logger::SPARKLE, - HumanDuration(started.elapsed()) - )} + if progress_bar.is_some() { + println!( + "{} Done in {}", + logger::SPARKLE, + HumanDuration(started.elapsed()) + ) + } } diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..03308cb --- /dev/null +++ b/cliff.toml @@ -0,0 +1,108 @@ +# git-cliff ~ default configuration file +# https://git-cliff.org/docs/configuration +# +# Lines starting with "#" are comments. +# Configuration options are organized into tables and keys. +# See documentation for more information on available options. + + +[remote.github] +owner = "nsyzrantsev" +repo = "barkit" + +[changelog] +# template for the changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{%- macro remote_url() -%} + https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }} +{%- endmacro -%} + +{% macro print_commit(commit) -%} + - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ + {% if commit.breaking %}[**breaking**] {% endif %}\ + {{ commit.message | upper_first }} - \ + ([{{ commit.id | truncate(length=7, end="") }}]({{ self::remote_url() }}/commit/{{ commit.id }}))\ +{% endmacro -%} + +{% if version %}\ + {% if previous.version %}\ + ## [{{ version | trim_start_matches(pat="v") }}]\ + ({{ self::remote_url() }}/compare/{{ previous.version }}..{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }} + {% else %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} + {% endif %}\ +{% else %}\ + ## [unreleased] +{% endif %}\ + +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits + | filter(attribute="scope") + | sort(attribute="scope") %} + {{ self::print_commit(commit=commit) }} + {%- endfor -%} + {% raw %}\n{% endraw %}\ + {%- for commit in commits %} + {%- if not commit.scope -%} + {{ self::print_commit(commit=commit) }} + {% endif -%} + {% endfor -%} +{% endfor -%} +{% raw %}\n{% endraw -%} +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailing s +trim = true +# postprocessors +postprocessors = [ + { pattern = '', replace = "https://github.com/nsyzrantsev/barkit" }, # replace repository URL +] + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # Replace issue numbers + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))"}, + # Check spelling of the commit with https://github.com/crate-ci/typos + # If the spelling is incorrect, it will be automatically fixed. + { pattern = '.*', replace_command = 'typos --write-changes -' }, +] +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "๐Ÿš€ Features" }, + { message = "^fix", group = "๐Ÿ› Bug Fixes" }, + { message = "^doc", group = "๐Ÿ“š Documentation" }, + { message = "^perf", group = "โšก Performance" }, + { message = "^refactor", group = "๐Ÿšœ Refactor" }, + { message = "^style", group = "๐ŸŽจ Styling" }, + { message = "^test", group = "๐Ÿงช Testing" }, + { message = "^chore\\(release\\): prepare for", skip = true }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore|^ci", group = "โš™๏ธ Miscellaneous Tasks" }, + { body = ".*security", group = "๐Ÿ›ก๏ธ Security" }, + { message = "^revert", group = "โ—€๏ธ Revert" }, +] +# filter out the commits that are not matched by commit parsers +filter_commits = false +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "newest" diff --git a/extract/Cargo.toml b/extract/Cargo.toml deleted file mode 100644 index d052a65..0000000 --- a/extract/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "extract" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap = { version = "4.5.4", features = ["derive", "env"] } -flate2 = "1.0.30" -regex = "1.10.4" -seq_io = "0.3.2" -thiserror = "1.0.61" -rayon = "1.10.0" -fancy-regex = "0.13.0" -lz4 = "1.26.0" -gzp = "0.11.3" -indicatif = "0.17.8" -console = "0.15.8" - -[dev-dependencies] -rstest = "0.22.0" diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..6c83be4 --- /dev/null +++ b/release.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +if ! command -v typos &>/dev/null; then + echo "typos is not installed. Run 'cargo install typos-cli' to install it, otherwise the typos won't be fixed" +fi + +if ! command -v git-cliff &>/dev/null; then + echo "git-cliff is not installed. Run 'cargo install git-cliff' to install it, otherwise the CHANGELOG.md won't be updated" +fi + +if [ -z "$1" ]; then + echo "Please provide a tag." + echo "Usage: ./release.sh v[X.Y.Z]" + exit +fi + +echo "Preparing $1..." + +# update the version +msg="# managed by release.sh" +sed -E -i "s/^version = .* $msg$/version = \"${1#v}\" $msg/" barkit*/Cargo.toml +sed -E -i "s/^version = .* $msg$/version = \"${1#v}\" $msg/" Cargo.toml +sed -E -i "s/(barkit-extract = \{ version = \")[^\"]+/\1${1#v}/" Cargo.toml + +# update the changelog +git cliff --config cliff.toml --tag "$1" >CHANGELOG.md +git add -A && git commit -m "chore(release): prepare for $1" +git show + +# generate a changelog for the tag message +export GIT_CLIFF_TEMPLATE="\ + {% for group, commits in commits | group_by(attribute=\"group\") %} + {{ group | upper_first }}\ + {% for commit in commits %} + - {% if commit.breaking %}(breaking) {% endif %}{{ commit.message | upper_first }} ({{ commit.id | truncate(length=7, end=\"\") }})\ + {% endfor %} + {% endfor %}" +changelog=$(git cliff --config examples/detailed.toml --unreleased --strip all) + +# create a signed tag +git -c user.name="barkit" \ + -c user.email="barkit-contributors@protonmail.com" \ + -c user.signingkey="61C056A107882D500B82BA561094E39B2BF14539" \ + tag -s -a "$1" -m "Release $1" -m "$changelog" +git tag -v "$1" +echo "Done!" +echo "Now push the commit (git push) and the tag (git push --tags)." \ No newline at end of file diff --git a/rustfmt.yml b/rustfmt.yml new file mode 100644 index 0000000..5c6ef4c --- /dev/null +++ b/rustfmt.yml @@ -0,0 +1,15 @@ +edition = "2018" +max_width = 85 +newline_style = "Unix" +hard_tabs = true +tab_spaces = 4 +use_field_init_shorthand = true +reorder_imports = true +binop_separator = "Back" +format_code_in_doc_comments = true +format_strings = true +imports_layout = "Vertical" +normalize_doc_attributes = true +overflow_delimited_expr = true +struct_field_align_threshold = 20 +wrap_comments = true \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ae9a8d7..750d688 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,7 @@ pub enum Commands { #[arg(short = 's', long, action=ArgAction::SetTrue)] skip_trimming: bool, - /// Max error (mistmatch) between provided pattern and read sequence + /// Max error (mismatch) between provided pattern and read sequence #[arg(short = 'e', long, default_value = "1")] max_error: usize, diff --git a/src/main.rs b/src/main.rs index 124d9f8..acaa0f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,11 +20,13 @@ fn main() { mgz, lz4, quiet, - force + force, } => { let output_compression = - extract::fastq::CompressionType::get_output_compression_type(gz, bgz, mgz, lz4); - extract::run::run( + barkit_extract::fastq::CompressionType::get_output_compression_type( + gz, bgz, mgz, lz4, + ); + barkit_extract::run::run( fq1.to_string(), fq2.clone(), patterns.pattern1.clone(), @@ -38,7 +40,7 @@ fn main() { *max_error, output_compression, *quiet, - *force + *force, ); } } diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..9cd6455 --- /dev/null +++ b/typos.toml @@ -0,0 +1,5 @@ +[type.md] +extend-ignore-re = [ + "\\[[[:xdigit:]]{7}\\]\\(https://github.com/nsyzrantsev/barkit/commit/[[:xdigit:]]{40}\\)", + "\\[halp\\]\\(https://github.com/orhun/halp\\)", +] \ No newline at end of file