From 1afecc75aa40147ac7315a2778ce2c91cd922c73 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 24 Jun 2024 15:01:15 -0400 Subject: [PATCH 01/16] Update to add 10xv4 (3p) chemistry --- resources/permit_list_info.json | 4 +++ src/simpleaf_commands/quant.rs | 7 +++-- src/utils/af_utils.rs | 50 +++++++++++++++++---------------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/resources/permit_list_info.json b/resources/permit_list_info.json index 69f467d..2e27635 100644 --- a/resources/permit_list_info.json +++ b/resources/permit_list_info.json @@ -7,4 +7,8 @@ "filename" : "10x_v3_permit.txt", "url" : "https://umd.box.com/shared/static/vc9zd4qyjj581gvtolw5kj638wmg4f3s" } + "10xv4-3p" : { + "filename" : "10x_v4_3p_permit.txt", + "url" : "https://umd.box.com/shared/static/4a2q2lxngogaq4vkniptpu2gts5a38fb.txt" + } } diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index 49c4691..952a794 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -212,6 +212,7 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< let chem = match opts.chemistry.as_str() { "10xv2" => Chemistry::TenxV2, "10xv3" => Chemistry::TenxV3, + "10xv4-3p" => Chemistry::TenxV43P, s => { if custom_chem_exists { // parse the custom chemistry json file @@ -247,10 +248,10 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< ori = o; } else { // otherwise, this was not set explicitly. In that case - // if we have 10xv2 or 10xv3 chemistry, set ori = "fw" + // if we have 10xv2, 10xv3, or 10xv4 chemistry, set ori = "fw" // otherwise set ori = "both" match chem { - Chemistry::TenxV2 | Chemistry::TenxV3 => { + Chemistry::TenxV2 | Chemistry::TenxV3 | Chemistry::TenxV43P => { ori = "fw".to_string(); } _ => { @@ -287,7 +288,7 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< // here, the -u flag is provided // but no file is provided, then the // inner option is None and we will try to get the permit list automatically if - // using 10xv2 or 10xv3 + // using 10xv2, 10xv3, or 10xv4 // check the chemistry let pl_res = af_utils::get_permit_if_absent(af_home_path, &chem)?; diff --git a/src/utils/af_utils.rs b/src/utils/af_utils.rs index d4c0b54..114be4a 100644 --- a/src/utils/af_utils.rs +++ b/src/utils/af_utils.rs @@ -16,6 +16,12 @@ use crate::utils::prog_utils; static KNOWN_CHEM_MAP_SALMON: phf::Map<&'static str, &'static str> = phf_map! { "10xv2" => "--chromium", "10xv3" => "--chromiumV3", + // NOTE:: This is not a typo, the geometry for + // the v3 and v4 chemistry are identical. Nonetheless, + // we likely want to still add an explicit flag to + // piscem and change this when we bump the minimum + // required version. + "10xv4-3p" => "--chromiumV3", "dropseq" => "--dropseq", "indropv2" => "--indropV2", "citeseq" => "--citeseq", @@ -32,7 +38,13 @@ static KNOWN_CHEM_MAP_SALMON: phf::Map<&'static str, &'static str> = phf_map! { /// should be passed to use this chemistry. static KNOWN_CHEM_MAP_PISCEM: phf::Map<&'static str, &'static str> = phf_map! { "10xv2" => "chromium_v2", - "10xv3" => "chromium_v3" + "10xv3" => "chromium_v3", + // NOTE:: This is not a typo, the geometry for + // the v3 and v4 chemistry are identical. Nonetheless, + // we likely want to still add an explicit flag to + // piscem and change this when we bump the minimum + // required version. + "10xv4-3p" => "chromium_v3" }; /// The types of "mappers" we know about @@ -101,6 +113,7 @@ pub fn add_to_args(fm: &CellFilterMethod, cmd: &mut std::process::Command) { pub enum Chemistry { TenxV2, TenxV3, + TenxV43P, Other(String), } @@ -109,6 +122,7 @@ impl Chemistry { match self { Chemistry::TenxV2 => "10xv2", Chemistry::TenxV3 => "10xv3", + Chemistry::TenxV43P => "10xv4-3p", Chemistry::Other(s) => s.as_str(), } } @@ -182,6 +196,12 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result { + let chem_file = "10x_v4_3p_permit.txt"; + if odir.join(chem_file).exists() { + return Ok(PermitListResult::AlreadyPresent(odir.join(chem_file))); + } + } _ => { return Ok(PermitListResult::UnregisteredChemistry); } @@ -197,28 +217,9 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result; // parse the JSON appropriately based on the chemistry we have match chem { - Chemistry::TenxV2 => { - if let Some(d) = permit_dict.get("10xv2") { - opt_chem_file = d - .get("filename") - .expect("value for filename field should be a string") - .as_str() - .map(|cf| cf.to_string()); - opt_dl_url = d - .get("url") - .expect("value for url field should be a string") - .as_str() - .map(|url| url.to_string()); - } else { - bail!( - "could not obtain \"10xv2\" key from the fetched permit_dict at {} = {:?}", - permit_dict_url, - permit_dict - ) - } - } - Chemistry::TenxV3 => { - if let Some(d) = permit_dict.get("10xv3") { + Chemistry::TenxV2 | Chemistry::TenxV3 | Chemistry::TenxV43P => { + let chem_key = chem.as_str(); + if let Some(d) = permit_dict.get(chem_key) { opt_chem_file = d .get("filename") .expect("value for filename field should be a string") @@ -231,7 +232,8 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result Date: Mon, 24 Jun 2024 16:46:23 -0400 Subject: [PATCH 02/16] Add cargo-dist stuff --- .github/workflows/release.yml | 275 ++++++++++++++++++++++++++++++++++ Cargo.toml | 23 +++ 2 files changed, 298 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..82e5731 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,275 @@ +# Copyright 2022-2024, axodotdev +# SPDX-License-Identifier: MIT or Apache-2.0 +# +# CI that: +# +# * checks for a Git Tag that looks like a release +# * builds artifacts with cargo-dist (archives, installers, hashes) +# * uploads those artifacts to temporary workflow zip +# * on success, uploads the artifacts to a GitHub Release +# +# Note that the GitHub Release will be created with a generated +# title/body based on your changelogs. + +name: Release + +permissions: + contents: write + +# This task will run whenever you push a git tag that looks like a version +# like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. +# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where +# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION +# must be a Cargo-style SemVer Version (must have at least major.minor.patch). +# +# If PACKAGE_NAME is specified, then the announcement will be for that +# package (erroring out if it doesn't have the given version or isn't cargo-dist-able). +# +# If PACKAGE_NAME isn't specified, then the announcement will be for all +# (cargo-dist-able) packages in the workspace with that version (this mode is +# intended for workspaces with only one dist-able package, or with all dist-able +# packages versioned/released in lockstep). +# +# If you push multiple tags at once, separate instances of this workflow will +# spin up, creating an independent announcement for each one. However, GitHub +# will hard limit this to 3 tags per commit, as it will assume more tags is a +# mistake. +# +# If there's a prerelease-style suffix to the version, then the release(s) +# will be marked as a prerelease. +on: + pull_request: + push: + tags: + - '**[0-9]+.[0-9]+.[0-9]+*' + +jobs: + # Run 'cargo dist plan' (or host) to determine what tasks we need to do + plan: + runs-on: "ubuntu-20.04" + outputs: + val: ${{ steps.plan.outputs.manifest }} + tag: ${{ !github.event.pull_request && github.ref_name || '' }} + tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} + publishing: ${{ !github.event.pull_request }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install cargo-dist + # we specify bash to get pipefail; it guards against the `curl` command + # failing. otherwise `sh` won't catch that `curl` returned non-0 + shell: bash + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.16.0/cargo-dist-installer.sh | sh" + # sure would be cool if github gave us proper conditionals... + # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible + # functionality based on whether this is a pull_request, and whether it's from a fork. + # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* + # but also really annoying to build CI around when it needs secrets to work right.) + - id: plan + run: | + cargo dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json + echo "cargo dist ran successfully" + cat plan-dist-manifest.json + echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" + - name: "Upload dist-manifest.json" + uses: actions/upload-artifact@v4 + with: + name: artifacts-plan-dist-manifest + path: plan-dist-manifest.json + + # Build and packages all the platform-specific things + build-local-artifacts: + name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) + # Let the initial task tell us to not run (currently very blunt) + needs: + - plan + if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} + strategy: + fail-fast: false + # Target platforms/runners are computed by cargo-dist in create-release. + # Each member of the matrix has the following arguments: + # + # - runner: the github runner + # - dist-args: cli flags to pass to cargo dist + # - install-dist: expression to run to install cargo-dist on the runner + # + # Typically there will be: + # - 1 "global" task that builds universal installers + # - N "local" tasks that build each platform's binaries and platform-specific installers + matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} + runs-on: ${{ matrix.runner }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json + steps: + - name: enable windows longpaths + run: | + git config --global core.longpaths true + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: swatinem/rust-cache@v2 + with: + key: ${{ join(matrix.targets, '-') }} + cache-provider: ${{ matrix.cache_provider }} + - name: Install cargo-dist + run: ${{ matrix.install_dist }} + # Get the dist-manifest + - name: Fetch local artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - name: Install dependencies + run: | + ${{ matrix.packages_install }} + - name: Build artifacts + run: | + # Actually do builds and make zips and whatnot + cargo dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json + echo "cargo dist ran successfully" + - id: cargo-dist + name: Post-build + # We force bash here just because github makes it really hard to get values up + # to "real" actions without writing to env-vars, and writing to env-vars has + # inconsistent syntax between shell and powershell. + shell: bash + run: | + # Parse out what we just built and upload it to scratch storage + echo "paths<> "$GITHUB_OUTPUT" + jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + cp dist-manifest.json "$BUILD_MANIFEST_NAME" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + with: + name: artifacts-build-local-${{ join(matrix.targets, '_') }} + path: | + ${{ steps.cargo-dist.outputs.paths }} + ${{ env.BUILD_MANIFEST_NAME }} + + # Build and package all the platform-agnostic(ish) things + build-global-artifacts: + needs: + - plan + - build-local-artifacts + runs-on: "ubuntu-20.04" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install cargo-dist + shell: bash + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.16.0/cargo-dist-installer.sh | sh" + # Get all the local artifacts for the global tasks to use (for e.g. checksums) + - name: Fetch local artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + - id: cargo-dist + shell: bash + run: | + cargo dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json + echo "cargo dist ran successfully" + + # Parse out what we just built and upload it to scratch storage + echo "paths<> "$GITHUB_OUTPUT" + jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + cp dist-manifest.json "$BUILD_MANIFEST_NAME" + - name: "Upload artifacts" + uses: actions/upload-artifact@v4 + with: + name: artifacts-build-global + path: | + ${{ steps.cargo-dist.outputs.paths }} + ${{ env.BUILD_MANIFEST_NAME }} + # Determines if we should publish/announce + host: + needs: + - plan + - build-local-artifacts + - build-global-artifacts + # Only run if we're "publishing", and only if local and global didn't fail (skipped is fine) + if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + runs-on: "ubuntu-20.04" + outputs: + val: ${{ steps.host.outputs.manifest }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Install cargo-dist + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.16.0/cargo-dist-installer.sh | sh" + # Fetch artifacts from scratch-storage + - name: Fetch artifacts + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: target/distrib/ + merge-multiple: true + # This is a harmless no-op for GitHub Releases, hosting for that happens in "announce" + - id: host + shell: bash + run: | + cargo dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json + echo "artifacts uploaded and released successfully" + cat dist-manifest.json + echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" + - name: "Upload dist-manifest.json" + uses: actions/upload-artifact@v4 + with: + # Overwrite the previous copy + name: artifacts-dist-manifest + path: dist-manifest.json + + # Create a GitHub Release while uploading all files to it + announce: + needs: + - plan + - host + # use "always() && ..." to allow us to wait for all publish jobs while + # still allowing individual publish jobs to skip themselves (for prereleases). + # "host" however must run to completion, no skipping allowed! + if: ${{ always() && needs.host.result == 'success' }} + runs-on: "ubuntu-20.04" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: "Download GitHub Artifacts" + uses: actions/download-artifact@v4 + with: + pattern: artifacts-* + path: artifacts + merge-multiple: true + - name: Cleanup + run: | + # Remove the granular manifests + rm -f artifacts/*-dist-manifest.json + - name: Create GitHub Release + env: + PRERELEASE_FLAG: "${{ fromJson(needs.host.outputs.val).announcement_is_prerelease && '--prerelease' || '' }}" + ANNOUNCEMENT_TITLE: "${{ fromJson(needs.host.outputs.val).announcement_title }}" + ANNOUNCEMENT_BODY: "${{ fromJson(needs.host.outputs.val).announcement_github_body }}" + run: | + # Write and read notes from a file to avoid quoting breaking things + echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt + + gh release create "${{ needs.plan.outputs.tag }}" --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" $PRERELEASE_FLAG + gh release upload "${{ needs.plan.outputs.tag }}" artifacts/* diff --git a/Cargo.toml b/Cargo.toml index e267ec9..8de4e0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,3 +58,26 @@ minreq = { version = "2.11.0", features = ["serde", "serde_json", "https", "json [profile.release] lto = "thin" opt-level = 3 + +# The profile that 'cargo dist' will build with +[profile.dist] +inherits = "release" +lto = "thin" + +# Config for 'cargo dist' +[workspace.metadata.dist] +# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax) +cargo-dist-version = "0.16.0" +# CI backends to support +ci = "github" +# The installers to generate for each app +installers = ["shell"] +# Target platforms to build apps for (Rust target-triple syntax) +targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"] +# Publish jobs to run in CI +pr-run-mode = "plan" +# Whether to install an updater program +install-updater = true + +[workspace.metadata.dist.github-custom-runners] +aarch64-apple-darwin = "macos-14" From 7900f76d8a8de0e8a41912b6359ea3255c570a57 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 24 Jun 2024 21:44:03 -0400 Subject: [PATCH 03/16] missing comma --- resources/permit_list_info.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/permit_list_info.json b/resources/permit_list_info.json index 2e27635..e892efb 100644 --- a/resources/permit_list_info.json +++ b/resources/permit_list_info.json @@ -6,7 +6,7 @@ "10xv3" : { "filename" : "10x_v3_permit.txt", "url" : "https://umd.box.com/shared/static/vc9zd4qyjj581gvtolw5kj638wmg4f3s" - } + }, "10xv4-3p" : { "filename" : "10x_v4_3p_permit.txt", "url" : "https://umd.box.com/shared/static/4a2q2lxngogaq4vkniptpu2gts5a38fb.txt" From 4cd779f3072794ea897a749ea6926c683201f37d Mon Sep 17 00:00:00 2001 From: rob-p Date: Tue, 25 Jun 2024 10:11:35 -0400 Subject: [PATCH 04/16] Update deps Make clippy happy --- Cargo.lock | 311 ++++++++++++++++------------- Cargo.toml | 18 +- src/simpleaf_commands/chemistry.rs | 1 + src/utils/workflow_utils.rs | 4 +- 4 files changed, 184 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8537395..af31020 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,9 +23,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -63,38 +63,39 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] @@ -151,9 +152,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "base64" @@ -175,9 +176,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitvec" @@ -239,7 +240,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -277,12 +278,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -293,23 +295,23 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.33" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] name = "clap" -version = "4.4.18" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", "clap_derive", @@ -317,40 +319,40 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", "terminal_size", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "cmd_lib" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5f4cbdcab51ca635c5b19c85ece4072ea42e0d2360242826a6fc96fb11f0d40" +checksum = "718f77610af91e4d648fe9da0150ae58698cbcfb93bf63e764907fbefd56ffe8" dependencies = [ "cmd_lib_macros", "env_logger", @@ -362,9 +364,9 @@ dependencies = [ [[package]] name = "cmd_lib_macros" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae881960f7e2a409f91ef0b1c09558cf293031a1d6e8b45f908311f2a43f5fdf" +checksum = "9a80fac05ed12fe97a70b5dfdd910c9b90b53f4de69002c3179e29ac2d066abc" dependencies = [ "proc-macro-error", "proc-macro2", @@ -374,9 +376,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "comfy-table" @@ -463,7 +465,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "crossterm_winapi", "libc", "parking_lot", @@ -549,9 +551,9 @@ checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "either" -version = "1.9.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "enum_dispatch" @@ -562,7 +564,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -586,9 +588,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -673,9 +675,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -740,6 +742,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[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.4" @@ -763,9 +771,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -806,15 +814,21 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ "hermit-abi", - "rustix", + "libc", "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -826,15 +840,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -870,7 +884,7 @@ dependencies = [ "rustc-hash", "serde", "static_assertions", - "strsim", + "strsim 0.10.0", "thiserror", ] @@ -1061,9 +1075,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libm" @@ -1106,9 +1120,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lz4" @@ -1158,9 +1172,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memmap2" @@ -1191,9 +1205,9 @@ dependencies = [ [[package]] name = "minreq" -version = "2.11.0" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3371dfc7b772c540da1380123674a8e20583aca99907087d990ca58cf44203" +checksum = "6fdef521c74c2884a4f3570bcdb6d2a77b3c533feb6b27ac2ae72673cc221c64" dependencies = [ "log", "once_cell", @@ -1360,11 +1374,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -1533,7 +1553,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -1577,7 +1597,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -1667,7 +1687,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdfb622b8ca81b4614c64d95e7590d6e0571d7d398b5ad595c1abc4412abe714" dependencies = [ "ahash", - "bitflags 2.4.2", + "bitflags 2.5.0", "bytemuck", "chrono", "comfy-table", @@ -1739,7 +1759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e1c2da1ca20106f80d9510090344e7311fd1dcfd6e6b65031e10606c0958c7" dependencies = [ "ahash", - "bitflags 2.4.2", + "bitflags 2.5.0", "glob", "once_cell", "polars-arrow", @@ -1928,18 +1948,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2021,14 +2041,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", - "regex-syntax 0.8.2", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", ] [[package]] @@ -2042,13 +2062,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2059,9 +2079,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "ring" @@ -2123,11 +2143,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -2164,9 +2184,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safemem" @@ -2192,9 +2212,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "seq_geom_parser" @@ -2225,29 +2245,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" dependencies = [ "itoa", "ryu", @@ -2403,6 +2423,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "structdump" version = "0.2.0" @@ -2437,11 +2463,11 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -2457,9 +2483,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -2497,7 +2523,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -2565,7 +2591,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -2586,12 +2612,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -2606,10 +2633,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -2632,7 +2660,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] @@ -2755,7 +2783,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -2777,7 +2805,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2796,15 +2824,14 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "which" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c" +checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" dependencies = [ "either", "home", - "once_cell", "rustix", - "windows-sys 0.52.0", + "winsafe", ] [[package]] @@ -2844,7 +2871,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -2862,7 +2889,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -2882,17 +2909,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -2903,9 +2930,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -2915,9 +2942,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -2927,9 +2954,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -2939,9 +2966,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -2951,9 +2978,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -2963,9 +2990,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -2975,9 +3002,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winsafe" +version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wyz" @@ -3038,7 +3071,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.66", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8de4e0c..956f7d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,24 +36,24 @@ seq_geom_parser = { git = "https://github.com/COMBINE-lab/seq_geom_parser", bran seq_geom_xform = { git = "https://github.com/COMBINE-lab/seq_geom_xform", branch = "dev", version = "0.4.0" } roers = { git = "https://github.com/COMBINE-lab/roers", branch = "main", version = "0.3.0" } anyhow = "^1.0" -clap = { version = "4.4.18", features = ["derive", "cargo", "deprecated", "wrap_help", "help", "usage", "error-context"] } -cmd_lib = "^1.9.3" +clap = { version = "4.5.7", features = ["derive", "cargo", "deprecated", "wrap_help", "help", "usage", "error-context"] } +cmd_lib = "^1.9.4" tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", default-features = true, features = ["env-filter"] } -semver = "^1.0.21" -serde = {version = "1.0.196", features = ["derive"]} -serde_json = "1.0.113" -time = {version = "^0.3.31", features = ["macros", "formatting", "parsing", "serde", "serde-human-readable"]} -which = "^6.0.0" +semver = "^1.0.23" +serde = {version = "1.0.203", features = ["derive"]} +serde_json = "1.0.118" +time = {version = "^0.3.36", features = ["macros", "formatting", "parsing", "serde", "serde-human-readable"]} +which = "^6.0.1" jrsonnet-evaluator = "0.5.0-pre95" jrsonnet-cli = "0.5.0-pre95" jrsonnet-parser = "0.5.0-pre95" thiserror = "1.0" phf = { version = "0.11.2", features = ["macros"] } -chrono = "0.4.33" +chrono = "0.4.38" tabled = "0.15.0" csv = "1.3.0" -minreq = { version = "2.11.0", features = ["serde", "serde_json", "https", "json-using-serde"] } +minreq = { version = "2.11.2", features = ["serde", "serde_json", "https", "json-using-serde"] } [profile.release] lto = "thin" diff --git a/src/simpleaf_commands/chemistry.rs b/src/simpleaf_commands/chemistry.rs index dfb80b0..9bd6d61 100644 --- a/src/simpleaf_commands/chemistry.rs +++ b/src/simpleaf_commands/chemistry.rs @@ -23,6 +23,7 @@ pub fn add_chemistry(af_home_path: PathBuf, add_chem_cmd: Commands) -> Result<() .read(true) .write(true) .create(true) + .truncate(false) // can't truncate because we've not read it yet .open(&custom_chem_p) .with_context({ || { diff --git a/src/utils/workflow_utils.rs b/src/utils/workflow_utils.rs index 791e1d3..8cd9355 100644 --- a/src/utils/workflow_utils.rs +++ b/src/utils/workflow_utils.rs @@ -171,7 +171,7 @@ be certain you intend to do this.", } // loop over every row (but the headers) - for (_i, row) in rdr.records().enumerate() { + for row in rdr.records() { let mut output_json = json!({}); let mut patch_name = String::new(); // for each key that we need to replace @@ -856,7 +856,7 @@ impl WorkflowLog { .to_owned(); // push the latest run in the log into previous run, as we will update it - pr[latest_run_time_stamp] = latest_run.to_owned(); + latest_run.clone_into(&mut pr[latest_run_time_stamp]); pr } else { json!({}) From cbb7d4d0af3a8fad252eae95770efb7985eec9a5 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Thu, 27 Jun 2024 18:52:06 -0400 Subject: [PATCH 05/16] sync chemistries with next piscem release --- resources/permit_list_info.json | 8 ++++++++ src/simpleaf_commands/quant.rs | 13 +++++++++++- src/utils/af_utils.rs | 36 ++++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/resources/permit_list_info.json b/resources/permit_list_info.json index e892efb..6485307 100644 --- a/resources/permit_list_info.json +++ b/resources/permit_list_info.json @@ -3,10 +3,18 @@ "filename" : "10x_v2_permit.txt", "url" : "https://umd.box.com/shared/static/jbs2wszgbj7k4ic2hass9ts6nhqkwq1p" }, + "10xv2-5p" : { + "filename" : "10x_v2_permit.txt", + "url" : "https://umd.box.com/shared/static/jbs2wszgbj7k4ic2hass9ts6nhqkwq1p" + }, "10xv3" : { "filename" : "10x_v3_permit.txt", "url" : "https://umd.box.com/shared/static/vc9zd4qyjj581gvtolw5kj638wmg4f3s" }, + "10xv3-5p" : { + "filename" : "10x_v3_5p_permit.txt", + "url" : "https://umd.box.com/shared/static/cbpv1c4zi6ty81nvcgy3pyta2oj7vea1.txt" + }, "10xv4-3p" : { "filename" : "10x_v4_3p_permit.txt", "url" : "https://umd.box.com/shared/static/4a2q2lxngogaq4vkniptpu2gts5a38fb.txt" diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index 952a794..61ff364 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -211,7 +211,9 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< let chem = match opts.chemistry.as_str() { "10xv2" => Chemistry::TenxV2, + "10xv2-5p" => Chemistry::TenxV25P, "10xv3" => Chemistry::TenxV3, + "10xv3-5p" => Chemistry::TenxV35P, "10xv4-3p" => Chemistry::TenxV43P, s => { if custom_chem_exists { @@ -248,12 +250,21 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< ori = o; } else { // otherwise, this was not set explicitly. In that case - // if we have 10xv2, 10xv3, or 10xv4 chemistry, set ori = "fw" + // if we have 10xv2, 10xv3, or 10xv4 (3') chemistry, set ori = "fw" + // if we have 10xv2-5p or 10xv3-5p chemistry, set ori = "rc" // otherwise set ori = "both" match chem { Chemistry::TenxV2 | Chemistry::TenxV3 | Chemistry::TenxV43P => { ori = "fw".to_string(); } + Chemistry::TenxV25P | Chemistry::TenxV35P => { + // NOTE: This is because we assume the piscem encoding + // that is, these are treated as potentially paired-end protocols and + // we infer the orientation of the fragment = orientation of read 1. + // Think about changing this or making it more robust if and when we + // propagate more information about paired-end mappings. + ori = "rc".to_string(); + } _ => { ori = "both".to_string(); } diff --git a/src/utils/af_utils.rs b/src/utils/af_utils.rs index 114be4a..4b339f3 100644 --- a/src/utils/af_utils.rs +++ b/src/utils/af_utils.rs @@ -18,8 +18,8 @@ static KNOWN_CHEM_MAP_SALMON: phf::Map<&'static str, &'static str> = phf_map! { "10xv3" => "--chromiumV3", // NOTE:: This is not a typo, the geometry for // the v3 and v4 chemistry are identical. Nonetheless, - // we likely want to still add an explicit flag to - // piscem and change this when we bump the minimum + // we may want to still add an explicit flag to + // salmon and change this when we bump the minimum // required version. "10xv4-3p" => "--chromiumV3", "dropseq" => "--dropseq", @@ -38,13 +38,10 @@ static KNOWN_CHEM_MAP_SALMON: phf::Map<&'static str, &'static str> = phf_map! { /// should be passed to use this chemistry. static KNOWN_CHEM_MAP_PISCEM: phf::Map<&'static str, &'static str> = phf_map! { "10xv2" => "chromium_v2", + "10xv2-5p" => "chromium_v2_5p", "10xv3" => "chromium_v3", - // NOTE:: This is not a typo, the geometry for - // the v3 and v4 chemistry are identical. Nonetheless, - // we likely want to still add an explicit flag to - // piscem and change this when we bump the minimum - // required version. - "10xv4-3p" => "chromium_v3" + "10xv3-5p" => "chromium_v3_5p", + "10xv4-3p" => "chromium_v4_3p" }; /// The types of "mappers" we know about @@ -112,7 +109,9 @@ pub fn add_to_args(fm: &CellFilterMethod, cmd: &mut std::process::Command) { pub enum Chemistry { TenxV2, + TenxV25P, TenxV3, + TenxV35P, TenxV43P, Other(String), } @@ -121,7 +120,9 @@ impl Chemistry { pub fn as_str(&self) -> &str { match self { Chemistry::TenxV2 => "10xv2", + Chemistry::TenxV25P => "10xv2-5p", Chemistry::TenxV3 => "10xv3", + Chemistry::TenxV35P => "10xv3-5p", Chemistry::TenxV43P => "10xv4-3p", Chemistry::Other(s) => s.as_str(), } @@ -190,12 +191,25 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result { + // v2 and v2-5' use the same permit list + let chem_file = "10x_v2_permit.txt"; + if odir.join(chem_file).exists() { + return Ok(PermitListResult::AlreadyPresent(odir.join(chem_file))); + } + } Chemistry::TenxV3 => { let chem_file = "10x_v3_permit.txt"; if odir.join(chem_file).exists() { return Ok(PermitListResult::AlreadyPresent(odir.join(chem_file))); } } + Chemistry::TenxV35P => { + let chem_file = "10x_v3_5p_permit.txt"; + if odir.join(chem_file).exists() { + return Ok(PermitListResult::AlreadyPresent(odir.join(chem_file))); + } + } Chemistry::TenxV43P => { let chem_file = "10x_v4_3p_permit.txt"; if odir.join(chem_file).exists() { @@ -217,7 +231,11 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result; // parse the JSON appropriately based on the chemistry we have match chem { - Chemistry::TenxV2 | Chemistry::TenxV3 | Chemistry::TenxV43P => { + Chemistry::TenxV2 + | Chemistry::TenxV25P + | Chemistry::TenxV3 + | Chemistry::TenxV35P + | Chemistry::TenxV43P => { let chem_key = chem.as_str(); if let Some(d) = permit_dict.get(chem_key) { opt_chem_file = d From e78fbcb90dd46b83b06ab6af6b441d0c16f0f0bc Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Thu, 27 Jun 2024 19:39:15 -0400 Subject: [PATCH 06/16] add known chemistry output to inspect --- Cargo.lock | 93 ++++++++++++++++++++++++++++---- Cargo.toml | 2 + src/simpleaf_commands/inspect.rs | 10 +++- src/utils/af_utils.rs | 17 ++++++ 4 files changed, 112 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ae4c87..25410c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,8 +387,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c64043d6c7b7a4c58e39e7efccfdea7b93d885a795d0c054a69dbbf4dd52686" dependencies = [ "crossterm", - "strum", - "strum_macros", + "strum 0.25.0", + "strum_macros 0.25.3", "unicode-width", ] @@ -1567,14 +1567,35 @@ dependencies = [ "sha2", ] +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + [[package]] name = "phf" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros", - "phf_shared", + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand", ] [[package]] @@ -1583,23 +1604,46 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared", + "phf_shared 0.11.2", "rand", ] +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "phf_macros" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.11.2", + "phf_shared 0.11.2", "proc-macro2", "quote", "syn 2.0.66", ] +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "phf_shared" version = "0.11.2" @@ -1841,7 +1885,7 @@ dependencies = [ "rayon", "regex", "smartstring", - "strum_macros", + "strum_macros 0.25.3", "version_check", ] @@ -1946,6 +1990,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.85" @@ -2346,13 +2396,15 @@ dependencies = [ "jrsonnet-evaluator", "jrsonnet-parser", "minreq", - "phf", + "phf 0.11.2", "roers", "semver", "seq_geom_parser", "seq_geom_xform", "serde", "serde_json", + "strum 0.26.3", + "strum_macros 0.26.4", "tabled", "thiserror", "time", @@ -2457,6 +2509,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "phf 0.10.1", + "strum_macros 0.26.4", +] + [[package]] name = "strum_macros" version = "0.25.3" @@ -2470,6 +2532,19 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/Cargo.toml b/Cargo.toml index 54e6bed..54270b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,8 @@ chrono = "0.4.38" tabled = "0.15.0" csv = "1.3.0" minreq = { version = "2.11.2", features = ["serde", "serde_json", "https", "json-using-serde"] } +strum = { version = "0.26.3", features = ["derive", "phf"] } +strum_macros = "0.26.4" [profile.release] lto = "thin" diff --git a/src/simpleaf_commands/inspect.rs b/src/simpleaf_commands/inspect.rs index 95a1ae3..a570859 100644 --- a/src/simpleaf_commands/inspect.rs +++ b/src/simpleaf_commands/inspect.rs @@ -1,4 +1,5 @@ -use crate::utils::prog_utils::*; +use crate::utils::{af_utils::Chemistry, prog_utils::*}; +use strum::IntoEnumIterator; use anyhow::{Context, Result}; use serde_json::Value; @@ -33,5 +34,12 @@ pub fn inspect_simpleaf(af_home_path: PathBuf) -> Result<()> { let v: Value = serde_json::from_reader(custom_chem_reader)?; println!("{}", serde_json::to_string_pretty(&v).unwrap()); } + + println!("\nKnown chemistry flags\n"); + + for c in Chemistry::iter() { + println!("{:?}", c); + } + Ok(()) } diff --git a/src/utils/af_utils.rs b/src/utils/af_utils.rs index 4b339f3..275dc41 100644 --- a/src/utils/af_utils.rs +++ b/src/utils/af_utils.rs @@ -3,7 +3,10 @@ use cmd_lib::run_fun; use phf::phf_map; use seq_geom_parser::{AppendToCmdArgs, FragmentGeomDesc, PiscemGeomDesc, SalmonSeparateGeomDesc}; use seq_geom_xform::{FifoXFormData, FragmentGeomDescExt}; +use std::fmt; use std::path::{Path, PathBuf}; + +use strum_macros::EnumIter; use tracing::error; use crate::utils::prog_utils; @@ -107,6 +110,7 @@ pub fn add_to_args(fm: &CellFilterMethod, cmd: &mut std::process::Command) { } } +#[derive(EnumIter, PartialEq)] pub enum Chemistry { TenxV2, TenxV25P, @@ -129,6 +133,19 @@ impl Chemistry { } } +impl fmt::Debug for Chemistry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Chemistry::TenxV2 => write!(f, "10xv2"), + Chemistry::TenxV25P => write!(f, "10xv2-5p"), + Chemistry::TenxV3 => write!(f, "10xv3"), + Chemistry::TenxV35P => write!(f, "10xv3-5p"), + Chemistry::TenxV43P => write!(f, "10xv4-3p"), + Chemistry::Other(s) => write!(f, "custom({})", s.as_str()), + } + } +} + pub enum PermitListResult { DownloadSuccessful(PathBuf), AlreadyPresent(PathBuf), From a1599a391b0d98d202ddd9431c6d2e258bd0dfa8 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 08:12:48 -0400 Subject: [PATCH 07/16] Output inspect info in json format --- src/simpleaf_commands/inspect.rs | 37 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/src/simpleaf_commands/inspect.rs b/src/simpleaf_commands/inspect.rs index a570859..9b2b83e 100644 --- a/src/simpleaf_commands/inspect.rs +++ b/src/simpleaf_commands/inspect.rs @@ -2,25 +2,16 @@ use crate::utils::{af_utils::Chemistry, prog_utils::*}; use strum::IntoEnumIterator; use anyhow::{Context, Result}; -use serde_json::Value; +use serde_json::{json, Value}; use std::io::BufReader; use std::path::PathBuf; pub fn inspect_simpleaf(af_home_path: PathBuf) -> Result<()> { // Read the JSON contents of the file as an instance of `User`. let v: Value = inspect_af_home(af_home_path.as_path())?; - println!( - "\n----- simpleaf info -----\n{}", - serde_json::to_string_pretty(&v).unwrap() - ); - // do we have a custom chemistry file let custom_chem_p = af_home_path.join("custom_chemistries.json"); - if custom_chem_p.is_file() { - println!( - "\nCustom chemistries exist at path : {}\n----- custom chemistries -----\n", - custom_chem_p.display() - ); + let chem_info_value = if custom_chem_p.is_file() { // parse the custom chemistry json file let custom_chem_file = std::fs::File::open(&custom_chem_p).with_context({ || { @@ -32,14 +23,24 @@ pub fn inspect_simpleaf(af_home_path: PathBuf) -> Result<()> { })?; let custom_chem_reader = BufReader::new(custom_chem_file); let v: Value = serde_json::from_reader(custom_chem_reader)?; - println!("{}", serde_json::to_string_pretty(&v).unwrap()); - } - - println!("\nKnown chemistry flags\n"); + json!({ + "custom_chem_path" : custom_chem_p.display().to_string(), + "custom_geometries" : v + }) + } else { + json!("") + }; - for c in Chemistry::iter() { - println!("{:?}", c); - } + let chem_list = Chemistry::iter() + .map(|c| format!("{:?}", c)) + .collect::>() + .join(", "); + let inspect_v = json!({ + "simpleaf_info" : v, + "custom_chem_info" : chem_info_value, + "builtin_chemistries" : chem_list + }); + println!("{}", serde_json::to_string_pretty(&inspect_v)?); Ok(()) } From 215622a92e0a1256edebf93c1753ba3f907ea896 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 09:05:08 -0400 Subject: [PATCH 08/16] include simpleaf_version in inspect output --- src/main.rs | 4 ++-- src/simpleaf_commands/inspect.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 973836f..e967cbc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use tracing_subscriber::{filter::LevelFilter, fmt, prelude::*, EnvFilter}; use anyhow::bail; -use clap::Parser; +use clap::{crate_version, Parser}; use std::env; use std::path::PathBuf; @@ -75,7 +75,7 @@ fn main() -> anyhow::Result<()> { Commands::AddChemistry { name, geometry } => { add_chemistry(af_home_path, Commands::AddChemistry { name, geometry }) } - Commands::Inspect {} => inspect_simpleaf(af_home_path), + Commands::Inspect {} => inspect_simpleaf(crate_version!(), af_home_path), // if we are building the reference and indexing Commands::Index(index_opts) => build_ref_and_index(af_home_path.as_path(), index_opts), diff --git a/src/simpleaf_commands/inspect.rs b/src/simpleaf_commands/inspect.rs index 9b2b83e..1360245 100644 --- a/src/simpleaf_commands/inspect.rs +++ b/src/simpleaf_commands/inspect.rs @@ -6,7 +6,7 @@ use serde_json::{json, Value}; use std::io::BufReader; use std::path::PathBuf; -pub fn inspect_simpleaf(af_home_path: PathBuf) -> Result<()> { +pub fn inspect_simpleaf(version: &str, af_home_path: PathBuf) -> Result<()> { // Read the JSON contents of the file as an instance of `User`. let v: Value = inspect_af_home(af_home_path.as_path())?; // do we have a custom chemistry file @@ -37,6 +37,7 @@ pub fn inspect_simpleaf(af_home_path: PathBuf) -> Result<()> { .join(", "); let inspect_v = json!({ + "simpleaf_version" : version, "simpleaf_info" : v, "custom_chem_info" : chem_info_value, "builtin_chemistries" : chem_list From 436ca267b4a66086887b474be72597d30b005c6f Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 22:35:38 -0400 Subject: [PATCH 09/16] render builtin chemistries as an actual json list --- src/simpleaf_commands/inspect.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/simpleaf_commands/inspect.rs b/src/simpleaf_commands/inspect.rs index 1360245..55e4abc 100644 --- a/src/simpleaf_commands/inspect.rs +++ b/src/simpleaf_commands/inspect.rs @@ -33,8 +33,7 @@ pub fn inspect_simpleaf(version: &str, af_home_path: PathBuf) -> Result<()> { let chem_list = Chemistry::iter() .map(|c| format!("{:?}", c)) - .collect::>() - .join(", "); + .collect::>(); let inspect_v = json!({ "simpleaf_version" : version, From 5c9e620a32f613aae8fd5cced865872a2a65c3a7 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 22:48:50 -0400 Subject: [PATCH 10/16] update deps --- Cargo.lock | 58 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25410c6..8c98271 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -176,9 +176,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitvec" @@ -240,7 +240,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -319,9 +319,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -332,14 +332,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -465,7 +465,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", "libc", "parking_lot", @@ -564,7 +564,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1553,7 +1553,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1632,7 +1632,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -1731,7 +1731,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdfb622b8ca81b4614c64d95e7590d6e0571d7d398b5ad595c1abc4412abe714" dependencies = [ "ahash", - "bitflags 2.5.0", + "bitflags 2.6.0", "bytemuck", "chrono", "comfy-table", @@ -1803,7 +1803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e1c2da1ca20106f80d9510090344e7311fd1dcfd6e6b65031e10606c0958c7" dependencies = [ "ahash", - "bitflags 2.5.0", + "bitflags 2.6.0", "glob", "once_cell", "polars-arrow", @@ -1998,9 +1998,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -2197,7 +2197,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2310,7 +2310,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2529,7 +2529,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2542,7 +2542,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2558,9 +2558,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" dependencies = [ "proc-macro2", "quote", @@ -2666,7 +2666,7 @@ checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2735,7 +2735,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] @@ -2858,7 +2858,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-shared", ] @@ -2880,7 +2880,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3146,7 +3146,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.68", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 54270b2..03fa3ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ seq_geom_parser = { git = "https://github.com/COMBINE-lab/seq_geom_parser", bran seq_geom_xform = { git = "https://github.com/COMBINE-lab/seq_geom_xform", branch = "dev", version = "0.4.0" } roers = { git = "https://github.com/COMBINE-lab/roers", branch = "main", version = "0.3.0" } anyhow = "^1.0" -clap = { version = "4.5.7", features = ["derive", "cargo", "deprecated", "wrap_help", "help", "usage", "error-context"] } +clap = { version = "4.5.8", features = ["derive", "cargo", "deprecated", "wrap_help", "help", "usage", "error-context"] } cmd_lib = "^1.9.4" tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", default-features = true, features = ["env-filter"] } From b723c0e5d9f23fbc81d7afab845fd642939ad15c Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 23:04:57 -0400 Subject: [PATCH 11/16] we want to treat PE 5' geometries as fw --- src/simpleaf_commands/quant.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index 61ff364..2214adb 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -261,9 +261,11 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< // NOTE: This is because we assume the piscem encoding // that is, these are treated as potentially paired-end protocols and // we infer the orientation of the fragment = orientation of read 1. - // Think about changing this or making it more robust if and when we - // propagate more information about paired-end mappings. - ori = "rc".to_string(); + // So, while the direction we want is the same as the 3' protocols + // above, we separate out the case statement here for clarity. + // Further, we may consider changing this or making it more robust if + // and when we propagate more information about paired-end mappings. + ori = "fw".to_string(); } _ => { ori = "both".to_string(); From 06082570adea23766969450d8df317dec1a5e5dd Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Fri, 28 Jun 2024 23:15:07 -0400 Subject: [PATCH 12/16] Add field name to permit_list_info.json --- resources/permit_list_info.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/permit_list_info.json b/resources/permit_list_info.json index 6485307..86c795d 100644 --- a/resources/permit_list_info.json +++ b/resources/permit_list_info.json @@ -1,22 +1,27 @@ { "10xv2" : { "filename" : "10x_v2_permit.txt", + "cr_filename" : "737k-august-2016.txt", "url" : "https://umd.box.com/shared/static/jbs2wszgbj7k4ic2hass9ts6nhqkwq1p" }, "10xv2-5p" : { "filename" : "10x_v2_permit.txt", + "cr_filename" : "737k-august-2016.txt", "url" : "https://umd.box.com/shared/static/jbs2wszgbj7k4ic2hass9ts6nhqkwq1p" }, "10xv3" : { "filename" : "10x_v3_permit.txt", + "cr_filename" : "3M-febrary-2018.txt.gz", "url" : "https://umd.box.com/shared/static/vc9zd4qyjj581gvtolw5kj638wmg4f3s" }, "10xv3-5p" : { "filename" : "10x_v3_5p_permit.txt", + "cr_filename" : "3M-5pgex-jan-2023.txt.gz", "url" : "https://umd.box.com/shared/static/cbpv1c4zi6ty81nvcgy3pyta2oj7vea1.txt" }, "10xv4-3p" : { "filename" : "10x_v4_3p_permit.txt", + "cr_filename": "3M-3pgex-may-2023.txt.gz", "url" : "https://umd.box.com/shared/static/4a2q2lxngogaq4vkniptpu2gts5a38fb.txt" } } From 8ab152d145c35df7fff8f0151893c20c83ca3984 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Sat, 29 Jun 2024 00:28:28 -0400 Subject: [PATCH 13/16] Add extra info / suggestion In the case a network error occurs while trying to obtain the permit list metadata file. --- src/simpleaf_commands/quant.rs | 2 +- src/utils/af_utils.rs | 60 +++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index 2214adb..4d27b46 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -603,7 +603,7 @@ being used by simpleaf"#, alevin_gpl_cmd.arg("-d").arg(&ori); // add the filter mode - af_utils::add_to_args(&filter_meth, &mut alevin_gpl_cmd); + filter_meth.add_to_args(&mut alevin_gpl_cmd); let gpl_output = opts.output.join("af_quant"); alevin_gpl_cmd.arg("-o").arg(&gpl_output); diff --git a/src/utils/af_utils.rs b/src/utils/af_utils.rs index 275dc41..b384e54 100644 --- a/src/utils/af_utils.rs +++ b/src/utils/af_utils.rs @@ -65,6 +65,8 @@ pub enum FragmentTransformationType { TransformedIntoFifo(FifoXFormData), } +/// The different alevin-fry supported methods for +/// permit-list generation. #[derive(Debug, Clone)] pub enum CellFilterMethod { // cut off at this cell in @@ -87,29 +89,36 @@ pub enum CellFilterMethod { KneeFinding, } -pub fn add_to_args(fm: &CellFilterMethod, cmd: &mut std::process::Command) { - match fm { - CellFilterMethod::ForceCells(nc) => { - cmd.arg("--force-cells").arg(format!("{}", nc)); - } - CellFilterMethod::ExpectCells(nc) => { - cmd.arg("--expect-cells").arg(format!("{}", nc)); - } - CellFilterMethod::ExplicitList(l) => { - cmd.arg("--valid-bc").arg(l); - } - CellFilterMethod::UnfilteredExternalList(l, m) => { - cmd.arg("--unfiltered-pl") - .arg(l) - .arg("--min-reads") - .arg(format!("{}", m)); - } - CellFilterMethod::KneeFinding => { - cmd.arg("--knee-distance"); +impl CellFilterMethod { + /// How a [CellFilterMethod] should add itself to an + /// `alevin-fry` command. + pub fn add_to_args(&self, cmd: &mut std::process::Command) { + match self { + CellFilterMethod::ForceCells(nc) => { + cmd.arg("--force-cells").arg(format!("{}", nc)); + } + CellFilterMethod::ExpectCells(nc) => { + cmd.arg("--expect-cells").arg(format!("{}", nc)); + } + CellFilterMethod::ExplicitList(l) => { + cmd.arg("--valid-bc").arg(l); + } + CellFilterMethod::UnfilteredExternalList(l, m) => { + cmd.arg("--unfiltered-pl") + .arg(l) + .arg("--min-reads") + .arg(format!("{}", m)); + } + CellFilterMethod::KneeFinding => { + cmd.arg("--knee-distance"); + } } } } +/// The builtin geometry types that have special handling to +/// reduce necessary options in the common case, as well as the +/// `Other` varant that covers custom geometries. #[derive(EnumIter, PartialEq)] pub enum Chemistry { TenxV2, @@ -120,6 +129,7 @@ pub enum Chemistry { Other(String), } +/// `&str` representations of the different geometries. impl Chemistry { pub fn as_str(&self) -> &str { match self { @@ -133,6 +143,7 @@ impl Chemistry { } } +/// [Debug] representations of the different geometries. impl fmt::Debug for Chemistry { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -146,6 +157,7 @@ impl fmt::Debug for Chemistry { } } +/// The result of requesting a permit list pub enum PermitListResult { DownloadSuccessful(PathBuf), AlreadyPresent(PathBuf), @@ -241,9 +253,13 @@ pub fn get_permit_if_absent(af_home: &Path, chem: &Chemistry) -> Result()?; + let request_result = minreq::get(permit_dict_url).send().inspect_err( |err| { + error!("Could not obtain the permit list metadata from {}; encountered {:?}.", &permit_dict_url, &err); + error!("This may be a transient failure, or could be because the client is lacking a network connection. \ + In the latter case, please consider manually providing the appropriate permit list file directly \ + via the command line to avoid an attempt by simpleaf to automatically obtain it."); + })?; + let permit_dict: serde_json::Value = request_result.json::()?; let opt_chem_file: Option; let opt_dl_url: Option; // parse the JSON appropriately based on the chemistry we have From 3b96d01830e0b61216ebc1815daf6d9b8aa6c751 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Sat, 29 Jun 2024 22:17:54 -0400 Subject: [PATCH 14/16] copy gene_name_to_id.tsv to quant folder if we can --- src/simpleaf_commands/quant.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index 4d27b46..b24de1d 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -82,6 +82,8 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< let v: Value = prog_utils::inspect_af_home(af_home_path)?; let rp: ReqProgs = serde_json::from_value(v["prog_info"].clone())?; + let mut gene_id_to_name_opt: Option = None; + // figure out what type of index we expect let index_type; @@ -154,6 +156,17 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< t2g_map = Some(t2g_loc); } } + + // if the user used simpleaf for index construction, then we also built the + // reference and populated the gene_id_to_name.tsv file. See if we can grab + // that as well. + if let Some(index_parent) = index.parent() { + // we are doing index_dir/../ref/gene_id_to_name.tsv + let gene_name_path = index_parent.join("ref").join("gene_id_to_name.tsv"); + if gene_name_path.exists() && gene_name_path.is_file() { + gene_id_to_name_opt = Some(gene_name_path); + } + } } Ok(false) => { // at this point, we have inferred that simpleaf wasn't @@ -675,7 +688,7 @@ being used by simpleaf"#, info!("cmd : {:?}", alevin_quant_cmd); - let input_files = vec![gpl_output, t2g_map_file]; + let input_files = vec![gpl_output.clone(), t2g_map_file]; prog_utils::check_files_exist(&input_files)?; let quant_start = Instant::now(); @@ -709,6 +722,22 @@ being used by simpleaf"#, } }); + // If we had a gene_id_to_name.tsv file handy, copy it over into the + // quantification directory. + if let Some(gene_name_path) = gene_id_to_name_opt { + let target_path = gpl_output.join("gene_id_to_name.tsv"); + match std::fs::copy(&gene_name_path, &target_path) { + Ok(_) => { + info!("successfully copied the gene_name_to_id.tsv file into the quantification directory."); + } + Err(err) => { + warn!("could not successfully copy gene_id_to_name file from {:?} to {:?} because of {:?}", + gene_name_path, target_path, err + ); + } + } + } + // write the relevant info about // our run to file. std::fs::write( From 8597635edde981f3afab367d008e39d157858ba3 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 1 Jul 2024 13:11:59 -0400 Subject: [PATCH 15/16] feat: Add refresh-prog-info subcommand feat: copy over gene_id_to_names.tsv to quant directory feat: support new piscem geometry flags --- src/main.rs | 2 ++ src/simpleaf_commands.rs | 5 +++++ src/simpleaf_commands/indexing.rs | 1 + src/simpleaf_commands/quant.rs | 2 ++ src/simpleaf_commands/refresh.rs | 27 +++++++++++++++++++++++++++ src/utils/prog_utils.rs | 19 ++++++++++++++++++- 6 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/simpleaf_commands/refresh.rs diff --git a/src/main.rs b/src/main.rs index e967cbc..4d9530c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,6 +77,8 @@ fn main() -> anyhow::Result<()> { } Commands::Inspect {} => inspect_simpleaf(crate_version!(), af_home_path), + Commands::RefreshProgInfo {} => refresh_prog_info(af_home_path), + // if we are building the reference and indexing Commands::Index(index_opts) => build_ref_and_index(af_home_path.as_path(), index_opts), diff --git a/src/simpleaf_commands.rs b/src/simpleaf_commands.rs index 6dbc6d5..ef4faa3 100644 --- a/src/simpleaf_commands.rs +++ b/src/simpleaf_commands.rs @@ -1,6 +1,9 @@ pub mod inspect; pub use self::inspect::inspect_simpleaf; +pub mod refresh; +pub use self::refresh::refresh_prog_info; + pub mod chemistry; pub use self::chemistry::add_chemistry; @@ -473,6 +476,8 @@ pub enum Commands { #[arg(short, long)] alevin_fry: Option, }, + /// refreshes version information associated with programs used by simpleaf + RefreshProgInfo {}, /// simpleaf workflow related command set Workflow(WorkflowOpts), } diff --git a/src/simpleaf_commands/indexing.rs b/src/simpleaf_commands/indexing.rs index bc0142f..ca71d03 100644 --- a/src/simpleaf_commands/indexing.rs +++ b/src/simpleaf_commands/indexing.rs @@ -37,6 +37,7 @@ pub fn build_ref_and_index(af_home_path: &Path, opts: IndexOpts) -> anyhow::Resu // Read the JSON contents of the file as an instance of `User`. let rp: ReqProgs = serde_json::from_value(v["prog_info"].clone())?; + rp.issue_recommended_version_messages(); // we are building a custom spliced+intronic reference // make sure that a read length is available / was provided. // if fasta.is_some() && matches!(ref_type, ReferenceType::SplicedIntronic) && rlen.is_none() { diff --git a/src/simpleaf_commands/quant.rs b/src/simpleaf_commands/quant.rs index b24de1d..9d19898 100644 --- a/src/simpleaf_commands/quant.rs +++ b/src/simpleaf_commands/quant.rs @@ -82,6 +82,8 @@ pub fn map_and_quant(af_home_path: &Path, opts: MapQuantOpts) -> anyhow::Result< let v: Value = prog_utils::inspect_af_home(af_home_path)?; let rp: ReqProgs = serde_json::from_value(v["prog_info"].clone())?; + rp.issue_recommended_version_messages(); + let mut gene_id_to_name_opt: Option = None; // figure out what type of index we expect diff --git a/src/simpleaf_commands/refresh.rs b/src/simpleaf_commands/refresh.rs new file mode 100644 index 0000000..14a5fbb --- /dev/null +++ b/src/simpleaf_commands/refresh.rs @@ -0,0 +1,27 @@ +use crate::utils::prog_utils::*; + +use anyhow::Context; +use serde_json::{json, Value}; +use std::path::PathBuf; + +pub fn refresh_prog_info(af_home_path: PathBuf) -> anyhow::Result<()> { + // Read the JSON contents of the file as an instance of `User`. + let v: Value = inspect_af_home(af_home_path.as_path())?; + let current_rp: ReqProgs = serde_json::from_value(v["prog_info"].clone())?; + + let new_rp = get_required_progs_from_paths( + current_rp.salmon.map(|p| p.exe_path), + current_rp.piscem.map(|p| p.exe_path), + current_rp.alevin_fry.map(|p| p.exe_path), + )?; + + let simpleaf_info_file = af_home_path.join("simpleaf_info.json"); + let simpleaf_info = json!({ "prog_info": new_rp }); + + std::fs::write( + &simpleaf_info_file, + serde_json::to_string_pretty(&simpleaf_info).unwrap(), + ) + .with_context(|| format!("could not write {}", simpleaf_info_file.display()))?; + Ok(()) +} diff --git a/src/utils/prog_utils.rs b/src/utils/prog_utils.rs index c51da67..4c6db6f 100644 --- a/src/utils/prog_utils.rs +++ b/src/utils/prog_utils.rs @@ -7,7 +7,7 @@ use std::ffi::{OsStr, OsString}; use std::path::{Path, PathBuf}; use std::process::Command; use std::sync::Once; -use tracing::{debug, error, info}; +use tracing::{debug, error, info, warn}; use which::which; // The below functions are taken from the [`execute`](https://crates.io/crates/execute) @@ -170,6 +170,23 @@ pub struct ReqProgs { pub alevin_fry: Option, } +impl ReqProgs { + pub fn issue_recommended_version_messages(&self) { + // Currently (07/01/2024) want to recommend piscem >= 0.9.0 + if let Some(ref piscem_info) = self.piscem { + let desired_ver = VersionReq::parse(">=0.9.0").unwrap(); + let current_ver = Version::parse(&piscem_info.version).unwrap(); + if desired_ver.matches(¤t_ver) { + // nothing to do here + } else { + warn!("It is recommended to use piscem version {}, but currently version {} is being used. \ + Please consider installing the latest version of piscem and setting simpleaf to use this \ + new version by running the `refresh-prog-info` command.", &desired_ver, ¤t_ver); + } + } + } +} + #[allow(dead_code)] pub fn check_version_constraints>( prog_name: &str, From fa42a0697a9dd4096f4dc5d79e12b9e84711f970 Mon Sep 17 00:00:00 2001 From: Rob Patro Date: Mon, 1 Jul 2024 13:14:24 -0400 Subject: [PATCH 16/16] update deps --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c98271..fcbfad5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2315,9 +2315,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.118" +version = "1.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index 03fa3ae..79302b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", default-features = true, features = ["env-filter"] } semver = "^1.0.23" serde = {version = "1.0.203", features = ["derive"]} -serde_json = "1.0.118" +serde_json = "1.0.119" time = {version = "^0.3.36", features = ["macros", "formatting", "parsing", "serde", "serde-human-readable"]} which = "^6.0.1" jrsonnet-evaluator = "0.5.0-pre95"