diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000..c6bb27f --- /dev/null +++ b/.bazelignore @@ -0,0 +1,3 @@ +# Nested consumer workspace with its own MODULE.bazel; built by +# integration_tests/run_integration_test.sh, not as part of //... +integration_tests diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..cb3cdaa --- /dev/null +++ b/.bazelrc @@ -0,0 +1,34 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ +common --registry=https://bcr.bazel.build + +# score_tooling (dev dependency) transitively brings android_sdk_repository +# into the graph; an empty ANDROID_HOME keeps it inert on stripped runners. +common --repo_env=ANDROID_HOME= + +test --test_output=errors + +# Rust toolchain for the analysis-test fixtures (same registration as the +# consumer repos; the standard Ferrocene toolchain of score_toolchains_rust). +common --extra_toolchains=@score_toolchains_rust//toolchains/ferrocene:ferrocene_x86_64_unknown_linux_gnu + +# Static analysis of the Python (ruff, pylint, ty) as aspects; findings fail +# the build. Usage: bazel build --config=lint //score_coverage/... //tools/... +build:lint --aspects=//tools:linters.bzl%ruff,//tools:linters.bzl%pylint,//tools:linters.bzl%ty +build:lint --output_groups=+rules_lint_human +build:lint --@aspect_rules_lint//lint:fail_on_violation + +# Per-developer overrides (disk cache, etc.). Must stay last: bazelrc is last-wins. +try-import %workspace%/user.bazelrc diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000..acd405b --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +8.6.0 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8db10ee --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,10 @@ +# 👋 Code owners help maintain this repository and keep it aligned with our technical vision. +# You're responsible for reviewing changes, ensuring quality, and guiding contributors. +# You're also encouraged to help triage issues and keep discussions constructive and focused. +# Ownership can be shared, delegated, or updated as the project evolves. + +# For more information about CODEOWNERS, see: +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners + +# https://github.com/orgs/eclipse-score/teams/infrastructure-maintainers +* @AlexanderLanin @MaximilianSoerenPollak @dcalavrezo-qorix @nradakovic diff --git a/.github/actions/gitlint/action.yml b/.github/actions/gitlint/action.yml new file mode 100644 index 0000000..2857a41 --- /dev/null +++ b/.github/actions/gitlint/action.yml @@ -0,0 +1,41 @@ +# ******************************************************************************* +# Copyright (c) 2024 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: "Gitlint Action" +description: "An action to install and run Gitlint on PR commits" +inputs: + pr-number: + description: "Pull Request number used to fetch commits" + required: true + base-branch: + description: "Base branch to compare commits against (default: origin/main)" + default: "origin/main" + required: false +runs: + using: "docker" + image: "jorisroovers/gitlint:0.19.1" + entrypoint: /bin/sh + args: + - -c + - | + git config --global --add safe.directory /github/workspace && \ + git fetch origin +refs/heads/main:refs/remotes/origin/main && \ + git fetch origin +refs/pull/${{ inputs.pr-number }}/head && \ + if ! gitlint --commits origin/main..HEAD; then \ + echo -e "\nWARNING: Your commit message does not follow the required format." && \ + echo "Formatting rules: https://eclipse-score.github.io/score/process/guidance/git/index.html" && \ + echo -e "To fix your commit message, run:\n" && \ + echo " git commit --amend" && \ + echo "Then update your commit (fix gitlint warnings). Finally, force-push:" && \ + echo " git push --force-with-lease" && \ + exit 1; \ + fi diff --git a/.github/workflows/copyright.yml b/.github/workflows/copyright.yml new file mode 100644 index 0000000..a69d02a --- /dev/null +++ b/.github/workflows/copyright.yml @@ -0,0 +1,25 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Copyright checks +on: + pull_request: + types: [opened, reopened, synchronize] + merge_group: + types: [checks_requested] +permissions: + contents: read +jobs: + copyright-check: + uses: eclipse-score/cicd-workflows/.github/workflows/copyright.yml@93aac16ada7d247bbb6ae926509ddea74cf5213a # v0.0.2 + with: + bazel-target: "run //tools:copyright.check" diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..3b74800 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,39 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Formatting checks +on: + pull_request: + types: [opened, reopened, synchronize] + merge_group: + types: [checks_requested] +permissions: + contents: read +env: + ANDROID_HOME: "" + ANDROID_SDK_ROOT: "" +jobs: + formatting-check: + runs-on: ubuntu-24.04 + steps: + - name: Checkout repository + uses: actions/checkout@v7.0.1 + - uses: castler/setup-bazel@cache-optimized + with: + bazelisk-cache: true + disk-cache: format + repository-cache: true + cache-optimized: true + cache-save: ${{ github.ref == 'refs/heads/main' }} + - name: Run formatting checks + # score_tooling >= 2 tags format tests `manual`; lift the tag filter. + run: bazel test --test_tag_filters= //tools:format.check diff --git a/.github/workflows/gitlint.yml b/.github/workflows/gitlint.yml new file mode 100644 index 0000000..567223e --- /dev/null +++ b/.github/workflows/gitlint.yml @@ -0,0 +1,33 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Gitlint check +on: + pull_request: + types: [opened, synchronize, reopened] +permissions: + contents: read +jobs: + lint-commits: + name: check-commit-messages + runs-on: ubuntu-24.04 + steps: + - name: Checkout code + uses: actions/checkout@v7.0.1 + with: + fetch-depth: 0 + - name: Run Gitlint Action + if: ${{ github.event_name == 'pull_request' }} + uses: ./.github/actions/gitlint + with: + pr-number: ${{ github.event.number }} + base-branch: ${{ github.event.pull_request.base.ref }} diff --git a/.github/workflows/license_check.yml b/.github/workflows/license_check.yml new file mode 100644 index 0000000..0667027 --- /dev/null +++ b/.github/workflows/license_check.yml @@ -0,0 +1,28 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: License check preparation +on: + pull_request_target: + types: [opened, reopened, synchronize] + merge_group: + types: [checks_requested] +permissions: + pull-requests: write + issues: write +jobs: + license-check: + uses: eclipse-score/cicd-workflows/.github/workflows/license-check.yml@main + with: + repo-url: "${{ github.server_url }}/${{ github.repository }}" + secrets: + dash-api-token: ${{ secrets.ECLIPSE_GITLAB_API_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..ac943c4 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,118 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Tests +on: + pull_request: + types: [opened, reopened, synchronize] + push: + branches: + - main + merge_group: + types: [checks_requested] +concurrency: + group: tests-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} +permissions: + contents: write + pages: write + pull-requests: write + id-token: write +env: + ANDROID_HOME: "" + ANDROID_SDK_ROOT: "" +jobs: + unit_tests: + runs-on: ubuntu-24.04 + steps: + - name: Checkout repository + uses: actions/checkout@v7.0.1 + - name: Free Disk Space (Ubuntu) + uses: eclipse-score/more-disk-space@v1 + with: + level: 4 + - uses: castler/setup-bazel@cache-optimized + with: + bazelisk-cache: true + disk-cache: unit_tests + repository-cache: true + cache-optimized: true + cache-save: ${{ github.ref == 'refs/heads/main' }} + - name: Build everything + run: bazel build --lockfile_mode=error //... + - name: Run unit and Starlark analysis tests + run: bazel test --lockfile_mode=error //score_coverage/... //tools/... + - name: Static analysis of the Python (ruff, pylint, ty; findings fail the build) + run: bazel build --lockfile_mode=error --config=lint //score_coverage/... //tools/... + - name: Measure structural coverage of the tool itself (coverage.py) + run: bazel coverage --lockfile_mode=error --combined_report=lcov //score_coverage/tests:all + - name: "Gate structural coverage (ratchet, raise as tests land; target 100/100)" + run: | + bazel run --lockfile_mode=error //tools:self_coverage_gate -- \ + --min-lines 95 --min-branches 87 --summary-md "$GITHUB_STEP_SUMMARY" + - name: Ensure the lockfile is up to date + run: | + bazel mod deps --lockfile_mode=update + git diff --exit-code MODULE.bazel.lock + - name: Collect JUnit results for the documentation build + # docs-as-code links testcases to requirements from these files + # (tests-report//test.xml). + run: | + rm -rf tests-report && mkdir -p tests-report/score_coverage + rsync -amL --include='*/' --include='test.xml' --exclude='*' bazel-testlogs/score_coverage/ tests-report/score_coverage/ + echo "collected $(find tests-report -name test.xml | wc -l) test.xml files" + - uses: actions/upload-artifact@v4 + with: + name: tests-report + path: tests-report + if-no-files-found: error + retention-days: 3 + integration_tests: + runs-on: ubuntu-24.04 + steps: + - name: Checkout repository + uses: actions/checkout@v7.0.1 + - name: Free Disk Space (Ubuntu) + uses: eclipse-score/more-disk-space@v1 + with: + level: 4 + - uses: castler/setup-bazel@cache-optimized + with: + bazelisk-cache: true + disk-cache: integration_tests + repository-cache: true + cache-optimized: true + cache-save: ${{ github.ref == 'refs/heads/main' }} + - name: Run the end-to-end pipeline test (C++ + Rust consumer workspace) + run: integration_tests/run_integration_test.sh + - name: Upload coverage report of the integration workspace + if: always() + uses: actions/upload-artifact@v4 + with: + name: integration_coverage_report + path: integration_tests/coverage_artifact + if-no-files-found: ignore + retention-days: 10 + docs: + needs: unit_tests + uses: eclipse-score/cicd-workflows/.github/workflows/docs.yml@93aac16ada7d247bbb6ae926509ddea74cf5213a # v0.0.2 + permissions: + contents: write + pages: write + pull-requests: write + id-token: write + with: + # docs() lives in //docs (the root package must not load dev deps), so + # the output is docs/_build; the reusable workflow archives _build. + bazel-target: "//docs:docs && mv docs/_build _build" + tests-report-artifact: tests-report + retention-days: 3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50f17db --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +bazel-* +external +.vscode/ +.clwb/ +user.bazelrc + +__pycache__ +.ruff_cache/ + +# Outputs of integration_tests/run_integration_test.sh +integration_tests/coverage_artifacts.zip +integration_tests/lcov.dat +integration_tests/coverage_linux/ +integration_tests/summary.md +integration_tests/step_summary.md +integration_tests/coverage_artifact/ +integration_tests/actual_normalised.dat +integration_tests/expected_normalised.dat +integration_tests/typo_dir/ +integration_tests/typo.log +integration_tests/report.backup + +# Generated by docs-as-code on every docs build +ubproject.toml +_build/ +tests-report/ diff --git a/.gitlint b/.gitlint new file mode 100644 index 0000000..7cb86ee --- /dev/null +++ b/.gitlint @@ -0,0 +1,22 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +# Commit message rules, aligned with eclipse-score/score: 72-character titles, +# body lines unrestricted (B1) so DCO sign-off lines with long addresses pass. +[general] +ignore=T3,T5,B1,B5,B6,B7 +regex-style-search=true + +[title-max-length] +line-length=72 + +[body-first-line-empty] diff --git a/BUILD b/BUILD new file mode 100644 index 0000000..9ddfc0c --- /dev/null +++ b/BUILD @@ -0,0 +1,85 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_cc//cc/toolchains:args.bzl", "cc_args") +load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") + +# IMPORTANT: this file is loaded by every consumer of @score_coverage. It must +# only load from the module's runtime dependencies (never from dev +# dependencies such as score_tooling): dev deps are dropped when this module is +# not the root, and a failing load here breaks the whole @score_coverage// +# package for the consumer. Repository hygiene targets live in //tools. +package(default_visibility = ["//visibility:public"]) + +exports_files([ + "MODULE.bazel", + "pyproject.toml", +]) + +# ============================================================================= +# Consumer-facing labels. Everything a consumer references lives at the root +# of this module: +# load("@score_coverage//:defs.bzl", "score_coverage_scope", "score_coverage_reporter") +# coverage:llvm_cov --coverage_output_generator=@score_coverage//:merger +# bazel run @score_coverage//:generate_coverage_html -- ... +# llvm.toolchain(extra_known_features = ["@score_coverage//:enable_llvm_coverage_for_death_tests"]) +# The implementation lives in //score_coverage. +# ============================================================================= + +alias( + name = "merger", + actual = "//score_coverage:merger", +) + +alias( + name = "generate_coverage_html", + actual = "//score_coverage:generate_coverage_html", +) + +# Standalone entry points of the justification layer (generate_coverage_html +# calls them in-process; these aliases keep them runnable on their own). +alias( + name = "justify", + actual = "//score_coverage:justify", +) + +alias( + name = "effective_coverage", + actual = "//score_coverage:effective_coverage", +) + +alias( + name = "coverage_summary", + actual = "//score_coverage:coverage_summary", +) + +# These compile time options are required to cover abnormal termination cases +# (death tests). LLVM provides them in combination with a specific profile +# setting which is enabled in Bazel via LLVM_PROFILE_CONTINUOUS_MODE. +cc_args( + name = "runtime_relocation_args", + actions = [ + "@rules_cc//cc/toolchains/actions:compile_actions", + "@rules_cc//cc/toolchains/actions:link_actions", + ], + args = [ + "-mllvm", + "-runtime-counter-relocation", + ], +) + +cc_feature( + name = "enable_llvm_coverage_for_death_tests", + args = [":runtime_relocation_args"], + feature_name = "enable_llvm_coverage_for_death_tests", +) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..f40ce2a --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,80 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# score_coverage: LLVM source-based code coverage pipeline for Eclipse S-CORE. +# The version is intentionally absent; the S-CORE Bazel registry patches it in +# from the release tag (same mechanism as score_tooling). +module(name = "score_coverage") + +############################################################################### +# Runtime dependencies of the pipeline (visible to consumers) +############################################################################### +bazel_dep(name = "platforms", version = "1.0.0") +bazel_dep(name = "rules_cc", version = "0.2.16") # cc_args/cc_feature for the death-test feature +bazel_dep(name = "rules_python", version = "1.8.5") + +# CrateInfo provider consumed by the coverage-scope aspect (coverage_scope.bzl). +bazel_dep(name = "rules_rust", version = "0.68.2-score") + +############################################################################### +# Python toolchain +############################################################################### +# Python 3.12 only: every S-CORE consumer defaults to 3.12, and the qualified +# environment pins one interpreter version. +PYTHON_VERSION = "3.12" + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + configure_coverage_tool = True, + is_default = True, + python_version = PYTHON_VERSION, +) + +############################################################################### +# Pip hub (pyyaml for justify.py). Hub name is unique to this module so it +# never collides with the legacy pip_coverage hub still declared by +# score_tooling < 3. +############################################################################### +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + envsubst = ["PIP_INDEX_URL"], + extra_pip_args = ["--index-url=${PIP_INDEX_URL:-https://pypi.org/simple/}"], + hub_name = "pip_score_coverage", + python_version = PYTHON_VERSION, + requirements_lock = "//score_coverage:requirements_3_12.txt", +) +use_repo(pip, "pip_score_coverage") + +############################################################################### +# Development-only dependencies (repository hygiene: copyright, formatting) +############################################################################### +bazel_dep(name = "score_tooling", version = "2.2.0", dev_dependency = True) + +# use_format_targets() (from score_tooling) loads these from the ROOT module's +# repo mapping, so the root has to declare them itself. +bazel_dep(name = "aspect_rules_lint", version = "2.7.1", dev_dependency = True) +bazel_dep(name = "buildifier_prebuilt", version = "8.5.1", dev_dependency = True) + +# Starlark analysis tests for the coverage_scope rule/aspect, incl. Rust fixtures +# built with the standard Ferrocene toolchain (registered in .bazelrc). +bazel_dep(name = "rules_testing", version = "0.9.0", dev_dependency = True) +bazel_dep(name = "score_toolchains_rust", version = "0.10.0", dev_dependency = True) + +############################################################################### +# Documentation (docs-as-code with the S-CORE process needs for `satisfies` / +# `realizes` links). NOT dev dependencies: reference_integration and the Tool +# Verification Report in eclipse-score/score consume //docs:needs_json and the +# docs bundle of this module, which requires these to resolve from a consumer. +############################################################################### +bazel_dep(name = "score_docs_as_code", version = "8.1.1") +bazel_dep(name = "score_process_description", version = "2.1.2") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 0000000..939ccf6 --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,5919 @@ +{ + "lockFileVersion": 24, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20220623.1/MODULE.bazel": "73ae41b6818d423a11fd79d95aedef1258f304448193d4db4ff90e5e7a0f076c", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.0/MODULE.bazel": "98dc378d64c12a4e4741ad3362f87fb737ee6a0886b2d90c3cdbb4d93ea3e0bf", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20240722.0/MODULE.bazel": "88668a07647adbdc14cb3a7cd116fb23c9dda37a90a1681590b6c9d8339a5b84", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/source.json": "d725d73707d01bb46ab3ca59ba408b8e9bd336642ca77a2269d4bfb8bbfd413d", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.17.1/MODULE.bazel": "655c922ab1209978a94ef6ca7d9d43e940cd97d9c172fb55f94d91ac53f8610b", + "https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458", + "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", + "https://bcr.bazel.build/modules/apple_support/1.24.1/MODULE.bazel": "f46e8ddad60aef170ee92b2f3d00ef66c147ceafea68b6877cb45bd91737f5f8", + "https://bcr.bazel.build/modules/apple_support/1.24.1/source.json": "cf725267cbacc5f028ef13bb77e7f2c2e0066923a4dab1025e4a0511b1ed258a", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.31.2/MODULE.bazel": "7bee702b4862612f29333590f4b658a5832d433d6f8e4395f090e8f4e85d442f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.38.0/MODULE.bazel": "6307fec451ba9962c1c969eb516ebfe1e46528f7fa92e1c9ac8646bef4cdaa3f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.42.2/MODULE.bazel": "2e0d8ab25c57a14f56ace1c8e881b69050417ff91b2fb7718dc00d201f3c3478", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "e118477db5c49419a88d78ebc7a2c2cea9d49600fe0f490c1903324a2c16ecd9", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.11.0/MODULE.bazel": "cb1ba9f9999ed0bc08600c221f532c1ddd8d217686b32ba7d45b0713b5131452", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.16.0/MODULE.bazel": "852f9ebbda017572a7c113a2434592dd3b2f55cd9a0faea3d4be5a09a59e4900", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.20.0/MODULE.bazel": "c5565bac49e1973227225b441fad1c938d498d83df62dc5da95b2fab0f0626a2", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.0/MODULE.bazel": "7fe0191f047d4fe4a4a46c1107e2350cbb58a8fc2e10913aa4322d3190dec0bf", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.0/source.json": "369df5b7f2eae82f200fff95cf1425f90dee90a0d0948122060b48150ff0e224", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.9.3/MODULE.bazel": "66baf724dbae7aff4787bf2245cc188d50cb08e07789769730151c0943587c14", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/MODULE.bazel": "77dc393c43ad79398b05865444c5200c6f1aae6765615544f2c7730b5858d533", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/source.json": "062b1d3dba8adcfeb28fe60c185647f5a53ec0487ffe93cf0ae91566596e4b49", + "https://bcr.bazel.build/modules/aspect_rules_js/1.33.1/MODULE.bazel": "db3e7f16e471cf6827059d03af7c21859e7a0d2bc65429a3a11f005d46fc501b", + "https://bcr.bazel.build/modules/aspect_rules_js/1.40.0/MODULE.bazel": "01a1014e95e6816b68ecee2584ae929c7d6a1b72e4333ab1ff2d2c6c30babdf1", + "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", + "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/MODULE.bazel": "74bf20a7a6bd5f2be09607fdb4196cfd6f203422ea271752ec2b1afe95426101", + "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/source.json": "411ec9d79d6f5fe8a083359588c21d01a5b48d88a2cbd334a4c90365015b7836", + "https://bcr.bazel.build/modules/aspect_rules_lint/0.12.0/MODULE.bazel": "e767c5dbfeb254ec03275a7701b5cfde2c4d2873676804bc7cb27ddff3728fed", + "https://bcr.bazel.build/modules/aspect_rules_lint/2.5.0/MODULE.bazel": "24f49acb3b8375fa138ba6ab53bcf517ae92529770a04ab04d47c958ff47b63e", + "https://bcr.bazel.build/modules/aspect_rules_lint/2.7.1/MODULE.bazel": "52f070e52379d262523676b6c5db430b6615849c68c001c3e16d72c6ac411b18", + "https://bcr.bazel.build/modules/aspect_rules_lint/2.7.1/source.json": "afc63f90e4fbcdcb9ec01a472609b8b778efb86156ae34ff4a58a1a2262489d7", + "https://bcr.bazel.build/modules/aspect_rules_py/1.4.0/MODULE.bazel": "6fd29b93207a31445d5d3ab9d9882fd5511e43c95e8e82e7492872663720fd44", + "https://bcr.bazel.build/modules/aspect_rules_py/1.4.0/source.json": "fb1ba946478fb6dbb26d49307d756b0fd2ff88be339af23c39c0397d59143d2c", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/MODULE.bazel": "d0045b5eabb012be550a609589b3e5e47eba682344b19cfd9365d4d896ed07df", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/source.json": "5593e3f1cd0dd5147f7748e163307fd5c2e1077913d6945b58739ad8d770a290", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/source.json": "605086bbc197743a0d360f7ddc550a1d4dfa0441bc807236e17170f636153348", + "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd", + "https://bcr.bazel.build/modules/bazel_features/1.0.0/MODULE.bazel": "d7f022dc887efb96e1ee51cec7b2e48d41e36ff59a6e4f216c40e4029e1585bf", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.20.0/MODULE.bazel": "8b85300b9c8594752e0721a37210e34879d23adc219ed9dc8f4104a4a1750920", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", + "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", + "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", + "https://bcr.bazel.build/modules/bazel_features/1.39.0/source.json": "f63cbeb4c602098484d57001e5a07d31cb02bbccde9b5e2c9bf0b29d05283e93", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_jar_jar/0.1.7/MODULE.bazel": "d2736a1dbfd8f72befc532823b5112f2597a28064ce4aac280c65bee7d8830a0", + "https://bcr.bazel.build/modules/bazel_jar_jar/0.1.7/source.json": "f894f62528821f749b8d57fb8fb737b13f6cfacde422c88019d4c48077ad0d96", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-beta.1/MODULE.bazel": "407729e232f611c3270005b016b437005daa7b1505826798ea584169a476e878", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/source.json": "d353c410d47a8b65d09fa98e83d57ebec257a2c2b9c6e42d6fda1cb25e5464a5", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/source.json": "a2d30458fd86cf022c2b6331e652526fa08e17573b2f5034a9dbcacdf9c2583c", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20211025-d4f1ab9/MODULE.bazel": "6ee6353f8b1a701fe2178e1d925034294971350b6d3ac37e67e5a7d463267834", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20230215-5c22014/MODULE.bazel": "4b03dc0d04375fa0271174badcd202ed249870c8e895b26664fd7298abea7282", + "https://bcr.bazel.build/modules/boringssl/0.0.0-20240530-2db0eb3/MODULE.bazel": "d0405b762c5e87cd445b7015f2b8da5400ef9a8dbca0bfefa6c1cea79d528a97", + "https://bcr.bazel.build/modules/boringssl/0.20240913.0/MODULE.bazel": "fcaa7503a5213290831a91ed1eb538551cf11ac0bc3a6ad92d0fef92c5bd25fb", + "https://bcr.bazel.build/modules/boringssl/0.20241024.0/MODULE.bazel": "b540cff73d948cb79cb0bc108d7cef391d2098a25adabfda5043e4ef548dbc87", + "https://bcr.bazel.build/modules/boringssl/0.20241024.0/source.json": "d843092e682b84188c043ac742965d7f96e04c846c7e338187e03238674909a9", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.4.0/MODULE.bazel": "37389c6b5a40c59410b4226d3bb54b08637f393d66e2fa57925c6fcf68e64bf4", + "https://bcr.bazel.build/modules/buildifier_prebuilt/7.3.1/MODULE.bazel": "537faf0ad9f5892910074b8e43b4c91c96f1d5d86b6ed04bdbe40cf68aa48b68", + "https://bcr.bazel.build/modules/buildifier_prebuilt/8.2.0.2/MODULE.bazel": "a9b689711d5b69f9db741649b218c119b9fdf82924ba390415037e09798edd03", + "https://bcr.bazel.build/modules/buildifier_prebuilt/8.5.1/MODULE.bazel": "77f2a1958d1d07376dd3ce3ae16540f2c1b01921c1fd21930827271260e75a66", + "https://bcr.bazel.build/modules/buildifier_prebuilt/8.5.1/source.json": "ae9f3d9dc7bec033976cf47165a78788bebad2b5c272241063ae31bad8664fd4", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/c-ares/1.15.0/MODULE.bazel": "ba0a78360fdc83f02f437a9e7df0532ad1fbaa59b722f6e715c11effebaa0166", + "https://bcr.bazel.build/modules/c-ares/1.15.0/source.json": "5e3ed991616c5ec4cc09b0893b29a19232de4a1830eb78c567121bfea87453f7", + "https://bcr.bazel.build/modules/cel-spec/0.15.0/MODULE.bazel": "e1eed53d233acbdcf024b4b0bc1528116d92c29713251b5154078ab1348cb600", + "https://bcr.bazel.build/modules/cel-spec/0.15.0/source.json": "ab7dccdf21ea2261c0f809b5a5221a4d7f8b580309f285fdf1444baaca75d44a", + "https://bcr.bazel.build/modules/civetweb/1.16/MODULE.bazel": "46a38f9daeb57392e3827fce7d40926be0c802bd23cdd6bfd3a96c804de42fae", + "https://bcr.bazel.build/modules/civetweb/1.16/source.json": "ba8b9585adb8355cb51b999d57172fd05e7a762c56b8d4bac6db42c99de3beb7", + "https://bcr.bazel.build/modules/curl/8.4.0/MODULE.bazel": "0bc250aa1cb69590049383df7a9537c809591fcf876c620f5f097c58fdc9bc10", + "https://bcr.bazel.build/modules/curl/8.7.1/MODULE.bazel": "088221c35a2939c555e6e47cb31a81c15f8b59f4daa8009b1e9271a502d33485", + "https://bcr.bazel.build/modules/curl/8.7.1/source.json": "bf9890e809717445b10a3ddc323b6d25c46631589c693a232df8310a25964484", + "https://bcr.bazel.build/modules/cython/3.0.11-1/MODULE.bazel": "868b3f5c956c3657420d2302004c6bb92606bfa47e314bab7f2ba0630c7c966c", + "https://bcr.bazel.build/modules/cython/3.0.11-1/source.json": "da318be900b8ca9c3d1018839d3bebc5a8e1645620d0848fa2c696d4ecf7c296", + "https://bcr.bazel.build/modules/diff.bzl/0.5.1/MODULE.bazel": "bad8dd444e512b6fcbcd969d6385cd6bc093d4c12e5640fb1f0ace2282f99ef9", + "https://bcr.bazel.build/modules/diff.bzl/0.5.1/source.json": "64571044143273ff8adb322c0f7acefca36f9589ff37a743e3cac9c35ce6b010", + "https://bcr.bazel.build/modules/download_utils/1.2.2/MODULE.bazel": "7d185ec9dd3c5ee277f269e3a8e5f09b9de4cb7ba34d06b93dce9bf41c1279f8", + "https://bcr.bazel.build/modules/download_utils/1.2.2/source.json": "c88be2bc48c98371d35665b805f307a647c98c83327345c918d9088822d77928", + "https://bcr.bazel.build/modules/envoy_api/0.0.0-20241214-918efc9/MODULE.bazel": "24e05f6f52f37be63a795192848555a2c8c855e7814dbc1ed419fb04a7005464", + "https://bcr.bazel.build/modules/envoy_api/0.0.0-20241214-918efc9/source.json": "212043ab69d87f7a04aa4f627f725b540cff5e145a3a31a9403d8b6ec2e920c9", + "https://bcr.bazel.build/modules/flatbuffers/25.9.23/MODULE.bazel": "32753ba60bf3bacfe7737c0f3e8e3e55624b19af5d398c485580d57492d145d8", + "https://bcr.bazel.build/modules/flatbuffers/25.9.23/source.json": "a2116f0017f6896353fd3abf65ef2b89b0a257e8a87f395c5000f53934829f31", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/MODULE.bazel": "f1b7bb2dd53e8f2ef984b39485ec8a44e9076dda5c4b8efd2fb4c6a6e856a31d", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.3/source.json": "ebe931bfe362e4b41e59ee00a528db6074157ff2ced92eb9e970acab2e1089c9", + "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", + "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.44.0/MODULE.bazel": "fd3177ca0938da57a1e416cad3f39b9c4334defbc717e89aba9d9ddbbb0341da", + "https://bcr.bazel.build/modules/gazelle/0.44.0/source.json": "7fb65ef9c1ce470d099ca27fd478673d9d64c844af28d0d472b0874c7d590cb6", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/google_benchmark/1.8.4/MODULE.bazel": "c6d54a11dcf64ee63545f42561eda3fd94c1b5f5ebe1357011de63ae33739d5e", + "https://bcr.bazel.build/modules/google_benchmark/1.8.4/source.json": "84590f7bc5a1fd99e1ef274ee16bb41c214f705e62847b42e705010dfa81fe53", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240326-1c8d509c5/MODULE.bazel": "a4b7e46393c1cdcc5a00e6f85524467c48c565256b22b5fae20f84ab4a999a68", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240819-fe8ba054a/MODULE.bazel": "117b7c7be7327ed5d6c482274533f2dbd78631313f607094d4625c28203cacdf", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240819-fe8ba054a/source.json": "b31fc7eb283a83f71d2e5bfc3d1c562d2994198fa1278409fbe8caec3afc1d3e", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.13.0/MODULE.bazel": "369533f4a302dc7d9ad1cd9a09a9e820a1d9a4011fad2dfa636b5bb225b9a6c7", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/MODULE.bazel": "827f54f492a3ce549c940106d73de332c2b30cebd0c20c0bc5d786aba7f116cb", + "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/source.json": "3664514073a819992320ffbce5825e4238459df344d8b01748af2208f8d2e1eb", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/grpc-java/1.62.2/MODULE.bazel": "99b8771e8c7cacb130170fed2a10c9e8fed26334a93e73b42d2953250885a158", + "https://bcr.bazel.build/modules/grpc-java/1.66.0/MODULE.bazel": "86ff26209fac846adb89db11f3714b3dc0090fb2fb81575673cc74880cda4e7e", + "https://bcr.bazel.build/modules/grpc-java/1.75.0.bcr.1/MODULE.bazel": "ba818f142b40cc7fb82fbdc8a9f7475b6783cd7849f9a71da814bacaf0acfd74", + "https://bcr.bazel.build/modules/grpc-java/1.75.0.bcr.1/source.json": "4cc3ef019b5a60031125af394b6c52df4da807528be110d9834e9e2690dfcf16", + "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/MODULE.bazel": "88de79051e668a04726e9ea94a481ec6f1692086735fd6f488ab908b3b909238", + "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/source.json": "5035d379c61042930244ab59e750106d893ec440add92ec0df6a0098ca7f131d", + "https://bcr.bazel.build/modules/grpc/1.41.0/MODULE.bazel": "5bcbfc2b274dabea628f0649dc50c90cf36543b1cfc31624832538644ad1aae8", + "https://bcr.bazel.build/modules/grpc/1.56.3.bcr.1/MODULE.bazel": "cd5b1eb276b806ec5ab85032921f24acc51735a69ace781be586880af20ab33f", + "https://bcr.bazel.build/modules/grpc/1.62.1/MODULE.bazel": "2998211594b8a79a6b459c4e797cfa19f0fb8b3be3149760ec7b8c99abfd426f", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.2/MODULE.bazel": "0fa2b0fd028ce354febf0fe90f1ed8fecfbfc33118cddd95ac0418cc283333a0", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.3/MODULE.bazel": "f6047e89faf488f5e3e65cb2594c6f5e86992abec7487163ff6b623526e543b0", + "https://bcr.bazel.build/modules/grpc/1.70.1/MODULE.bazel": "b800cd8e3e7555c1e61cba2e02d3a2fcf0e91f66e800db286d965d3b7a6a721a", + "https://bcr.bazel.build/modules/grpc/1.70.1/source.json": "e2977ea6cf9f2755418934d4ae134a6569713dd200fd7aded86a4b7f1b86efc9", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.6.0/MODULE.bazel": "26ec5118e66a55fef36f8ea39d6415d55fc966671fe4d61a6b9ef0cd6bc7b6a1", + "https://bcr.bazel.build/modules/jq.bzl/0.6.0/source.json": "2ed4e35b9fa9505495784114f7637fbde5846ec14af917841b6c045d877f20eb", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/libpfm/4.11.0/source.json": "caaffb3ac2b59b8aac456917a4ecf3167d40478ee79f15ab7a877ec9273937c9", + "https://bcr.bazel.build/modules/lobster/1.0.6/MODULE.bazel": "fd5778e9a1db6d19d7c9028dce2e40e29cf63809c9a95a53c0a80d954aa92f84", + "https://bcr.bazel.build/modules/lobster/1.0.6/source.json": "6be6b3030dbaede36aba42faba16f5d0a31346985bdf29ff236e47c3592ff4bf", + "https://bcr.bazel.build/modules/mbedtls/3.6.0/MODULE.bazel": "8e380e4698107c5f8766264d4df92e36766248447858db28187151d884995a09", + "https://bcr.bazel.build/modules/mbedtls/3.6.0/source.json": "1dbe7eb5258050afcc3806b9d43050f71c6f539ce0175535c670df606790b30c", + "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/MODULE.bazel": "87023db2f55fc3a9949c7b08dc711fae4d4be339a80a99d04453c4bb3998eefc", + "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/source.json": "296c63a90c6813e53b3812d24245711981fc7e563d98fe15625f55181494488a", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/MODULE.bazel": "02201d2921dadb4ec90c4980eca4b2a02904eddcf6fa02f3da7594fb7b0d821c", + "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/source.json": "f50efc07822f5425bd1d3e40e977484f9c0142463052717d40ec85cd6744243e", + "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/MODULE.bazel": "4a2e8b4d0b544002502474d611a5a183aa282251e14f6a01afe841c0c1b10372", + "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/source.json": "a7d956700a85b833c43fc61455c0e111ab75bab40768ed17a206ee18a2bbe38f", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "089a5613c2a159c7dfde098dabfc61e966889c7d6a81a98422a84c51535ed17d", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "b7379a140f538cea3f749179a2d481ed81942cc6f7b05a6113723eb34ac3b3e7", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/source.json": "da0cf667713b1e48d7f8912b100b4e0a8284c8a95717af5eb8c830d699e61cf5", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "a49f406e99bf05ab43ed4f5b3322fbd33adfd484b6546948929d1316299b68bf", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.3.1/MODULE.bazel": "0141a50e989576ee064c11ce8dd5ec89993525bd9f9a09c5618e4dacc8df9352", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.4.0.bcr.1/MODULE.bazel": "5ceaf25e11170d22eded4c8032728b4a3f273765fccda32f9e94f463755c4167", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.4.0.bcr.1/source.json": "fb9e01517460cfad8bafab082f2e1508d3cc2b7ed700cff19f3c7c84b146e5eb", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/MODULE.bazel": "b3925269f63561b8b880ae7cf62ccf81f6ece55b62cd791eda9925147ae116ec", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/source.json": "da1cb1add160f5e5074b7272e9db6fd8f1b3336c15032cd0a653af9d2f484aed", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.6/MODULE.bazel": "341dab6f417197494517d54c8e557c0baee1de7aec83543a4fbefe57900acb7e", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/prometheus-cpp/1.2.4/MODULE.bazel": "0fbe5dcff66311947a3f6b86ebc6a6d9328e31a28413ca864debc4a043f371e5", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0/MODULE.bazel": "ce82e086bbc0b60267e970f6a54b2ca6d0f22d3eb6633e00e2cc2899c700f3d8", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0/source.json": "8cb66b4e535afc718e9d104a3db96ccb71a42ee816a100e50fd0d5ac843c0606", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/26.0.bcr.1/MODULE.bazel": "8f04d38c2da40a3715ff6bdce4d32c5981e6432557571482d43a62c31a24c2cf", + "https://bcr.bazel.build/modules/protobuf/26.0.bcr.2/MODULE.bazel": "62e0b84ca727bdeb55a6fe1ef180e6b191bbe548a58305ea1426c158067be534", + "https://bcr.bazel.build/modules/protobuf/26.0/MODULE.bazel": "8402da964092af40097f4a205eec2a33fd4a7748dc43632b7d1629bfd9a2b856", + "https://bcr.bazel.build/modules/protobuf/27.0-rc2/MODULE.bazel": "b2b0dbafd57b6bec0ca9b251da02e628c357dab53a097570aa7d79d020f107cf", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/31.1/source.json": "25af5d0219da0c0fc4d1191a24ce438e6ca7f49d2e1a94f354efeba6ef10426f", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4.bcr.2/MODULE.bazel": "c4bd2c850211ff5b7dadf9d2d0496c1c922fdedc303c775b01dfd3b3efc907ed", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4.bcr.2/source.json": "4cc97f70b521890798058600a927ce4b0def8ee84ff2a5aa632aabcb4234aa0b", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4/MODULE.bazel": "b8913c154b16177990f6126d2d2477d187f9ddc568e95ee3e2d50fc65d2c494a", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/MODULE.bazel": "2d746fda559464b253b2b2e6073cb51643a2ac79009ca02100ebbc44b4548656", + "https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/source.json": "6aa0703de8efb20cc897bbdbeb928582ee7beaf278bcd001ac253e1605bddfae", + "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/MODULE.bazel": "82fbcb2e42f9e0040e76ccc74c06c3e46dfd33c64ca359293f8b84df0e6dff4c", + "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/source.json": "5c42389ad0e21fc06b95ad7c0b730008271624a2fa3292e0eab5f30e15adeee3", + "https://bcr.bazel.build/modules/re2/2021-09-01/MODULE.bazel": "bcb6b96f3b071e6fe2d8bed9cc8ada137a105f9d2c5912e91d27528b3d123833", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-05-01/MODULE.bazel": "55a3f059538f381107824e7d00df5df6d061ba1fb80e874e4909c0f0549e8f3e", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/MODULE.bazel": "e09b434b122bfb786a69179f9b325e35cb1856c3f56a7a81dd61609260ed46e1", + "https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/source.json": "a8ae7c09533bf67f9f6e5122d884d5741600b09d78dca6fc0f2f8d2ee0c2d957", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", + "https://bcr.bazel.build/modules/rules_android/0.6.6/source.json": "a9d8dc2d5a102dc03269a94acc886a4cab82cdcb9ccbc77b0f665d6d17a6ae09", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/source.json": "d8b5fe461272018cc07cfafce11fe369c7525330804c37eec5a82f84cd475366", + "https://bcr.bazel.build/modules/rules_apple/3.5.1/MODULE.bazel": "3d1bbf65ad3692003d36d8a29eff54d4e5c1c5f4bfb60f79e28646a924d9101c", + "https://bcr.bazel.build/modules/rules_buf/0.1.1/MODULE.bazel": "6189aec18a4f7caff599ad41b851ab7645d4f1e114aa6431acf9b0666eb92162", + "https://bcr.bazel.build/modules/rules_buf/0.5.2/MODULE.bazel": "5f2492d284ab9bedf2668178303abf5f3cd7d8cdf85d768951008e88456e9c6a", + "https://bcr.bazel.build/modules/rules_buf/0.5.2/source.json": "41876d4834c0832de4b393de6e55dfd1cb3b25d3109e4ba90eb7fb57c560e0d9", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.5/MODULE.bazel": "be41f87587998fe8890cd82ea4e848ed8eb799e053c224f78f3ff7fe1a1d9b74", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", + "https://bcr.bazel.build/modules/rules_cc/0.2.16/source.json": "d03d5cde49376d87e14ec14b666c56075e5e3926930327fd5d0484a1ff2ac1cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_distroless/0.8.0/MODULE.bazel": "a3e473943b685190e20668f5149f62a116fdcbeba66c7b9778f71d2aed4533c1", + "https://bcr.bazel.build/modules/rules_distroless/0.8.0/source.json": "a6931e20d97a13675693adb8b6cd3a0e6eb5218db43dfc83b75566ddc4158efc", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/MODULE.bazel": "b9527010e5fef060af92b6724edb3691970a5b1f76f74b21d39f7d433641be60", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/source.json": "9300e71df0cdde0952f10afff1401fa664e9fc5d9ae6204660ba1b158d90d6a6", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", + "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", + "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.45.1/MODULE.bazel": "6d7884f0edf890024eba8ab31a621faa98714df0ec9d512389519f0edff0281a", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.48.0/MODULE.bazel": "d00ebcae0908ee3f5e6d53f68677a303d6d59a77beef879598700049c3980a03", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.51.0/MODULE.bazel": "b6920f505935bfd69381651c942496d99b16e2a12f3dd5263b90ded16f3b4d0f", + "https://bcr.bazel.build/modules/rules_go/0.51.0/source.json": "473c0263360b1ae3aca71758e001d257a638620b2e2a36e3a2721fdae04377ec", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.1.0/MODULE.bazel": "324b6478b0343a3ce7a9add8586ad75d24076d6d43d2f622990b9c1cfd8a1b15", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/5.5.0/MODULE.bazel": "486ad1aa15cdc881af632b4b1448b0136c76025a1fe1ad1b65c5899376b83a50", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.3.1/MODULE.bazel": "5a3471c8b84d53d58d5f6e316313680d7dd2c70afac696dbe14b761b0b5c6a06", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.0.6/MODULE.bazel": "6ddb07d9857a1a3accc9f6d005f20c969c4659c7710e6269a51db3527e0ea969", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", + "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", + "https://bcr.bazel.build/modules/rules_java/8.15.1/MODULE.bazel": "5071eebf0fd602ab0617f846e0e0d8f388d66c961513c736e0ac4a1dcde3ff2c", + "https://bcr.bazel.build/modules/rules_java/8.15.1/source.json": "e48286d5819767bc5b3d457539ae7f94e28a9b3e55d092d5c47176cb6a2a289b", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.8.0/MODULE.bazel": "de589d0880911ac007abd521b9f0ddcd8b0dbd05c8553e6f8124a050b83acf7d", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.0/MODULE.bazel": "37c93a5a78d32e895d52f86a8d0416176e915daabd029ccb5594db422e87c495", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/source.json": "c191249787625db72616a3fb3cc2786ab57355a2e3b615402b8b3b66b0f995b7", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/source.json": "0b0dc9400f14b5fbb13d278ad3bf0413cdbaf0da0db337e055b855e35b878a3b", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.4/MODULE.bazel": "6a88dd22800cf1f9f79ba32cacad0d3a423ed28efa2c2ed5582eaa78dd3ac1e5", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_multirun/0.9.0/MODULE.bazel": "32d628ef586b5b23f67e55886b7bc38913ea4160420d66ae90521dda2ff37df0", + "https://bcr.bazel.build/modules/rules_multirun/0.9.0/source.json": "e882ba77962fa6c5fe68619e5c7d0374ec9a219fb8d03c42eadaf6d0243771bd", + "https://bcr.bazel.build/modules/rules_multitool/0.11.0/MODULE.bazel": "8d9dda78d2398e136300d3ef4fbcc89ede7c32c158d8c016fa7d032df41c4aaf", + "https://bcr.bazel.build/modules/rules_multitool/1.11.1/MODULE.bazel": "f826d2d394e8d964e44ebb4a75ebcfe4e9cd4eb150e2ddcd60398ffeb939696a", + "https://bcr.bazel.build/modules/rules_multitool/1.11.1/source.json": "201f43de1d35bd17f25a4fed3ba5a2ec500ef5e08b7d4b341bb9fd39cef0cbc6", + "https://bcr.bazel.build/modules/rules_multitool/1.9.0/MODULE.bazel": "8a042b0dbf35e4aaa94c28ad69efa75c9e673e9ea4bd5c0fb70bab75ef9c636b", + "https://bcr.bazel.build/modules/rules_nodejs/5.8.2/MODULE.bazel": "6bc03c8f37f69401b888023bf511cb6ee4781433b0cb56236b2e55a21e3a026a", + "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/MODULE.bazel": "b66eadebd10f1f1b25f52f95ab5213a57e82c37c3f656fcd9a57ad04d2264ce7", + "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056", + "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/source.json": "a3f966f4415a8a6545e560ee5449eac95cc633f96429d08e87c87775c72f5e09", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.1.0/MODULE.bazel": "9db8031e71b6ef32d1846106e10dd0ee2deac042bd9a2de22b4761b0c3036453", + "https://bcr.bazel.build/modules/rules_pkg/1.1.0/source.json": "fef768df13a92ce6067e1cd0cdc47560dace01354f1d921cfb1d632511f7d608", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.18.0/MODULE.bazel": "4927032417a3ad1ff220c3e6f940b6811387151aec9e43d3ba76fd7ac8962be8", + "https://bcr.bazel.build/modules/rules_python/0.20.0/MODULE.bazel": "bfe14d17f20e3fe900b9588f526f52c967a6f281e47a1d6b988679bd15082286", + "https://bcr.bazel.build/modules/rules_python/0.22.0/MODULE.bazel": "b8057bafa11a9e0f4b08fc3b7cd7bee0dcbccea209ac6fc9a3ff051cd03e19e9", + "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.26.0/MODULE.bazel": "42cb98cd15954e83b96b540dcc6d5a618eb061f056147ac4ea46e687a066a7c7", + "https://bcr.bazel.build/modules/rules_python/0.27.1/MODULE.bazel": "65dc875cc1a06c30d5bbdba7ab021fd9e551a6579e408a3943a61303e2228a53", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.1.0/MODULE.bazel": "57e01abae22956eb96d891572490d20e07d983e0c065de0b2170cafe5053e788", + "https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5", + "https://bcr.bazel.build/modules/rules_python/1.8.5/MODULE.bazel": "28b2d79ed8368d7d45b34bacc220e3c0b99cbcd9392641961b849e4c3f55dd30", + "https://bcr.bazel.build/modules/rules_python/1.8.5/source.json": "e261b03c8804f2582c9536013f987e1ea105a2b38c238aa2ac8f98fc34c8b18a", + "https://bcr.bazel.build/modules/rules_python_gazelle_plugin/1.5.1/MODULE.bazel": "371440271705f949a1b51ca875c7d00ce9057e540fdbf26311445cc10810974b", + "https://bcr.bazel.build/modules/rules_python_gazelle_plugin/1.5.1/source.json": "c52e4d2229fbd92b658bf60a7638e79b96525e8f7ed6c59036b4827cade9e430", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_rust/0.56.0/MODULE.bazel": "3295b00757db397122092322fe1e920be7f5c9fbfb8619138977e820f2cbbbae", + "https://bcr.bazel.build/modules/rules_rust/0.67.0/MODULE.bazel": "87c3816c4321352dcfd9e9e26b58e84efc5b21351ae3ef8fb5d0d57bde7237f5", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.5.0/MODULE.bazel": "8c8447370594d45539f66858b602b0bb2cb2d3401a4ebb9ad25830c59c0f366d", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/1.18.0/MODULE.bazel": "a6aba73625d0dc64c7b4a1e831549b6e375fbddb9d2dde9d80c9de6ec45b24c9", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/source.json": "40fc69dfaac64deddbb75bd99cdac55f4427d9ca0afbe408576a65428427a186", + "https://bcr.bazel.build/modules/rules_testing/0.9.0/MODULE.bazel": "d4d9a7367978b5c589437f01dba1dc80ac6f389e9991e1c1edb3c8207526ca83", + "https://bcr.bazel.build/modules/rules_testing/0.9.0/source.json": "2a943853f3480f42a9a5205cc4881a147fecdcf7c8ee87750bbeffff9c9a1877", + "https://bcr.bazel.build/modules/sphinxdocs/2.2.0/MODULE.bazel": "e046c573919d72605d62c352a08d9223a10aafef3a7cb70d0fe253ebdd97019e", + "https://bcr.bazel.build/modules/sphinxdocs/2.2.0/source.json": "b1da19a3d14a1dd8aa6a9ccaedc42bbe0313c8160a77ba5cca336cca1315298d", + "https://bcr.bazel.build/modules/stardoc/0.5.0/MODULE.bazel": "f9f1f46ba8d9c3362648eea571c6f9100680efc44913618811b58cc9c02cd678", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/source.json": "32bd87e5f4d7acc57c5b2ff7c325ae3061d5e242c0c4c214ae87e0f1c13e54cb", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/source.json": "4a620381df075a16cb3a7ed57bd1d05f7480222394c64a20fa51bdb636fda658", + "https://bcr.bazel.build/modules/trlc/3.0.0/MODULE.bazel": "45444f9112300e7a716bf842beb17ed8f84d7d1f84c3d1ed126f57bec9bdf2a9", + "https://bcr.bazel.build/modules/trlc/3.0.1/MODULE.bazel": "9ece74d6ae5a718850a6f39d94ac52a84c002e0a5c6dadf676433e330c2e2f6c", + "https://bcr.bazel.build/modules/trlc/3.0.1/source.json": "3bd9ec62c5a44d759377acee89b7ed966e2ce227292b2b175424bf4343ed0b66", + "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/upb/0.0.0-20230907-e7430e6/MODULE.bazel": "3a7dedadf70346e678dc059dbe44d05cbf3ab17f1ce43a1c7a42edc7cbf93fd9", + "https://bcr.bazel.build/modules/xds/0.0.0-20240423-555b57e/MODULE.bazel": "cea509976a77e34131411684ef05a1d6ad194dd71a8d5816643bc5b0af16dc0f", + "https://bcr.bazel.build/modules/xds/0.0.0-20240423-555b57e/source.json": "7227e1fcad55f3f3cab1a08691ecd753cb29cc6380a47bc650851be9f9ad6d20", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.3.1/MODULE.bazel": "9bcb7151b3cd4681b89d350530eaf7b45e32a44dda94843b8932b0cb1cd4594a", + "https://bcr.bazel.build/modules/yq.bzl/0.3.1/source.json": "f0b0f204a2a6b0e34b4c9541efe8c04f2ef1af65948daa784eccea738b21dbd2", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.2.13/MODULE.bazel": "aa6deb1b83c18ffecd940c4119aff9567cd0a671d7bba756741cb2ef043a29d5", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.1/MODULE.bazel": "6a9fe6e3fc865715a7be9823ce694ceb01e364c35f7a846bf0d2b34762bc066b", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", + "https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20210324.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20211102.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20220623.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230125.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20240116.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20240116.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20240116.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20240722.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20250127.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20250127.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20250512.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-py/2.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.15.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.17.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.22.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.24.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/1.31.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/1.38.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/1.42.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.16.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.20.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.22.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.9.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_esbuild/0.21.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_js/1.33.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_js/1.40.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_js/2.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_js/2.3.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_lint/0.12.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_lint/2.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_lint/2.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_py/1.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_ts/3.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/0.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.10.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.13.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.15.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.17.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.18.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.20.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.21.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.23.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.30.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.32.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.34.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.39.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.9.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_jar_jar/0.1.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_lib/3.0.0-beta.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_lib/3.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_worker_api/0.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_worker_api/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_worker_java/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/boringssl/0.0.0-20211025-d4f1ab9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/boringssl/0.0.0-20230215-5c22014/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/boringssl/0.0.0-20240530-2db0eb3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/boringssl/0.20240913.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/boringssl/0.20241024.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/6.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/7.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/8.2.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/8.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildozer/7.1.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/c-ares/1.15.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/cel-spec/0.15.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/civetweb/1.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/curl/8.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/curl/8.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/cython/3.0.11-1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/diff.bzl/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/download_utils/1.2.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/envoy_api/0.0.0-20241214-918efc9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/flatbuffers/25.9.23/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gawk/5.3.2.bcr.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.30.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.32.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.33.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.34.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.36.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.40.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.44.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/google_benchmark/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/google_benchmark/1.8.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googleapis/0.0.0-20240326-1c8d509c5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googleapis/0.0.0-20240819-fe8ba054a/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.13.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.15.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.17.0.bcr.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.17.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc-java/1.62.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc-java/1.66.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc-java/1.75.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc-proto/0.0.0-20240627-ec30f58/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.41.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.56.3.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.62.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.66.0.bcr.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.66.0.bcr.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/grpc/1.70.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jq.bzl/0.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jq.bzl/0.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jsoncpp/1.9.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jsoncpp/1.9.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/libpfm/4.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/lobster/1.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/mbedtls/3.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/nlohmann_json/3.11.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/nlohmann_json/3.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opencensus-cpp/0.0.0-20230502-50eb5de/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opencensus-proto/0.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-proto/1.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-proto/1.4.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentracing-cpp/1.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/package_metadata/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/package_metadata/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/package_metadata/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/prometheus-cpp/1.2.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/prometheus-cpp/1.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/24.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/26.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/26.0.bcr.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/26.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.0-rc2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0-rc2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0-rc3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/3.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/3.19.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/3.19.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/31.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protoc-gen-validate/1.0.4.bcr.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protoc-gen-validate/1.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/pybind11_bazel/2.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/pybind11_bazel/2.12.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/pybind11_bazel/2.13.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rapidjson/1.1.0.bcr.20241007/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2021-09-01/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2023-09-01/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2024-05-01/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2024-07-02/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2025-08-12.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_android/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_android/0.6.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_apple/3.16.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_apple/3.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_buf/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_buf/0.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.13/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.14/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.15/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.17/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.14/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_distroless/0.8.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_foreign_cc/0.10.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_fuzzing/0.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.33.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.38.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.39.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.41.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.42.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.45.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.46.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.48.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.50.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.51.0-rc2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_go/0.51.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/5.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/5.3.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/5.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.10.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.12.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.13.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.15.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.8.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/4.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/1.9.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/1.9.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/2.1.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/0.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_multirun/0.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_multitool/0.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_multitool/1.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_multitool/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/5.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.3.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.7.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/6.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/6.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/7.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/7.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.10.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.18.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.20.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.22.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.22.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.25.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.26.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.27.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.29.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.31.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.33.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.34.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.37.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.37.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.40.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.8.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python_gazelle_plugin/1.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.56.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.67.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.68.1-score/MODULE.bazel": "dc1c87d74ef6d32190e65c3c8aabfa7e7764e457bf9888312e0313c3c11fdb69", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.68.2-score/MODULE.bazel": "37be8dee6df19d666c1d4266e1266d82012aa83bd82de38b3100fd7f641d064b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.68.2-score/source.json": "f88ad98dd08f296a546677e86ad42b20f61851e41a9fd3e0449971162fcaf784", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.1.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.16.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.18.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/2.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_testing/0.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_platforms/0.0.3/MODULE.bazel": "14c96e378c08705a46abe0799d6236fe3095c342c34f83f8d1b3f6046ce00651", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_platforms/0.0.3/source.json": "1a853ab23455388d550a9aecf3d8b53ec73de50e7fe2914d9269a3c698bf3624", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_devcontainer/1.11.0/MODULE.bazel": "fb6041c96e949a151307b4690ee81cf5d9254d6bf79540184b16567b04397171", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_devcontainer/1.11.0/source.json": "b379a2499cf06f16de65c2981665c3723afba9e858ed16b453f044882067f56f", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.0.1/MODULE.bazel": "446b0462f893021e3133b2f95672ae37dfe2ade434b6052c91530043e4d89993", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.1.1/MODULE.bazel": "4740f5e4229753b2ec023df5ce9c24c3472ad1e6d700a970e3e96f7347e65a1b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.1.1/source.json": "189c748d57a732e0653af377bb7635253ed7fc135f33c2f107c4d8a4a17259c5", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_process_description/2.1.2/MODULE.bazel": "1076b36d2d05ab1a18df0746f6a545869eec6927019d651af99d99ef056e2023", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_process_description/2.1.2/source.json": "f76099f076243e2641803971e2a95ed27f24756c9bdda5d10a808c664996f0fc", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_rust_policies/0.0.2/MODULE.bazel": "ade2bad4a331b02d9b7e7d9842e8de8c6fded6186486e02c4f7db5cd4b71d34d", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_rust_policies/0.0.2/source.json": "fbcbc738e652b0c68d5d28dd1db09f2e643dc111f5739b2f6af7ec56c2e88043", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.10.0/MODULE.bazel": "535296e6cdef55a506c580ca2ce541aa9ddefb354de1a24ab2bd4addc939282b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.10.0/source.json": "8bda773be264da16d2a82a03ebb737421dd4a35855f1e9a5d03d9722d84c1df5", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_tooling/2.2.0/MODULE.bazel": "178ba4862246b6ba2bbcd96b7e9e728299b19fb94bcf23d315dc2299aabf7178", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_tooling/2.2.0/source.json": "a76f2d093cff26d5b256ce531bb2f69b6c667c968f99a156327fd194d4f36e61", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/sphinxdocs/2.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.6.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/tar.bzl/0.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/tar.bzl/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/tar.bzl/0.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/trlc/3.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/trlc/3.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/upb/0.0.0-20230907-e7430e6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/xds/0.0.0-20240423-555b57e/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/yq.bzl/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/yq.bzl/0.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.2.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.2.12/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.2.13/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3/MODULE.bazel": "not found" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { + "general": { + "bzlTransitiveDigest": "qh4ujJcmdcm37/781UtOijzSUpQ4dDmcmRF/yI/+H2I=", + "usagesDigest": "sj4kz7yaVclWMuWhUhSLq0bVH7+HrkWyMdODMeA7Zhw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "esbuild_darwin-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "darwin-x64" + } + }, + "esbuild_darwin-arm64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "darwin-arm64" + } + }, + "esbuild_linux-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "linux-x64" + } + }, + "esbuild_linux-arm64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "linux-arm64" + } + }, + "esbuild_win32-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "win32-x64" + } + }, + "esbuild_toolchains": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "esbuild_version": "0.19.9", + "user_repository_name": "esbuild" + } + }, + "npm__esbuild_0.19.9": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", + "attributes": { + "package": "esbuild", + "version": "0.19.9", + "root_package": "", + "link_workspace": "", + "link_packages": {}, + "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", + "url": "", + "commit": "", + "patch_args": [ + "-p0" + ], + "patches": [], + "custom_postinstall": "", + "npm_auth": "", + "npm_auth_basic": "", + "npm_auth_username": "", + "npm_auth_password": "", + "lifecycle_hooks": [], + "extra_build_content": "", + "generate_bzl_library_targets": false, + "extract_full_archive": false, + "exclude_package_contents": [], + "system_tar": "auto" + } + }, + "npm__esbuild_0.19.9__links": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "attributes": { + "package": "esbuild", + "version": "0.19.9", + "dev": false, + "root_package": "", + "link_packages": {}, + "deps": {}, + "transitive_closure": {}, + "lifecycle_build_target": false, + "lifecycle_hooks_env": [], + "lifecycle_hooks_execution_requirements": [ + "no-sandbox" + ], + "lifecycle_hooks_use_default_shell_env": false, + "bins": {}, + "package_visibility": [ + "//visibility:public" + ], + "replace_package": "", + "exclude_package_contents": [] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_bazel_lib+", + "tar.bzl", + "tar.bzl+" + ], + [ + "aspect_rules_esbuild+", + "aspect_rules_js", + "aspect_rules_js+" + ], + [ + "aspect_rules_esbuild+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_rules_js+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "aspect_rules_js+", + "aspect_rules_js", + "aspect_rules_js+" + ], + [ + "aspect_rules_js+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_rules_js+", + "bazel_tools", + "bazel_tools" + ], + [ + "tar.bzl+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "tar.bzl+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "tar.bzl+", + "tar.bzl", + "tar.bzl+" + ] + ] + } + }, + "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { + "general": { + "bzlTransitiveDigest": "6CnPmgfrbmQ1ksmozHPuP2j3+BnRuCzw55p9IL41/kI=", + "usagesDigest": "kbjSw2REjlSC0HtTZDf2p+l/dmiMt3NHLoiWEXYAoQI=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "pnpm": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", + "attributes": { + "package": "pnpm", + "version": "8.6.7", + "root_package": "", + "link_workspace": "", + "link_packages": {}, + "integrity": "sha512-vRIWpD/L4phf9Bk2o/O2TDR8fFoJnpYrp2TKqTIZF/qZ2/rgL3qKXzHofHgbXsinwMoSEigz28sqk3pQ+yMEQQ==", + "url": "", + "commit": "", + "patch_args": [ + "-p0" + ], + "patches": [], + "custom_postinstall": "", + "npm_auth": "", + "npm_auth_basic": "", + "npm_auth_username": "", + "npm_auth_password": "", + "lifecycle_hooks": [], + "extra_build_content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\njs_binary(name = \"pnpm\", data = glob([\"package/**\"]), entry_point = \"package/dist/pnpm.cjs\", visibility = [\"//visibility:public\"])", + "generate_bzl_library_targets": false, + "extract_full_archive": true, + "exclude_package_contents": [], + "system_tar": "auto" + } + }, + "pnpm__links": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "attributes": { + "package": "pnpm", + "version": "8.6.7", + "dev": false, + "root_package": "", + "link_packages": {}, + "deps": {}, + "transitive_closure": {}, + "lifecycle_build_target": false, + "lifecycle_hooks_env": [], + "lifecycle_hooks_execution_requirements": [ + "no-sandbox" + ], + "lifecycle_hooks_use_default_shell_env": false, + "bins": {}, + "package_visibility": [ + "//visibility:public" + ], + "replace_package": "", + "exclude_package_contents": [] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_bazel_lib+", + "tar.bzl", + "tar.bzl+" + ], + [ + "aspect_rules_js+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "aspect_rules_js+", + "aspect_rules_js", + "aspect_rules_js+" + ], + [ + "aspect_rules_js+", + "bazel_features", + "bazel_features+" + ], + [ + "aspect_rules_js+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_rules_js+", + "bazel_tools", + "bazel_tools" + ], + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "tar.bzl+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "tar.bzl+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "tar.bzl+", + "tar.bzl", + "tar.bzl+" + ] + ] + } + }, + "@@aspect_rules_py+//py:extensions.bzl%py_tools": { + "general": { + "bzlTransitiveDigest": "VfJYy1B5v3oMq9SNoz4hGTKf+uJgqbxHJYD8rdhivHo=", + "usagesDigest": "NC1b49l5tenTBVWEUGzzC0j5Kg1GH+l5lBw5JRCldIU=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "bsd_tar_darwin_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "bsd_tar_darwin_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_linux_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "bsd_tar_linux_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "bsd_tar_windows_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "bsd_tar_windows_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_arm64" + } + }, + "bsd_tar_toolchains": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%tar_toolchains_repo", + "attributes": { + "user_repository_name": "bsd_tar" + } + }, + "rules_py_tools.darwin_amd64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "rules_py_tools.darwin_arm64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "rules_py_tools.linux_amd64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "rules_py_tools.linux_arm64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "rules_py_tools": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:repo.bzl%toolchains_repo", + "attributes": { + "user_repository_name": "rules_py_tools" + } + }, + "rules_py_pex_2_3_1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://files.pythonhosted.org/packages/e7/d0/fbda2a4d41d62d86ce53f5ae4fbaaee8c34070f75bb7ca009090510ae874/pex-2.3.1-py2.py3-none-any.whl" + ], + "sha256": "64692a5bf6f298403aab930d22f0d836ae4736c5bc820e262e9092fe8c56f830", + "downloaded_file_path": "pex-2.3.1-py2.py3-none-any.whl" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_rules_py+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "aspect_rules_py+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@aspect_rules_ts+//ts:extensions.bzl%ext": { + "general": { + "bzlTransitiveDigest": "U195YDrpWzfnEHQ+ASO5i6qLqeDF2eBcqVDryoKZRKY=", + "usagesDigest": "caXVbnxEUN71ZxydJbg6pZ8NaFPVDbNp12wS9TMC824=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "npm_typescript": { + "repoRuleId": "@@aspect_rules_ts+//ts/private:npm_repositories.bzl%http_archive_version", + "attributes": { + "bzlmod": true, + "version": "5.8.3", + "integrity": "", + "build_file": "@@aspect_rules_ts+//ts:BUILD.typescript", + "build_file_substitutions": { + "bazel_worker_version": "5.4.2", + "google_protobuf_version": "3.20.1" + }, + "urls": [ + "https://registry.npmjs.org/typescript/-/typescript-{}.tgz" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_rules_ts+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { + "general": { + "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", + "usagesDigest": "tiZsmifkpLM+xnn6EXkTF48bYLsbvhr5rcGkv4SuImc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "aspect_tools_telemetry_report": { + "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", + "attributes": { + "deps": { + "aspect_rules_lint": "2.7.1", + "aspect_tools_telemetry": "0.3.3" + } + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_tools_telemetry+", + "bazel_lib", + "bazel_lib+" + ], + [ + "aspect_tools_telemetry+", + "bazel_skylib", + "bazel_skylib+" + ] + ] + } + }, + "@@bazel_jar_jar+//internal:non_module_deps.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "VBviAE+Wh71Wczft5g7JzY9S5ZeH0iPXQyKjCeb5V1I=", + "usagesDigest": "P1uSZ4XnqOp90Mkh0A4Nrjx12Bgz/iceROnSbTsawGk=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "jvm__jarjar_abrams_assembly": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "urls": [ + "https://repo1.maven.org/maven2/com/eed3si9n/jarjarabrams/jarjar-abrams-assembly_2.12/1.14.0/jarjar-abrams-assembly_2.12-1.14.0.jar" + ], + "sha256": "75f86f7588136d6ca92d6fed8d58e6666e04c507b71de378527c053fd2a151c2" + } + }, + "jvm__com_twitter__scalding_args": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "urls": [ + "https://repo1.maven.org/maven2/com/twitter/scalding-args_2.12/0.17.4/scalding-args_2.12-0.17.4.jar" + ], + "sha256": "e0de2ad8ef344bb11a2854275b5b85a1adb17f0e0ed9740177d940a602cd977b" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "bazel_jar_jar+", + "bazel_tools", + "bazel_tools" + ], + [ + "bazel_tools", + "rules_java", + "rules_java+" + ], + [ + "protobuf+", + "proto_bazel_features", + "bazel_features+" + ], + [ + "rules_cc+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_cc+", + "cc_compatibility_proxy", + "rules_cc++compatibility_proxy+cc_compatibility_proxy" + ], + [ + "rules_cc+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_cc++compatibility_proxy+cc_compatibility_proxy", + "rules_cc", + "rules_cc+" + ], + [ + "rules_java+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_java+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_java+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_java+", + "com_google_protobuf", + "protobuf+" + ], + [ + "rules_java+", + "compatibility_proxy", + "rules_java++compatibility_proxy+compatibility_proxy" + ], + [ + "rules_java+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_java++compatibility_proxy+compatibility_proxy", + "rules_java", + "rules_java+" + ] + ] + } + }, + "@@cel-spec+//:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "49v9UE4eBOMtW8ATb+3VHdFaCc//dFbCS+ZQW0HIKNE=", + "usagesDigest": "HFQJtQrL9nKaFZEjgwaHVMHALMW+cafu696xy7J4ueM=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_google_googleapis": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "bd8e735d881fb829751ecb1a77038dda4a8d274c45490cb9fcf004583ee10571", + "strip_prefix": "googleapis-07c27163ac591955d736f3057b1619ece66f5b99", + "urls": [ + "https://github.com/googleapis/googleapis/archive/07c27163ac591955d736f3057b1619ece66f5b99.tar.gz" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "cel-spec+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@cel-spec+//:googleapis_ext.bzl%googleapis_ext": { + "general": { + "bzlTransitiveDigest": "yun2jmsomFi3bs5bjQWXApBzqQf66zBJ39JEBYigzdc=", + "usagesDigest": "Ek7VfZ+tuyRBx/1h5wcmtnW9EGpOb0dkXUwBluZbD8k=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_google_googleapis_imports": { + "repoRuleId": "@@cel-spec++non_module_dependencies+com_google_googleapis//:repository_rules.bzl%switched_rules", + "attributes": { + "rules": { + "proto_library_with_info": [ + "", + "" + ], + "moved_proto_library": [ + "", + "" + ], + "java_proto_library": [ + "", + "" + ], + "java_grpc_library": [ + "", + "" + ], + "java_gapic_library": [ + "", + "" + ], + "java_gapic_test": [ + "", + "" + ], + "java_gapic_assembly_gradle_pkg": [ + "", + "" + ], + "py_proto_library": [ + "", + "" + ], + "py_grpc_library": [ + "", + "" + ], + "py_gapic_library": [ + "", + "" + ], + "py_test": [ + "", + "" + ], + "py_gapic_assembly_pkg": [ + "", + "" + ], + "py_import": [ + "", + "" + ], + "go_proto_library": [ + "", + "" + ], + "go_library": [ + "", + "" + ], + "go_test": [ + "", + "" + ], + "go_gapic_library": [ + "", + "" + ], + "go_gapic_assembly_pkg": [ + "", + "" + ], + "cc_proto_library": [ + "native.cc_proto_library", + "" + ], + "cc_grpc_library": [ + "", + "" + ], + "cc_gapic_library": [ + "", + "" + ], + "php_proto_library": [ + "", + "php_proto_library" + ], + "php_grpc_library": [ + "", + "php_grpc_library" + ], + "php_gapic_library": [ + "", + "php_gapic_library" + ], + "php_gapic_assembly_pkg": [ + "", + "php_gapic_assembly_pkg" + ], + "nodejs_gapic_library": [ + "", + "typescript_gapic_library" + ], + "nodejs_gapic_assembly_pkg": [ + "", + "typescript_gapic_assembly_pkg" + ], + "ruby_proto_library": [ + "", + "" + ], + "ruby_grpc_library": [ + "", + "" + ], + "ruby_ads_gapic_library": [ + "", + "" + ], + "ruby_cloud_gapic_library": [ + "", + "" + ], + "ruby_gapic_assembly_pkg": [ + "", + "" + ], + "csharp_proto_library": [ + "", + "" + ], + "csharp_grpc_library": [ + "", + "" + ], + "csharp_gapic_library": [ + "", + "" + ], + "csharp_gapic_assembly_pkg": [ + "", + "" + ] + } + } + } + }, + "recordedRepoMappingEntries": [ + [ + "cel-spec+", + "com_google_googleapis", + "cel-spec++non_module_dependencies+com_google_googleapis" + ] + ] + } + }, + "@@envoy_api+//bazel:repositories.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "VzLskQI4CUM3XVC+wpI1FIlKua2ToSOGRJ8G+0HfaV8=", + "usagesDigest": "cxAa0VVo9d210JBUBw6wpuGp8jg+ltqw3tzH0tPtIEg=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "prometheus_metrics_model": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/prometheus/client_model/archive/v0.6.1.tar.gz" + ], + "sha256": "b9b690bc35d80061f255faa7df7621eae39fe157179ccd78ff6409c3b004f05e", + "strip_prefix": "client_model-0.6.1", + "build_file_content": "\nload(\"@envoy_api//bazel:api_build_system.bzl\", \"api_cc_py_proto_library\")\nload(\"@io_bazel_rules_go//proto:def.bzl\", \"go_proto_library\")\n\napi_cc_py_proto_library(\n name = \"client_model\",\n srcs = [\n \"io/prometheus/client/metrics.proto\",\n ],\n visibility = [\"//visibility:public\"],\n)\n\ngo_proto_library(\n name = \"client_model_go_proto\",\n importpath = \"github.com/prometheus/client_model/go\",\n proto = \":client_model\",\n visibility = [\"//visibility:public\"],\n)\n" + } + }, + "com_github_bufbuild_buf": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/bufbuild/buf/releases/download/v1.47.2/buf-Linux-x86_64.tar.gz" + ], + "sha256": "39716cfe0185df3cba21f66ec739620ffb6876c48b2da4338a8c68c290c9b116", + "strip_prefix": "buf", + "build_file_content": "\npackage(\n default_visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"buf\",\n srcs = [\n \"@com_github_bufbuild_buf//:bin/buf\",\n ],\n tags = [\"manual\"], # buf is downloaded as a linux binary; tagged manual to prevent build for non-linux users\n)\n" + } + }, + "envoy_toolshed": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/envoyproxy/toolshed/archive/bazel-v0.2.0.tar.gz" + ], + "sha256": "ef5e95580c41f6805beec197d9a4f6683550f4bfc1e1c678449b6d205dbf000b", + "strip_prefix": "toolshed-bazel-v0.2.0/bazel" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "envoy_api+", + "bazel_tools", + "bazel_tools" + ], + [ + "envoy_api+", + "envoy_api", + "envoy_api+" + ] + ] + } + }, + "@@googleapis+//:extensions.bzl%switched_rules": { + "general": { + "bzlTransitiveDigest": "vG6fuTzXD8MMvHWZEQud0MMH7eoC4GXY0va7VrFFh04=", + "usagesDigest": "+R+o+SUmw755TgAo3pOLuat5DyxcMumhHtsr8ivEIRg=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_google_googleapis_imports": { + "repoRuleId": "@@googleapis+//:repository_rules.bzl%switched_rules", + "attributes": { + "rules": { + "proto_library_with_info": [ + "", + "" + ], + "moved_proto_library": [ + "", + "" + ], + "java_proto_library": [ + "", + "" + ], + "java_grpc_library": [ + "", + "" + ], + "java_gapic_library": [ + "", + "" + ], + "java_gapic_test": [ + "", + "" + ], + "java_gapic_assembly_gradle_pkg": [ + "", + "" + ], + "py_proto_library": [ + "", + "" + ], + "py_grpc_library": [ + "", + "" + ], + "py_gapic_library": [ + "", + "" + ], + "py_test": [ + "", + "" + ], + "py_gapic_assembly_pkg": [ + "", + "" + ], + "py_import": [ + "", + "" + ], + "go_proto_library": [ + "", + "" + ], + "go_grpc_library": [ + "", + "" + ], + "go_library": [ + "", + "" + ], + "go_test": [ + "", + "" + ], + "go_gapic_library": [ + "", + "" + ], + "go_gapic_assembly_pkg": [ + "", + "" + ], + "cc_proto_library": [ + "", + "" + ], + "cc_grpc_library": [ + "", + "" + ], + "cc_gapic_library": [ + "", + "" + ], + "php_proto_library": [ + "", + "php_proto_library" + ], + "php_grpc_library": [ + "", + "php_grpc_library" + ], + "php_gapic_library": [ + "", + "php_gapic_library" + ], + "php_gapic_assembly_pkg": [ + "", + "php_gapic_assembly_pkg" + ], + "nodejs_gapic_library": [ + "", + "typescript_gapic_library" + ], + "nodejs_gapic_assembly_pkg": [ + "", + "typescript_gapic_assembly_pkg" + ], + "ruby_proto_library": [ + "", + "" + ], + "ruby_grpc_library": [ + "", + "" + ], + "ruby_ads_gapic_library": [ + "", + "" + ], + "ruby_cloud_gapic_library": [ + "", + "" + ], + "ruby_gapic_assembly_pkg": [ + "", + "" + ], + "csharp_proto_library": [ + "", + "" + ], + "csharp_grpc_library": [ + "", + "" + ], + "csharp_gapic_library": [ + "", + "" + ], + "csharp_gapic_assembly_pkg": [ + "", + "" + ] + } + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@pybind11_bazel+//:internal_configure.bzl%internal_configure_extension": { + "general": { + "bzlTransitiveDigest": "doxdX2drQaP4mqY6tnLSIGABgYuXR5Hpp6Wpfyb23Rg=", + "usagesDigest": "tVQNvLoXMWAbiK39am3yovKGpwINdftfn7RpDyN+JZc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "pybind11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@pybind11_bazel+//:pybind11-BUILD.bazel", + "strip_prefix": "pybind11-2.13.6", + "url": "https://github.com/pybind/pybind11/archive/refs/tags/v2.13.6.tar.gz", + "integrity": "sha256-4Iy4f0dz2pf6e18DXeh2OrxlbYfVdz5i9toFh9Hw7CA=" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "pybind11_bazel+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_android+//bzlmod_extensions:apksig.bzl%apksig_extension": { + "general": { + "bzlTransitiveDigest": "By9qVNN7G4oL1vYOJXye7Dp/CbR2ar9oxAW8WXAVcVw=", + "usagesDigest": "xq6OVkELeJvOgYo3oY/sUBsGFbcqdV+9BYiNgSPV/po=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "apksig": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://android.googlesource.com/platform/tools/apksig/+archive/24e3075e68ebe17c0b529bb24bfda819db5e2f3b.tar.gz", + "build_file": "@@rules_android+//bzlmod_extensions:apksig.BUILD" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_android+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_android+//bzlmod_extensions:com_android_dex.bzl%com_android_dex_extension": { + "general": { + "bzlTransitiveDigest": "rvWbJQc8jInfIAaXIMhSOqUlwM9HVeLey6q0ISvg08Y=", + "usagesDigest": "toF8IFMu98H/VU2p1sfVC5fVXVYJunpbbmtM6tOsQXY=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_android_dex": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://android.googlesource.com/platform/dalvik/+archive/5a81c499a569731e2395f7c8d13c0e0d4e17a2b6.tar.gz", + "build_file": "@@rules_android+//bzlmod_extensions:com_android_dex.BUILD" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_android+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { + "general": { + "bzlTransitiveDigest": "NAy+0M15JNVEBb8Tny6t7j3lKqTnsAMjoBB6LJ+C370=", + "usagesDigest": "g9Ur6X6qhf9a8MmY9qXU/jFjkyk/aZVBegI0yVMF0z4=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "androidsdk": { + "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@rules_apple+//apple:apple.bzl%provisioning_profile_repository_extension": { + "general": { + "bzlTransitiveDigest": "pdRt+Wm+XQmS427nAIg9z7qfm56CnZChO+HJ4zu3Xa8=", + "usagesDigest": "vsJl8Rw5NL+5Ag2wdUDoTeRF/5klkXO8545Iy7U1Q08=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_provisioning_profiles": { + "repoRuleId": "@@rules_apple+//apple/internal:local_provisioning_profiles.bzl%provisioning_profile_repository", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "apple_support+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "bazel_tools", + "rules_cc", + "rules_cc+" + ], + [ + "rules_apple+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_apple+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_apple+", + "build_bazel_apple_support", + "apple_support+" + ], + [ + "rules_apple+", + "build_bazel_rules_swift", + "rules_swift+" + ], + [ + "rules_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_cc+", + "cc_compatibility_proxy", + "rules_cc++compatibility_proxy+cc_compatibility_proxy" + ], + [ + "rules_cc+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_cc++compatibility_proxy+cc_compatibility_proxy", + "rules_cc", + "rules_cc+" + ], + [ + "rules_swift+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_swift+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_swift+", + "build_bazel_apple_support", + "apple_support+" + ], + [ + "rules_swift+", + "build_bazel_rules_swift", + "rules_swift+" + ], + [ + "rules_swift+", + "build_bazel_rules_swift_local_config", + "rules_swift++non_module_deps+build_bazel_rules_swift_local_config" + ] + ] + } + }, + "@@rules_apple+//apple:extensions.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "4xtddSlWIQdtVNVuvOI62fJfQVETHZCVWFvYYwQHMR4=", + "usagesDigest": "M3VqFpeTCo4qmrNKGZw0dxBHvTYDrfV3cscGzlSAhQ4=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "xctestrunner": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/google/xctestrunner/archive/b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6.tar.gz" + ], + "strip_prefix": "xctestrunner-b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6", + "sha256": "ae3a063c985a8633cb7eb566db21656f8db8eb9a0edb8c182312c7f0db53730d" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_apple+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_buf+//buf:extensions.bzl%buf": { + "general": { + "bzlTransitiveDigest": "dSWqckK2ILN7aDIDHfv+Qrl1fb1hF7o7MDXY6T8C41s=", + "usagesDigest": "vxN6C2h72rUERbAmd1476FWpxdxo1NhYoY5JSFXJT3g=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_buf_toolchains": { + "repoRuleId": "@@rules_buf+//buf/internal:toolchain.bzl%buf_download_releases", + "attributes": { + "version": "v1.47.2", + "sha256": "1b37b75dc0a777a0cba17fa2604bc9906e55bb4c578823d8b7a8fe3fc9fe4439" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_buf+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_distroless+//apt:extensions.bzl%apt": { + "general": { + "bzlTransitiveDigest": "eH+PnBEEuvk2JyknjwUNuJrwPPryyUkKwi8qCYCVrvY=", + "usagesDigest": "niPoYX/Hk8+YvcLiQxLt75319UN95ORAe5Ii2c+VVlk=", + "recordedFileInputs": { + "@@score_tooling+//third_party/docs_runtime/manifest.yaml": "f8bd762e0dcaf3150504eca8dfd60819fc3be428d3a8b58d1d9cc52d68e16a45", + "@@score_tooling+//third_party/tooling_sysroot/manifest.yaml": "ef1e4af34dbf67a9e332c69ccad0b12b2e295849c33e98658c6ccd69e363c4cd" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "docs_runtime_base-files_13ubuntu10.4_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/base-files/base-files_13ubuntu10.4_amd64.deb" + ], + "sha256": "94daf9ede91f6263d676611623d4c9edab695c728a584ab2fb1d11cabb8479e8" + } + }, + "docs_runtime_libcrypt1_1-4.4.36-4build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt1_4.4.36-4build1_amd64.deb" + ], + "sha256": "9474785cd6f398512bf8c305c3901dbb111569dccb6f5832002373c0a8ac5832" + } + }, + "docs_runtime_libc6_2.39-0ubuntu8.7_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6_2.39-0ubuntu8.7_amd64.deb" + ], + "sha256": "955644e8bc2930a9bf8eea5e4c2237c8a118c1e2ac2845b993b6f7f35eefd293" + } + }, + "docs_runtime_libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgcc-s1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "aa7fadbe33b78bcf99885318040601c550c208929565b179891d9a3cc2aa68cd" + } + }, + "docs_runtime_gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/gcc-14-base_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "b95c172411a7fdae70307cf33a9f5320ba5e056b556454543dd5b679d5ce1c4f" + } + }, + "docs_runtime_mawk_1.3.4.20240123-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/m/mawk/mawk_1.3.4.20240123-1build1_amd64.deb" + ], + "sha256": "dc7f7f4dad4b48f6012ea65de3198d8376604afef39f06d65ec6167740e203c9" + } + }, + "docs_runtime_fakechroot_2.20.1-p-ds-15_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/f/fakechroot/fakechroot_2.20.1+ds-15_all.deb" + ], + "sha256": "f311e5c449314e8e66427277e901a415d3d77d4e3e8c91817a4a831e47467675" + } + }, + "docs_runtime_libfakechroot_2.20.1-p-ds-15_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/f/fakechroot/libfakechroot_2.20.1+ds-15_amd64.deb" + ], + "sha256": "6a9dd5907de0b94ab9e79cedd39b91a5cc783708675869dd588b0f5bebb97d70" + } + }, + "docs_runtime_binutils_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "b3b5a84181a38fd191820b2cdcc1a3eeb1cd6333ad472f2092f96e81047e9c74" + } + }, + "docs_runtime_binutils-x86-64-linux-gnu_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils-x86-64-linux-gnu_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "1e510a15f30208d39edcd840e48f26a77bbca7c417805eeccb1e3f7de198ef29" + } + }, + "docs_runtime_zlib1g_1-1.3.dfsg-3.1ubuntu2.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.1_amd64.deb" + ], + "sha256": "7074b6a2f6367a10d280c00a1cb02e74277709180bab4f2491a2f355ab2d6c20" + } + }, + "docs_runtime_libzstd1_1.5.5-p-dfsg2-2build1.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libz/libzstd/libzstd1_1.5.5+dfsg2-2build1.1_amd64.deb" + ], + "sha256": "dfcf25061e07aad7efd3f4f880ba5ad4d4d09ebe7fc8cc77ab6b8a161d6d4727" + } + }, + "docs_runtime_libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libstdc++6_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "a51f8de7829211db961a31f02158058ad1a95f92ac6d0a5dff6350e2821c54c0" + } + }, + "docs_runtime_libsframe1_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libsframe1_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "72093fb456864db55f1352bfa5e952a94f7abaff64e71dff1fbf001db1984564" + } + }, + "docs_runtime_libjansson4_2.14-2build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/j/jansson/libjansson4_2.14-2build2_amd64.deb" + ], + "sha256": "0cf79113f5d193ce9af2be2ff4b2c3b30dd4e55a0b6c47f7d28f6c849ff3aa60" + } + }, + "docs_runtime_libgprofng0_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libgprofng0_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "1b7e3c2fc162e8358ca6e5a3fffdb4d0d632f790630323215841bb36a63c0ab8" + } + }, + "docs_runtime_libbinutils_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libbinutils_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "064dce00ce94e1fc2d33779cb0071088f4c8aac79e85345f2e78a020f7d14699" + } + }, + "docs_runtime_binutils-common_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils-common_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "d136073f5e2153f3df11c1d08d66727b9466b28ff483f50085f14bbe3464b5ee" + } + }, + "docs_runtime_libctf0_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libctf0_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "7ec86d697c3668503c85f308a6832f092075b5880ad002f22185264da0bd4645" + } + }, + "docs_runtime_libctf-nobfd0_2.42-4ubuntu2.10_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libctf-nobfd0_2.42-4ubuntu2.10_amd64.deb" + ], + "sha256": "da352eb7fa6c4369d2a6c1e5e680f574eda2e38576563326b18d9e47e61c4078" + } + }, + "docs_runtime_graphviz_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/graphviz_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "be4e5b1b036babfb1663c095bc645c2fbab79dd57b213fc3b1ab0d48e810dd85" + } + }, + "docs_runtime_libxt6t64_1-1.2.1-1.2build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxt/libxt6t64_1.2.1-1.2build1_amd64.deb" + ], + "sha256": "2e4317d5ae1a45e517771ea0b8d93519b5f915ab08983facecd480d64dbd1489" + } + }, + "docs_runtime_libx11-6_2-1.8.7-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libx11/libx11-6_1.8.7-1build1_amd64.deb" + ], + "sha256": "397f84347476a3c5786b39f3ff6f0f82866eb3d8be6d2ad3efeadf019efe5b80" + } + }, + "docs_runtime_libx11-data_2-1.8.7-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libx11/libx11-data_1.8.7-1build1_all.deb" + ], + "sha256": "9ae01f7747e7f479394c697c55acf11d3baf139e8e54b7c4adfb55ef9c50de08" + } + }, + "docs_runtime_libxcb1_1.15-1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb1_1.15-1ubuntu2_amd64.deb" + ], + "sha256": "e1c6611d11ad7398326f1bf028afc34c3b14c51d917a3426b966ed4b9687fa58" + } + }, + "docs_runtime_libxdmcp6_1-1.1.3-0ubuntu6_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxdmcp/libxdmcp6_1.1.3-0ubuntu6_amd64.deb" + ], + "sha256": "bcd336fce11ce2a45f34d0f95e6980af22529f22147e8f98c156e5cee8ee42bb" + } + }, + "docs_runtime_libbsd0_0.12.1-1build1.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libb/libbsd/libbsd0_0.12.1-1build1.1_amd64.deb" + ], + "sha256": "f3857b0863ac5cfd4263e9bf6cfb1d4be88d5321e4070d5bc2b62b0949e6c86f" + } + }, + "docs_runtime_libmd0_1.1.0-2build1.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libm/libmd/libmd0_1.1.0-2build1.1_amd64.deb" + ], + "sha256": "e5ba01d3c41f256aaf57ec59aa0554857162e3e7f97cdfbff1ed2c0e8d720ee7" + } + }, + "docs_runtime_libxau6_1-1.0.9-1build6_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxau/libxau6_1.0.9-1build6_amd64.deb" + ], + "sha256": "e40d29f1d1a62393bacaedebe0da3d9006084152a9f7e5e029293f08ce1c5c80" + } + }, + "docs_runtime_libsm6_2-1.2.3-1build3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libs/libsm/libsm6_1.2.3-1build3_amd64.deb" + ], + "sha256": "1d27ebc381b499075a28c504be4d7d424c63b6866354736ac7f8d25813860cdf" + } + }, + "docs_runtime_libuuid1_2.39.3-9ubuntu6.5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libuuid1_2.39.3-9ubuntu6.5_amd64.deb" + ], + "sha256": "2f801582b5f0e7cb0c2d3d3651193e69f4540ee3b7dcb6079a3562f0880b9edf" + } + }, + "docs_runtime_libice6_2-1.0.10-1build3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libi/libice/libice6_1.0.10-1build3_amd64.deb" + ], + "sha256": "ad1edb5303574fee154e487947177e5bd15363aa71b92f78f5a2a7145fdb81c5" + } + }, + "docs_runtime_x11-common_1-7.7-p-23ubuntu3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/x/xorg/x11-common_7.7+23ubuntu3_all.deb" + ], + "sha256": "b545fa5196dd7467ba3770d6ce575abcd7941071961ea9f7535a319d9d20fd46" + } + }, + "docs_runtime_sysvinit-utils_3.08-6ubuntu3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/s/sysvinit/sysvinit-utils_3.08-6ubuntu3_amd64.deb" + ], + "sha256": "03cf5c9c28a5d186fb7f5214e464f831ff28177695cbb61e66083237267a047e" + } + }, + "docs_runtime_libxmu6_2-1.1.3-3build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxmu/libxmu6_1.1.3-3build2_amd64.deb" + ], + "sha256": "05c13bce0e9a80139dfa72cc8e7a695b4f7d58b1884423929eade62179d99853" + } + }, + "docs_runtime_libxext6_2-1.3.4-1build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxext/libxext6_1.3.4-1build2_amd64.deb" + ], + "sha256": "45783969a9ece9d7b7b733b8c60981584c53c6bc5ee3b42d295d2f80d1285679" + } + }, + "docs_runtime_libxaw7_2-1.0.14-1build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxaw/libxaw7_1.0.14-1build2_amd64.deb" + ], + "sha256": "2a9cdc82ecf566de76e05394efc604c9cced49e12c28b10e1ca101062b47bac0" + } + }, + "docs_runtime_libxpm4_1-3.5.17-1build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxpm/libxpm4_3.5.17-1build2_amd64.deb" + ], + "sha256": "ad9d9cb9be156d8b80c12735ecb4aae57e5501280a9f952749e8b71a7e5f9c97" + } + }, + "docs_runtime_liblab-gamut1_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/liblab-gamut1_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "b9fa73d671d96b07360dd3b7a4d35814c8b892b5bf4b1e0945d3bc7937c9ee3d" + } + }, + "docs_runtime_libgvpr2_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libgvpr2_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "1a560080462b80ab56e0fe09af2abd52974a256e25b4f384b9be5872c1073c82" + } + }, + "docs_runtime_libcgraph6_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libcgraph6_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "4555e20d8cd068de6343484c5bf825d03830c5048ccf56a9baec9638ca5815b2" + } + }, + "docs_runtime_libcdt5_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libcdt5_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "3c49c2624e6a895d729bff5be16c96beeb1347e3282bc40f3d210c715fba07ef" + } + }, + "docs_runtime_libgvc6_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libgvc6_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "dc674afb98d9b64699f63be3a4e92d4f3b563435ebfc70cbaec0c91b8f41fb48" + } + }, + "docs_runtime_libwebp7_1.3.2-0.4build3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libw/libwebp/libwebp7_1.3.2-0.4build3_amd64.deb" + ], + "sha256": "c86f6439f0bbc531f7199794654231f3b29327d6585958511b958795d51c2484" + } + }, + "docs_runtime_libsharpyuv0_1.3.2-0.4build3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libw/libwebp/libsharpyuv0_1.3.2-0.4build3_amd64.deb" + ], + "sha256": "4e1763494e5b9d34192313aa88e38201fc67b3f13ea96ca268d26401a3002791" + } + }, + "docs_runtime_libpathplan4_2.42.2-9ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libpathplan4_2.42.2-9ubuntu0.1_amd64.deb" + ], + "sha256": "8cff70c607271662df4719d2e2848731d8f23ab9108e79404066a6f93af9fd23" + } + }, + "docs_runtime_libpangoft2-1.0-0_1.52.1-p-ds-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpangoft2-1.0-0_1.52.1+ds-1build1_amd64.deb" + ], + "sha256": "cc6bc9d86ef5f329edacaa4895232d8a9b8f95c5cbc77c3c460a3f64cecc213d" + } + }, + "docs_runtime_libpango-1.0-0_1.52.1-p-ds-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpango-1.0-0_1.52.1+ds-1build1_amd64.deb" + ], + "sha256": "09dfa5c881ab273ec6bc1830adcefdc407fcd619316e68fb26ca3a23d0fc9f54" + } + }, + "docs_runtime_libthai0_0.1.29-2build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libthai/libthai0_0.1.29-2build1_amd64.deb" + ], + "sha256": "5ada7045c5f84a4b774e6449151800aa6470e8d01dc9d6124ef4a44ae6af5508" + } + }, + "docs_runtime_libdatrie1_0.2.13-3build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libdatrie/libdatrie1_0.2.13-3build1_amd64.deb" + ], + "sha256": "1ae164e40e413eac4fbd38ce1c6ef9591f7a03278ad9076d71fa29258727f447" + } + }, + "docs_runtime_libthai-data_0.1.29-2build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libthai/libthai-data_0.1.29-2build1_all.deb" + ], + "sha256": "6035d4a714290b97816bed7f3bf64921c6358ddb84d1dacdddccdc1cf39bffb7" + } + }, + "docs_runtime_libharfbuzz0b_8.3.0-2build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/h/harfbuzz/libharfbuzz0b_8.3.0-2build2_amd64.deb" + ], + "sha256": "d6f7eea2244f98aa0463a056680d4629476bf624767ede301560e24add686b5c" + } + }, + "docs_runtime_libgraphite2-3_1.3.14-2build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/graphite2/libgraphite2-3_1.3.14-2build1_amd64.deb" + ], + "sha256": "e2a91c59a2b26649ed0b331bedab0c92e56cc2021cce27df1080089edaad7aba" + } + }, + "docs_runtime_libglib2.0-0t64_2.80.0-6ubuntu3.8_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glib2.0/libglib2.0-0t64_2.80.0-6ubuntu3.8_amd64.deb" + ], + "sha256": "ca4eda0e01c76ba2e5e501e77decce53d98a641234b517eb98fc5d74980f913f" + } + }, + "docs_runtime_libselinux1_3.5-2ubuntu2.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libs/libselinux/libselinux1_3.5-2ubuntu2.1_amd64.deb" + ], + "sha256": "6abaa6c26f46ef17764c4a753e0e84de1cdadde5634fd2987621fdc617988d19" + } + }, + "docs_runtime_libpcre2-8-0_10.42-4ubuntu2.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pcre2/libpcre2-8-0_10.42-4ubuntu2.1_amd64.deb" + ], + "sha256": "110a797a57673d3ee497a141cf988199258058c57525799c63194d81822529a0" + } + }, + "docs_runtime_libmount1_2.39.3-9ubuntu6.5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libmount1_2.39.3-9ubuntu6.5_amd64.deb" + ], + "sha256": "7ca31424fbfc96fbf245e6fe232fd2d2ec74169ca1add968e1987bece5bc0d1f" + } + }, + "docs_runtime_libblkid1_2.39.3-9ubuntu6.5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libblkid1_2.39.3-9ubuntu6.5_amd64.deb" + ], + "sha256": "2307a9ed92642a69de0284ac63e233e45ac5a2c3831f04399f7d212379487e82" + } + }, + "docs_runtime_libffi8_3.4.6-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libf/libffi/libffi8_3.4.6-1build1_amd64.deb" + ], + "sha256": "637e6a7744de08cd331a41f4efd0d24e6ea9064843dea9d1c6ca87bdb5f038a2" + } + }, + "docs_runtime_libfreetype6_2.13.2-p-dfsg-1ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/freetype/libfreetype6_2.13.2+dfsg-1ubuntu0.1_amd64.deb" + ], + "sha256": "f6937fd8a77e83001dcfd3857d5a5cfbd4caaeb297c7fdb71ec50514843e48af" + } + }, + "docs_runtime_libpng16-16t64_1.6.43-5ubuntu0.5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libp/libpng1.6/libpng16-16t64_1.6.43-5ubuntu0.5_amd64.deb" + ], + "sha256": "074c954a7a01069c3b3db9146911666f6ac75c1277e034eba901ee274554dadc" + } + }, + "docs_runtime_libbz2-1.0_1.0.8-5.1build0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/bzip2/libbz2-1.0_1.0.8-5.1build0.1_amd64.deb" + ], + "sha256": "d557ab12b42ab370249142099fae3cbb979948934e4dfa58c2ab59bf5bbbda73" + } + }, + "docs_runtime_libbrotli1_1.1.0-2build2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/brotli/libbrotli1_1.1.0-2build2_amd64.deb" + ], + "sha256": "74492419b8fda803774b8c9acef6afc5d2f9ff31782635aae212906adae7b277" + } + }, + "docs_runtime_libfribidi0_1.0.13-3build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fribidi/libfribidi0_1.0.13-3build1_amd64.deb" + ], + "sha256": "6cd50259d39ce0dfafee2632c6268538e6a02590e77161a133e9683af346dd1d" + } + }, + "docs_runtime_fontconfig_2.15.0-1.1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/fontconfig_2.15.0-1.1ubuntu2_amd64.deb" + ], + "sha256": "ddf0aace42b13a5bc38904e848b145b787ea254cddf5213d150254bd654db6e5" + } + }, + "docs_runtime_fontconfig-config_2.15.0-1.1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/fontconfig-config_2.15.0-1.1ubuntu2_amd64.deb" + ], + "sha256": "9df0579cd298a1f2b7a40efd519c849745aecd193a09733cf4d1032284a62bbf" + } + }, + "docs_runtime_fonts-dejavu-core_2.37-8_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fonts-dejavu/fonts-dejavu-core_2.37-8_all.deb" + ], + "sha256": "40049660c194f3b8a2541fc7369efebb10e9f94bdac836a2f38fafedd10fa73a" + } + }, + "docs_runtime_fonts-dejavu-mono_2.37-8_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fonts-dejavu/fonts-dejavu-mono_2.37-8_all.deb" + ], + "sha256": "8a599d6553307db7ecb795d2f0e5a301e03234afc75c7358b0ba43466454c89a" + } + }, + "docs_runtime_libfontconfig1_2.15.0-1.1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/libfontconfig1_2.15.0-1.1ubuntu2_amd64.deb" + ], + "sha256": "a2bc05cfef021fdb84285036f98eda5ebec3c4b7a378f5aa2bdba5c4d3d8d586" + } + }, + "docs_runtime_libexpat1_2.6.1-2ubuntu0.4_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/e/expat/libexpat1_2.6.1-2ubuntu0.4_amd64.deb" + ], + "sha256": "126a5612e652bdc2edee19ae8fe4308db72b5b3b0a5581bf885b44a093baf3e5" + } + }, + "docs_runtime_libpangocairo-1.0-0_1.52.1-p-ds-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpangocairo-1.0-0_1.52.1+ds-1build1_amd64.deb" + ], + "sha256": "98cf5fc9076c2911fe20dfc1e41cd8f686a2bb5d539b1105fab18105b0db1376" + } + }, + "docs_runtime_libcairo2_1.18.0-3build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/c/cairo/libcairo2_1.18.0-3build1_amd64.deb" + ], + "sha256": "96950b306889ff6e4248bb937b0a3b56e72dacf643fe732214ce375f0f6bbb36" + } + }, + "docs_runtime_libxrender1_1-0.9.10-1.1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxrender/libxrender1_0.9.10-1.1build1_amd64.deb" + ], + "sha256": "d70bd831aebe8d4834b5dd2ed98df26dd6bd27f1042c47543bd7f66df1ae22ea" + } + }, + "docs_runtime_libxcb-shm0_1.15-1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb-shm0_1.15-1ubuntu2_amd64.deb" + ], + "sha256": "229d1280d459f1ba44c22939d3f9b61d9d20932d9a646b3fe4ce50be4cdf2325" + } + }, + "docs_runtime_libxcb-render0_1.15-1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb-render0_1.15-1ubuntu2_amd64.deb" + ], + "sha256": "7d83a0668b1a693b5ea2e496206e8371fb6beda4c54a2b4b3902005915c272c5" + } + }, + "docs_runtime_libpixman-1-0_0.42.2-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pixman/libpixman-1-0_0.42.2-1build1_amd64.deb" + ], + "sha256": "d9c2931c4c424615eeab9dd5ae08bfc608b84e803c1d3ccddf319270db213421" + } + }, + "docs_runtime_libltdl7_2.4.7-7build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libtool/libltdl7_2.4.7-7build1_amd64.deb" + ], + "sha256": "02d0d2d7e1bf73f838a92f8df7a9b07b698c837e82bd89aee6a581cf793cd966" + } + }, + "docs_runtime_libgts-0.7-5t64_0.7.6-p-darcs121130-5.2build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/gts/libgts-0.7-5t64_0.7.6+darcs121130-5.2build1_amd64.deb" + ], + "sha256": "a6741ed94f3e786eaed0a9fcb69f641327cfe288af4f043e7036b5257e87fc48" + } + }, + "docs_runtime_libgd3_2.3.3-9ubuntu5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libg/libgd2/libgd3_2.3.3-9ubuntu5_amd64.deb" + ], + "sha256": "dbef5ad99eec399fd6afeb6d0cc92d81a8b3295a7ac80ac71311ea09c49704ae" + } + }, + "docs_runtime_libtiff6_4.5.1-p-git230720-4ubuntu2.5_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/t/tiff/libtiff6_4.5.1+git230720-4ubuntu2.5_amd64.deb" + ], + "sha256": "564cdf59dda5e1a826c51b5868ee2785fffa26ee5a7bad95bc5e8c8224c931b8" + } + }, + "docs_runtime_liblzma5_5.6.1-p-really5.4.5-1ubuntu0.2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/x/xz-utils/liblzma5_5.6.1+really5.4.5-1ubuntu0.2_amd64.deb" + ], + "sha256": "4c31cc76391ca47dbb4585edc740728f43fe7b6b090f5b3947fc8072db698aca" + } + }, + "docs_runtime_liblerc4_4.0.0-p-ds-4ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/l/lerc/liblerc4_4.0.0+ds-4ubuntu2_amd64.deb" + ], + "sha256": "f1b9dbfa28c56564f6b544f3757f5f3f4d549ce9962f39e897812c23b0a5d0e7" + } + }, + "docs_runtime_libjpeg8_8c-2ubuntu11_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libj/libjpeg8-empty/libjpeg8_8c-2ubuntu11_amd64.deb" + ], + "sha256": "4d6ed682972bddf62af158a06d68a0dda497e421423b7ca92fb450b3d9ceaac9" + } + }, + "docs_runtime_libjpeg-turbo8_2.1.5-2ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libj/libjpeg-turbo/libjpeg-turbo8_2.1.5-2ubuntu2_amd64.deb" + ], + "sha256": "f68b5b23bc8a1688fb787d2aed7e2cdf895a73022f6a5025e183162dac4500b2" + } + }, + "docs_runtime_libjbig0_2.1-6.1ubuntu2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/j/jbigkit/libjbig0_2.1-6.1ubuntu2_amd64.deb" + ], + "sha256": "074a760a86213a1286ad60f56394c90885cf45af070626a88c480d90b78c175a" + } + }, + "docs_runtime_libdeflate0_1.19-1build1.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libdeflate/libdeflate0_1.19-1build1.1_amd64.deb" + ], + "sha256": "8e7dfa9e63a9b5058071b84da48bb2e30dea07de169e80fbc759fe0e68639269" + } + }, + "docs_runtime_libheif1_1.17.6-1ubuntu4.2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif1_1.17.6-1ubuntu4.2_amd64.deb" + ], + "sha256": "c41176242ae4a6a66fa50fab00dc6d951711f0cf8aab32cf13530c4a404a7026" + } + }, + "docs_runtime_libheif-plugin-libde265_1.17.6-1ubuntu4.2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif-plugin-libde265_1.17.6-1ubuntu4.2_amd64.deb" + ], + "sha256": "f5284ae47a70538c503b15f458783df569ac7b8d5d16aaeac4e04c2d3b8e7341" + } + }, + "docs_runtime_libde265-0_1.0.15-1build3_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libde265/libde265-0_1.0.15-1build3_amd64.deb" + ], + "sha256": "3b8cb1fb70933261d076d1b2882fb303aa8da1a951ad7614234f890468c90310" + } + }, + "docs_runtime_libheif-plugin-aomdec_1.17.6-1ubuntu4.2_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif-plugin-aomdec_1.17.6-1ubuntu4.2_amd64.deb" + ], + "sha256": "65ce5cb8f2ee27127b7df6b358bde6e58ebcf00e1d9f5c92c32c842cfa260ef6" + } + }, + "docs_runtime_libaom3_3.8.2-2ubuntu0.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/a/aom/libaom3_3.8.2-2ubuntu0.1_amd64.deb" + ], + "sha256": "1623e49454a2981069ed4801c853630a63a68f77c73056dea11e3289a8467eb9" + } + }, + "docs_runtime_libann0_1.1.2-p-doc-9build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/a/ann/libann0_1.1.2+doc-9build1_amd64.deb" + ], + "sha256": "88347025b6292517dc591fd6a51c28b6a91a46c999505e3e54677c99038074e1" + } + }, + "docs_runtime_resolve": { + "repoRuleId": "@@rules_distroless+//apt/private:deb_resolve.bzl%deb_resolve", + "attributes": { + "manifest": "@@score_tooling+//third_party/docs_runtime:manifest.yaml", + "resolve_transitive": true + } + }, + "docs_runtime": { + "repoRuleId": "@@rules_distroless+//apt/private:deb_translate_lock.bzl%deb_translate_lock", + "attributes": { + "lock_content": "{\n\t\"packages\": [\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"mawk_1.3.4.20240123-1build1_amd64\",\n\t\t\t\t\t\"name\": \"mawk\",\n\t\t\t\t\t\"version\": \"1.3.4.20240123-1build1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"base-files_13ubuntu10.4_amd64\",\n\t\t\t\"name\": \"base-files\",\n\t\t\t\"sha256\": \"94daf9ede91f6263d676611623d4c9edab695c728a584ab2fb1d11cabb8479e8\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/base-files/base-files_13ubuntu10.4_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"13ubuntu10.4\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\"sha256\": \"9474785cd6f398512bf8c305c3901dbb111569dccb6f5832002373c0a8ac5832\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt1_4.4.36-4build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\"name\": \"libc6\",\n\t\t\t\"sha256\": \"955644e8bc2930a9bf8eea5e4c2237c8a118c1e2ac2845b993b6f7f35eefd293\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6_2.39-0ubuntu8.7_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\"sha256\": \"aa7fadbe33b78bcf99885318040601c550c208929565b179891d9a3cc2aa68cd\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgcc-s1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\"sha256\": \"b95c172411a7fdae70307cf33a9f5320ba5e056b556454543dd5b679d5ce1c4f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/gcc-14-base_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"mawk_1.3.4.20240123-1build1_amd64\",\n\t\t\t\"name\": \"mawk\",\n\t\t\t\"sha256\": \"dc7f7f4dad4b48f6012ea65de3198d8376604afef39f06d65ec6167740e203c9\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/m/mawk/mawk_1.3.4.20240123-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.3.4.20240123-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libfakechroot_2.20.1-p-ds-15_amd64\",\n\t\t\t\t\t\"name\": \"libfakechroot\",\n\t\t\t\t\t\"version\": \"2.20.1+ds-15\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"binutils_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"binutils\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"binutils-x86-64-linux-gnu_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"binutils-x86-64-linux-gnu\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"zlib1g_1-1.3.dfsg-3.1ubuntu2.1_amd64\",\n\t\t\t\t\t\"name\": \"zlib1g\",\n\t\t\t\t\t\"version\": \"1:1.3.dfsg-3.1ubuntu2.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libzstd1_1.5.5-p-dfsg2-2build1.1_amd64\",\n\t\t\t\t\t\"name\": \"libzstd1\",\n\t\t\t\t\t\"version\": \"1.5.5+dfsg2-2build1.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libstdc++6\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libsframe1_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"libsframe1\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libjansson4_2.14-2build2_amd64\",\n\t\t\t\t\t\"name\": \"libjansson4\",\n\t\t\t\t\t\"version\": \"2.14-2build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgprofng0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"libgprofng0\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libbinutils_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"libbinutils\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"binutils-common_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"binutils-common\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libctf0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"libctf0\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libctf-nobfd0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\t\t\"name\": \"libctf-nobfd0\",\n\t\t\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"fakechroot_2.20.1-p-ds-15_amd64\",\n\t\t\t\"name\": \"fakechroot\",\n\t\t\t\"sha256\": \"f311e5c449314e8e66427277e901a415d3d77d4e3e8c91817a4a831e47467675\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/f/fakechroot/fakechroot_2.20.1+ds-15_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.20.1+ds-15\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libfakechroot_2.20.1-p-ds-15_amd64\",\n\t\t\t\"name\": \"libfakechroot\",\n\t\t\t\"sha256\": \"6a9dd5907de0b94ab9e79cedd39b91a5cc783708675869dd588b0f5bebb97d70\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/f/fakechroot/libfakechroot_2.20.1+ds-15_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.20.1+ds-15\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"binutils_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"binutils\",\n\t\t\t\"sha256\": \"b3b5a84181a38fd191820b2cdcc1a3eeb1cd6333ad472f2092f96e81047e9c74\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"binutils-x86-64-linux-gnu_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"binutils-x86-64-linux-gnu\",\n\t\t\t\"sha256\": \"1e510a15f30208d39edcd840e48f26a77bbca7c417805eeccb1e3f7de198ef29\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils-x86-64-linux-gnu_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"zlib1g_1-1.3.dfsg-3.1ubuntu2.1_amd64\",\n\t\t\t\"name\": \"zlib1g\",\n\t\t\t\"sha256\": \"7074b6a2f6367a10d280c00a1cb02e74277709180bab4f2491a2f355ab2d6c20\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/z/zlib/zlib1g_1.3.dfsg-3.1ubuntu2.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:1.3.dfsg-3.1ubuntu2.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libzstd1_1.5.5-p-dfsg2-2build1.1_amd64\",\n\t\t\t\"name\": \"libzstd1\",\n\t\t\t\"sha256\": \"dfcf25061e07aad7efd3f4f880ba5ad4d4d09ebe7fc8cc77ab6b8a161d6d4727\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libz/libzstd/libzstd1_1.5.5+dfsg2-2build1.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.5.5+dfsg2-2build1.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libstdc++6\",\n\t\t\t\"sha256\": \"a51f8de7829211db961a31f02158058ad1a95f92ac6d0a5dff6350e2821c54c0\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libstdc++6_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libsframe1_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"libsframe1\",\n\t\t\t\"sha256\": \"72093fb456864db55f1352bfa5e952a94f7abaff64e71dff1fbf001db1984564\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libsframe1_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libjansson4_2.14-2build2_amd64\",\n\t\t\t\"name\": \"libjansson4\",\n\t\t\t\"sha256\": \"0cf79113f5d193ce9af2be2ff4b2c3b30dd4e55a0b6c47f7d28f6c849ff3aa60\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/j/jansson/libjansson4_2.14-2build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.14-2build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgprofng0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"libgprofng0\",\n\t\t\t\"sha256\": \"1b7e3c2fc162e8358ca6e5a3fffdb4d0d632f790630323215841bb36a63c0ab8\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libgprofng0_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libbinutils_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"libbinutils\",\n\t\t\t\"sha256\": \"064dce00ce94e1fc2d33779cb0071088f4c8aac79e85345f2e78a020f7d14699\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libbinutils_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"binutils-common_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"binutils-common\",\n\t\t\t\"sha256\": \"d136073f5e2153f3df11c1d08d66727b9466b28ff483f50085f14bbe3464b5ee\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/binutils-common_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libctf0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"libctf0\",\n\t\t\t\"sha256\": \"7ec86d697c3668503c85f308a6832f092075b5880ad002f22185264da0bd4645\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libctf0_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libctf-nobfd0_2.42-4ubuntu2.10_amd64\",\n\t\t\t\"name\": \"libctf-nobfd0\",\n\t\t\t\"sha256\": \"da352eb7fa6c4369d2a6c1e5e680f574eda2e38576563326b18d9e47e61c4078\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/binutils/libctf-nobfd0_2.42-4ubuntu2.10_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42-4ubuntu2.10\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxt6t64_1-1.2.1-1.2build1_amd64\",\n\t\t\t\t\t\"name\": \"libxt6t64\",\n\t\t\t\t\t\"version\": \"1:1.2.1-1.2build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libx11-6_2-1.8.7-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libx11-6\",\n\t\t\t\t\t\"version\": \"2:1.8.7-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libx11-data_2-1.8.7-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libx11-data\",\n\t\t\t\t\t\"version\": \"2:1.8.7-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxcb1_1.15-1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libxcb1\",\n\t\t\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxdmcp6_1-1.1.3-0ubuntu6_amd64\",\n\t\t\t\t\t\"name\": \"libxdmcp6\",\n\t\t\t\t\t\"version\": \"1:1.1.3-0ubuntu6\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libbsd0_0.12.1-1build1.1_amd64\",\n\t\t\t\t\t\"name\": \"libbsd0\",\n\t\t\t\t\t\"version\": \"0.12.1-1build1.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libmd0_1.1.0-2build1.1_amd64\",\n\t\t\t\t\t\"name\": \"libmd0\",\n\t\t\t\t\t\"version\": \"1.1.0-2build1.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxau6_1-1.0.9-1build6_amd64\",\n\t\t\t\t\t\"name\": \"libxau6\",\n\t\t\t\t\t\"version\": \"1:1.0.9-1build6\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libsm6_2-1.2.3-1build3_amd64\",\n\t\t\t\t\t\"name\": \"libsm6\",\n\t\t\t\t\t\"version\": \"2:1.2.3-1build3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libuuid1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\t\t\"name\": \"libuuid1\",\n\t\t\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libice6_2-1.0.10-1build3_amd64\",\n\t\t\t\t\t\"name\": \"libice6\",\n\t\t\t\t\t\"version\": \"2:1.0.10-1build3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"x11-common_1-7.7-p-23ubuntu3_amd64\",\n\t\t\t\t\t\"name\": \"x11-common\",\n\t\t\t\t\t\"version\": \"1:7.7+23ubuntu3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"sysvinit-utils_3.08-6ubuntu3_amd64\",\n\t\t\t\t\t\"name\": \"sysvinit-utils\",\n\t\t\t\t\t\"version\": \"3.08-6ubuntu3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxmu6_2-1.1.3-3build2_amd64\",\n\t\t\t\t\t\"name\": \"libxmu6\",\n\t\t\t\t\t\"version\": \"2:1.1.3-3build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxext6_2-1.3.4-1build2_amd64\",\n\t\t\t\t\t\"name\": \"libxext6\",\n\t\t\t\t\t\"version\": \"2:1.3.4-1build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxaw7_2-1.0.14-1build2_amd64\",\n\t\t\t\t\t\"name\": \"libxaw7\",\n\t\t\t\t\t\"version\": \"2:1.0.14-1build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxpm4_1-3.5.17-1build2_amd64\",\n\t\t\t\t\t\"name\": \"libxpm4\",\n\t\t\t\t\t\"version\": \"1:3.5.17-1build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libstdc++6\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"liblab-gamut1_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"liblab-gamut1\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgvpr2_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libgvpr2\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcgraph6_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libcgraph6\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcdt5_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libcdt5\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgvc6_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libgvc6\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"zlib1g_1-1.3.dfsg-3.1ubuntu2.1_amd64\",\n\t\t\t\t\t\"name\": \"zlib1g\",\n\t\t\t\t\t\"version\": \"1:1.3.dfsg-3.1ubuntu2.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libwebp7_1.3.2-0.4build3_amd64\",\n\t\t\t\t\t\"name\": \"libwebp7\",\n\t\t\t\t\t\"version\": \"1.3.2-0.4build3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libsharpyuv0_1.3.2-0.4build3_amd64\",\n\t\t\t\t\t\"name\": \"libsharpyuv0\",\n\t\t\t\t\t\"version\": \"1.3.2-0.4build3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpathplan4_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libpathplan4\",\n\t\t\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpangoft2-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libpangoft2-1.0-0\",\n\t\t\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpango-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libpango-1.0-0\",\n\t\t\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libthai0_0.1.29-2build1_amd64\",\n\t\t\t\t\t\"name\": \"libthai0\",\n\t\t\t\t\t\"version\": \"0.1.29-2build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libdatrie1_0.2.13-3build1_amd64\",\n\t\t\t\t\t\"name\": \"libdatrie1\",\n\t\t\t\t\t\"version\": \"0.2.13-3build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libthai-data_0.1.29-2build1_amd64\",\n\t\t\t\t\t\"name\": \"libthai-data\",\n\t\t\t\t\t\"version\": \"0.1.29-2build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libharfbuzz0b_8.3.0-2build2_amd64\",\n\t\t\t\t\t\"name\": \"libharfbuzz0b\",\n\t\t\t\t\t\"version\": \"8.3.0-2build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgraphite2-3_1.3.14-2build1_amd64\",\n\t\t\t\t\t\"name\": \"libgraphite2-3\",\n\t\t\t\t\t\"version\": \"1.3.14-2build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libglib2.0-0t64_2.80.0-6ubuntu3.8_amd64\",\n\t\t\t\t\t\"name\": \"libglib2.0-0t64\",\n\t\t\t\t\t\"version\": \"2.80.0-6ubuntu3.8\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libselinux1_3.5-2ubuntu2.1_amd64\",\n\t\t\t\t\t\"name\": \"libselinux1\",\n\t\t\t\t\t\"version\": \"3.5-2ubuntu2.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpcre2-8-0_10.42-4ubuntu2.1_amd64\",\n\t\t\t\t\t\"name\": \"libpcre2-8-0\",\n\t\t\t\t\t\"version\": \"10.42-4ubuntu2.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libmount1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\t\t\"name\": \"libmount1\",\n\t\t\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libblkid1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\t\t\"name\": \"libblkid1\",\n\t\t\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libffi8_3.4.6-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libffi8\",\n\t\t\t\t\t\"version\": \"3.4.6-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libfreetype6_2.13.2-p-dfsg-1ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libfreetype6\",\n\t\t\t\t\t\"version\": \"2.13.2+dfsg-1ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpng16-16t64_1.6.43-5ubuntu0.5_amd64\",\n\t\t\t\t\t\"name\": \"libpng16-16t64\",\n\t\t\t\t\t\"version\": \"1.6.43-5ubuntu0.5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libbz2-1.0_1.0.8-5.1build0.1_amd64\",\n\t\t\t\t\t\"name\": \"libbz2-1.0\",\n\t\t\t\t\t\"version\": \"1.0.8-5.1build0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libbrotli1_1.1.0-2build2_amd64\",\n\t\t\t\t\t\"name\": \"libbrotli1\",\n\t\t\t\t\t\"version\": \"1.1.0-2build2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libfribidi0_1.0.13-3build1_amd64\",\n\t\t\t\t\t\"name\": \"libfribidi0\",\n\t\t\t\t\t\"version\": \"1.0.13-3build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"fontconfig_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"fontconfig\",\n\t\t\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"fontconfig-config_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"fontconfig-config\",\n\t\t\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"fonts-dejavu-core_2.37-8_amd64\",\n\t\t\t\t\t\"name\": \"fonts-dejavu-core\",\n\t\t\t\t\t\"version\": \"2.37-8\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"fonts-dejavu-mono_2.37-8_amd64\",\n\t\t\t\t\t\"name\": \"fonts-dejavu-mono\",\n\t\t\t\t\t\"version\": \"2.37-8\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libfontconfig1_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libfontconfig1\",\n\t\t\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libexpat1_2.6.1-2ubuntu0.4_amd64\",\n\t\t\t\t\t\"name\": \"libexpat1\",\n\t\t\t\t\t\"version\": \"2.6.1-2ubuntu0.4\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpangocairo-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libpangocairo-1.0-0\",\n\t\t\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcairo2_1.18.0-3build1_amd64\",\n\t\t\t\t\t\"name\": \"libcairo2\",\n\t\t\t\t\t\"version\": \"1.18.0-3build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxrender1_1-0.9.10-1.1build1_amd64\",\n\t\t\t\t\t\"name\": \"libxrender1\",\n\t\t\t\t\t\"version\": \"1:0.9.10-1.1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxcb-shm0_1.15-1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libxcb-shm0\",\n\t\t\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libxcb-render0_1.15-1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libxcb-render0\",\n\t\t\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libpixman-1-0_0.42.2-1build1_amd64\",\n\t\t\t\t\t\"name\": \"libpixman-1-0\",\n\t\t\t\t\t\"version\": \"0.42.2-1build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libltdl7_2.4.7-7build1_amd64\",\n\t\t\t\t\t\"name\": \"libltdl7\",\n\t\t\t\t\t\"version\": \"2.4.7-7build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgts-0.7-5t64_0.7.6-p-darcs121130-5.2build1_amd64\",\n\t\t\t\t\t\"name\": \"libgts-0.7-5t64\",\n\t\t\t\t\t\"version\": \"0.7.6+darcs121130-5.2build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgd3_2.3.3-9ubuntu5_amd64\",\n\t\t\t\t\t\"name\": \"libgd3\",\n\t\t\t\t\t\"version\": \"2.3.3-9ubuntu5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libtiff6_4.5.1-p-git230720-4ubuntu2.5_amd64\",\n\t\t\t\t\t\"name\": \"libtiff6\",\n\t\t\t\t\t\"version\": \"4.5.1+git230720-4ubuntu2.5\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libzstd1_1.5.5-p-dfsg2-2build1.1_amd64\",\n\t\t\t\t\t\"name\": \"libzstd1\",\n\t\t\t\t\t\"version\": \"1.5.5+dfsg2-2build1.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"liblzma5_5.6.1-p-really5.4.5-1ubuntu0.2_amd64\",\n\t\t\t\t\t\"name\": \"liblzma5\",\n\t\t\t\t\t\"version\": \"5.6.1+really5.4.5-1ubuntu0.2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"liblerc4_4.0.0-p-ds-4ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"liblerc4\",\n\t\t\t\t\t\"version\": \"4.0.0+ds-4ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libjpeg8_8c-2ubuntu11_amd64\",\n\t\t\t\t\t\"name\": \"libjpeg8\",\n\t\t\t\t\t\"version\": \"8c-2ubuntu11\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libjpeg-turbo8_2.1.5-2ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libjpeg-turbo8\",\n\t\t\t\t\t\"version\": \"2.1.5-2ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libjbig0_2.1-6.1ubuntu2_amd64\",\n\t\t\t\t\t\"name\": \"libjbig0\",\n\t\t\t\t\t\"version\": \"2.1-6.1ubuntu2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libdeflate0_1.19-1build1.1_amd64\",\n\t\t\t\t\t\"name\": \"libdeflate0\",\n\t\t\t\t\t\"version\": \"1.19-1build1.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libheif1_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\t\t\"name\": \"libheif1\",\n\t\t\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libheif-plugin-libde265_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\t\t\"name\": \"libheif-plugin-libde265\",\n\t\t\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libde265-0_1.0.15-1build3_amd64\",\n\t\t\t\t\t\"name\": \"libde265-0\",\n\t\t\t\t\t\"version\": \"1.0.15-1build3\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libheif-plugin-aomdec_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\t\t\"name\": \"libheif-plugin-aomdec\",\n\t\t\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libaom3_3.8.2-2ubuntu0.1_amd64\",\n\t\t\t\t\t\"name\": \"libaom3\",\n\t\t\t\t\t\"version\": \"3.8.2-2ubuntu0.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libann0_1.1.2-p-doc-9build1_amd64\",\n\t\t\t\t\t\"name\": \"libann0\",\n\t\t\t\t\t\"version\": \"1.1.2+doc-9build1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"graphviz_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"graphviz\",\n\t\t\t\"sha256\": \"be4e5b1b036babfb1663c095bc645c2fbab79dd57b213fc3b1ab0d48e810dd85\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/graphviz_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxt6t64_1-1.2.1-1.2build1_amd64\",\n\t\t\t\"name\": \"libxt6t64\",\n\t\t\t\"sha256\": \"2e4317d5ae1a45e517771ea0b8d93519b5f915ab08983facecd480d64dbd1489\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxt/libxt6t64_1.2.1-1.2build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:1.2.1-1.2build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libx11-6_2-1.8.7-1build1_amd64\",\n\t\t\t\"name\": \"libx11-6\",\n\t\t\t\"sha256\": \"397f84347476a3c5786b39f3ff6f0f82866eb3d8be6d2ad3efeadf019efe5b80\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libx11/libx11-6_1.8.7-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.8.7-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libx11-data_2-1.8.7-1build1_amd64\",\n\t\t\t\"name\": \"libx11-data\",\n\t\t\t\"sha256\": \"9ae01f7747e7f479394c697c55acf11d3baf139e8e54b7c4adfb55ef9c50de08\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libx11/libx11-data_1.8.7-1build1_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.8.7-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxcb1_1.15-1ubuntu2_amd64\",\n\t\t\t\"name\": \"libxcb1\",\n\t\t\t\"sha256\": \"e1c6611d11ad7398326f1bf028afc34c3b14c51d917a3426b966ed4b9687fa58\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb1_1.15-1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxdmcp6_1-1.1.3-0ubuntu6_amd64\",\n\t\t\t\"name\": \"libxdmcp6\",\n\t\t\t\"sha256\": \"bcd336fce11ce2a45f34d0f95e6980af22529f22147e8f98c156e5cee8ee42bb\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxdmcp/libxdmcp6_1.1.3-0ubuntu6_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:1.1.3-0ubuntu6\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libbsd0_0.12.1-1build1.1_amd64\",\n\t\t\t\"name\": \"libbsd0\",\n\t\t\t\"sha256\": \"f3857b0863ac5cfd4263e9bf6cfb1d4be88d5321e4070d5bc2b62b0949e6c86f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libb/libbsd/libbsd0_0.12.1-1build1.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.12.1-1build1.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libmd0_1.1.0-2build1.1_amd64\",\n\t\t\t\"name\": \"libmd0\",\n\t\t\t\"sha256\": \"e5ba01d3c41f256aaf57ec59aa0554857162e3e7f97cdfbff1ed2c0e8d720ee7\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libm/libmd/libmd0_1.1.0-2build1.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.1.0-2build1.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxau6_1-1.0.9-1build6_amd64\",\n\t\t\t\"name\": \"libxau6\",\n\t\t\t\"sha256\": \"e40d29f1d1a62393bacaedebe0da3d9006084152a9f7e5e029293f08ce1c5c80\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxau/libxau6_1.0.9-1build6_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:1.0.9-1build6\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libsm6_2-1.2.3-1build3_amd64\",\n\t\t\t\"name\": \"libsm6\",\n\t\t\t\"sha256\": \"1d27ebc381b499075a28c504be4d7d424c63b6866354736ac7f8d25813860cdf\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libs/libsm/libsm6_1.2.3-1build3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.2.3-1build3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libuuid1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\"name\": \"libuuid1\",\n\t\t\t\"sha256\": \"2f801582b5f0e7cb0c2d3d3651193e69f4540ee3b7dcb6079a3562f0880b9edf\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libuuid1_2.39.3-9ubuntu6.5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libice6_2-1.0.10-1build3_amd64\",\n\t\t\t\"name\": \"libice6\",\n\t\t\t\"sha256\": \"ad1edb5303574fee154e487947177e5bd15363aa71b92f78f5a2a7145fdb81c5\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libi/libice/libice6_1.0.10-1build3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.0.10-1build3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"x11-common_1-7.7-p-23ubuntu3_amd64\",\n\t\t\t\"name\": \"x11-common\",\n\t\t\t\"sha256\": \"b545fa5196dd7467ba3770d6ce575abcd7941071961ea9f7535a319d9d20fd46\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/x/xorg/x11-common_7.7+23ubuntu3_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:7.7+23ubuntu3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"sysvinit-utils_3.08-6ubuntu3_amd64\",\n\t\t\t\"name\": \"sysvinit-utils\",\n\t\t\t\"sha256\": \"03cf5c9c28a5d186fb7f5214e464f831ff28177695cbb61e66083237267a047e\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/s/sysvinit/sysvinit-utils_3.08-6ubuntu3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"3.08-6ubuntu3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxmu6_2-1.1.3-3build2_amd64\",\n\t\t\t\"name\": \"libxmu6\",\n\t\t\t\"sha256\": \"05c13bce0e9a80139dfa72cc8e7a695b4f7d58b1884423929eade62179d99853\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxmu/libxmu6_1.1.3-3build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.1.3-3build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxext6_2-1.3.4-1build2_amd64\",\n\t\t\t\"name\": \"libxext6\",\n\t\t\t\"sha256\": \"45783969a9ece9d7b7b733b8c60981584c53c6bc5ee3b42d295d2f80d1285679\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxext/libxext6_1.3.4-1build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.3.4-1build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxaw7_2-1.0.14-1build2_amd64\",\n\t\t\t\"name\": \"libxaw7\",\n\t\t\t\"sha256\": \"2a9cdc82ecf566de76e05394efc604c9cced49e12c28b10e1ca101062b47bac0\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxaw/libxaw7_1.0.14-1build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2:1.0.14-1build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxpm4_1-3.5.17-1build2_amd64\",\n\t\t\t\"name\": \"libxpm4\",\n\t\t\t\"sha256\": \"ad9d9cb9be156d8b80c12735ecb4aae57e5501280a9f952749e8b71a7e5f9c97\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxpm/libxpm4_3.5.17-1build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:3.5.17-1build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"liblab-gamut1_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"liblab-gamut1\",\n\t\t\t\"sha256\": \"b9fa73d671d96b07360dd3b7a4d35814c8b892b5bf4b1e0945d3bc7937c9ee3d\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/liblab-gamut1_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgvpr2_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libgvpr2\",\n\t\t\t\"sha256\": \"1a560080462b80ab56e0fe09af2abd52974a256e25b4f384b9be5872c1073c82\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libgvpr2_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcgraph6_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libcgraph6\",\n\t\t\t\"sha256\": \"4555e20d8cd068de6343484c5bf825d03830c5048ccf56a9baec9638ca5815b2\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libcgraph6_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcdt5_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libcdt5\",\n\t\t\t\"sha256\": \"3c49c2624e6a895d729bff5be16c96beeb1347e3282bc40f3d210c715fba07ef\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libcdt5_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgvc6_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libgvc6\",\n\t\t\t\"sha256\": \"dc674afb98d9b64699f63be3a4e92d4f3b563435ebfc70cbaec0c91b8f41fb48\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libgvc6_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libwebp7_1.3.2-0.4build3_amd64\",\n\t\t\t\"name\": \"libwebp7\",\n\t\t\t\"sha256\": \"c86f6439f0bbc531f7199794654231f3b29327d6585958511b958795d51c2484\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libw/libwebp/libwebp7_1.3.2-0.4build3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.3.2-0.4build3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libsharpyuv0_1.3.2-0.4build3_amd64\",\n\t\t\t\"name\": \"libsharpyuv0\",\n\t\t\t\"sha256\": \"4e1763494e5b9d34192313aa88e38201fc67b3f13ea96ca268d26401a3002791\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libw/libwebp/libsharpyuv0_1.3.2-0.4build3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.3.2-0.4build3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpathplan4_2.42.2-9ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libpathplan4\",\n\t\t\t\"sha256\": \"8cff70c607271662df4719d2e2848731d8f23ab9108e79404066a6f93af9fd23\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/graphviz/libpathplan4_2.42.2-9ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.42.2-9ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpangoft2-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\"name\": \"libpangoft2-1.0-0\",\n\t\t\t\"sha256\": \"cc6bc9d86ef5f329edacaa4895232d8a9b8f95c5cbc77c3c460a3f64cecc213d\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpangoft2-1.0-0_1.52.1+ds-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpango-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\"name\": \"libpango-1.0-0\",\n\t\t\t\"sha256\": \"09dfa5c881ab273ec6bc1830adcefdc407fcd619316e68fb26ca3a23d0fc9f54\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpango-1.0-0_1.52.1+ds-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libthai0_0.1.29-2build1_amd64\",\n\t\t\t\"name\": \"libthai0\",\n\t\t\t\"sha256\": \"5ada7045c5f84a4b774e6449151800aa6470e8d01dc9d6124ef4a44ae6af5508\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libthai/libthai0_0.1.29-2build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.1.29-2build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libdatrie1_0.2.13-3build1_amd64\",\n\t\t\t\"name\": \"libdatrie1\",\n\t\t\t\"sha256\": \"1ae164e40e413eac4fbd38ce1c6ef9591f7a03278ad9076d71fa29258727f447\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libdatrie/libdatrie1_0.2.13-3build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.2.13-3build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libthai-data_0.1.29-2build1_amd64\",\n\t\t\t\"name\": \"libthai-data\",\n\t\t\t\"sha256\": \"6035d4a714290b97816bed7f3bf64921c6358ddb84d1dacdddccdc1cf39bffb7\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libthai/libthai-data_0.1.29-2build1_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.1.29-2build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libharfbuzz0b_8.3.0-2build2_amd64\",\n\t\t\t\"name\": \"libharfbuzz0b\",\n\t\t\t\"sha256\": \"d6f7eea2244f98aa0463a056680d4629476bf624767ede301560e24add686b5c\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/h/harfbuzz/libharfbuzz0b_8.3.0-2build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"8.3.0-2build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgraphite2-3_1.3.14-2build1_amd64\",\n\t\t\t\"name\": \"libgraphite2-3\",\n\t\t\t\"sha256\": \"e2a91c59a2b26649ed0b331bedab0c92e56cc2021cce27df1080089edaad7aba\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/graphite2/libgraphite2-3_1.3.14-2build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.3.14-2build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libglib2.0-0t64_2.80.0-6ubuntu3.8_amd64\",\n\t\t\t\"name\": \"libglib2.0-0t64\",\n\t\t\t\"sha256\": \"ca4eda0e01c76ba2e5e501e77decce53d98a641234b517eb98fc5d74980f913f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glib2.0/libglib2.0-0t64_2.80.0-6ubuntu3.8_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.80.0-6ubuntu3.8\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libselinux1_3.5-2ubuntu2.1_amd64\",\n\t\t\t\"name\": \"libselinux1\",\n\t\t\t\"sha256\": \"6abaa6c26f46ef17764c4a753e0e84de1cdadde5634fd2987621fdc617988d19\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libs/libselinux/libselinux1_3.5-2ubuntu2.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"3.5-2ubuntu2.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpcre2-8-0_10.42-4ubuntu2.1_amd64\",\n\t\t\t\"name\": \"libpcre2-8-0\",\n\t\t\t\"sha256\": \"110a797a57673d3ee497a141cf988199258058c57525799c63194d81822529a0\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pcre2/libpcre2-8-0_10.42-4ubuntu2.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"10.42-4ubuntu2.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libmount1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\"name\": \"libmount1\",\n\t\t\t\"sha256\": \"7ca31424fbfc96fbf245e6fe232fd2d2ec74169ca1add968e1987bece5bc0d1f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libmount1_2.39.3-9ubuntu6.5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libblkid1_2.39.3-9ubuntu6.5_amd64\",\n\t\t\t\"name\": \"libblkid1\",\n\t\t\t\"sha256\": \"2307a9ed92642a69de0284ac63e233e45ac5a2c3831f04399f7d212379487e82\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/u/util-linux/libblkid1_2.39.3-9ubuntu6.5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39.3-9ubuntu6.5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libffi8_3.4.6-1build1_amd64\",\n\t\t\t\"name\": \"libffi8\",\n\t\t\t\"sha256\": \"637e6a7744de08cd331a41f4efd0d24e6ea9064843dea9d1c6ca87bdb5f038a2\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libf/libffi/libffi8_3.4.6-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"3.4.6-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libfreetype6_2.13.2-p-dfsg-1ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libfreetype6\",\n\t\t\t\"sha256\": \"f6937fd8a77e83001dcfd3857d5a5cfbd4caaeb297c7fdb71ec50514843e48af\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/freetype/libfreetype6_2.13.2+dfsg-1ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.13.2+dfsg-1ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpng16-16t64_1.6.43-5ubuntu0.5_amd64\",\n\t\t\t\"name\": \"libpng16-16t64\",\n\t\t\t\"sha256\": \"074c954a7a01069c3b3db9146911666f6ac75c1277e034eba901ee274554dadc\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libp/libpng1.6/libpng16-16t64_1.6.43-5ubuntu0.5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.6.43-5ubuntu0.5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libbz2-1.0_1.0.8-5.1build0.1_amd64\",\n\t\t\t\"name\": \"libbz2-1.0\",\n\t\t\t\"sha256\": \"d557ab12b42ab370249142099fae3cbb979948934e4dfa58c2ab59bf5bbbda73\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/bzip2/libbz2-1.0_1.0.8-5.1build0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.0.8-5.1build0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libbrotli1_1.1.0-2build2_amd64\",\n\t\t\t\"name\": \"libbrotli1\",\n\t\t\t\"sha256\": \"74492419b8fda803774b8c9acef6afc5d2f9ff31782635aae212906adae7b277\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/brotli/libbrotli1_1.1.0-2build2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.1.0-2build2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libfribidi0_1.0.13-3build1_amd64\",\n\t\t\t\"name\": \"libfribidi0\",\n\t\t\t\"sha256\": \"6cd50259d39ce0dfafee2632c6268538e6a02590e77161a133e9683af346dd1d\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fribidi/libfribidi0_1.0.13-3build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.0.13-3build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"fontconfig_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\"name\": \"fontconfig\",\n\t\t\t\"sha256\": \"ddf0aace42b13a5bc38904e848b145b787ea254cddf5213d150254bd654db6e5\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/fontconfig_2.15.0-1.1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"fontconfig-config_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\"name\": \"fontconfig-config\",\n\t\t\t\"sha256\": \"9df0579cd298a1f2b7a40efd519c849745aecd193a09733cf4d1032284a62bbf\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/fontconfig-config_2.15.0-1.1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"fonts-dejavu-core_2.37-8_amd64\",\n\t\t\t\"name\": \"fonts-dejavu-core\",\n\t\t\t\"sha256\": \"40049660c194f3b8a2541fc7369efebb10e9f94bdac836a2f38fafedd10fa73a\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fonts-dejavu/fonts-dejavu-core_2.37-8_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.37-8\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"fonts-dejavu-mono_2.37-8_amd64\",\n\t\t\t\"name\": \"fonts-dejavu-mono\",\n\t\t\t\"sha256\": \"8a599d6553307db7ecb795d2f0e5a301e03234afc75c7358b0ba43466454c89a\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fonts-dejavu/fonts-dejavu-mono_2.37-8_all.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.37-8\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libfontconfig1_2.15.0-1.1ubuntu2_amd64\",\n\t\t\t\"name\": \"libfontconfig1\",\n\t\t\t\"sha256\": \"a2bc05cfef021fdb84285036f98eda5ebec3c4b7a378f5aa2bdba5c4d3d8d586\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/f/fontconfig/libfontconfig1_2.15.0-1.1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.15.0-1.1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libexpat1_2.6.1-2ubuntu0.4_amd64\",\n\t\t\t\"name\": \"libexpat1\",\n\t\t\t\"sha256\": \"126a5612e652bdc2edee19ae8fe4308db72b5b3b0a5581bf885b44a093baf3e5\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/e/expat/libexpat1_2.6.1-2ubuntu0.4_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.6.1-2ubuntu0.4\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpangocairo-1.0-0_1.52.1-p-ds-1build1_amd64\",\n\t\t\t\"name\": \"libpangocairo-1.0-0\",\n\t\t\t\"sha256\": \"98cf5fc9076c2911fe20dfc1e41cd8f686a2bb5d539b1105fab18105b0db1376\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pango1.0/libpangocairo-1.0-0_1.52.1+ds-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.52.1+ds-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcairo2_1.18.0-3build1_amd64\",\n\t\t\t\"name\": \"libcairo2\",\n\t\t\t\"sha256\": \"96950b306889ff6e4248bb937b0a3b56e72dacf643fe732214ce375f0f6bbb36\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/c/cairo/libcairo2_1.18.0-3build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.18.0-3build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxrender1_1-0.9.10-1.1build1_amd64\",\n\t\t\t\"name\": \"libxrender1\",\n\t\t\t\"sha256\": \"d70bd831aebe8d4834b5dd2ed98df26dd6bd27f1042c47543bd7f66df1ae22ea\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxrender/libxrender1_0.9.10-1.1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:0.9.10-1.1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxcb-shm0_1.15-1ubuntu2_amd64\",\n\t\t\t\"name\": \"libxcb-shm0\",\n\t\t\t\"sha256\": \"229d1280d459f1ba44c22939d3f9b61d9d20932d9a646b3fe4ce50be4cdf2325\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb-shm0_1.15-1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libxcb-render0_1.15-1ubuntu2_amd64\",\n\t\t\t\"name\": \"libxcb-render0\",\n\t\t\t\"sha256\": \"7d83a0668b1a693b5ea2e496206e8371fb6beda4c54a2b4b3902005915c272c5\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcb/libxcb-render0_1.15-1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.15-1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libpixman-1-0_0.42.2-1build1_amd64\",\n\t\t\t\"name\": \"libpixman-1-0\",\n\t\t\t\"sha256\": \"d9c2931c4c424615eeab9dd5ae08bfc608b84e803c1d3ccddf319270db213421\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/p/pixman/libpixman-1-0_0.42.2-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.42.2-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libltdl7_2.4.7-7build1_amd64\",\n\t\t\t\"name\": \"libltdl7\",\n\t\t\t\"sha256\": \"02d0d2d7e1bf73f838a92f8df7a9b07b698c837e82bd89aee6a581cf793cd966\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libt/libtool/libltdl7_2.4.7-7build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.4.7-7build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgts-0.7-5t64_0.7.6-p-darcs121130-5.2build1_amd64\",\n\t\t\t\"name\": \"libgts-0.7-5t64\",\n\t\t\t\"sha256\": \"a6741ed94f3e786eaed0a9fcb69f641327cfe288af4f043e7036b5257e87fc48\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/g/gts/libgts-0.7-5t64_0.7.6+darcs121130-5.2build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"0.7.6+darcs121130-5.2build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgd3_2.3.3-9ubuntu5_amd64\",\n\t\t\t\"name\": \"libgd3\",\n\t\t\t\"sha256\": \"dbef5ad99eec399fd6afeb6d0cc92d81a8b3295a7ac80ac71311ea09c49704ae\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libg/libgd2/libgd3_2.3.3-9ubuntu5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.3.3-9ubuntu5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libtiff6_4.5.1-p-git230720-4ubuntu2.5_amd64\",\n\t\t\t\"name\": \"libtiff6\",\n\t\t\t\"sha256\": \"564cdf59dda5e1a826c51b5868ee2785fffa26ee5a7bad95bc5e8c8224c931b8\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/t/tiff/libtiff6_4.5.1+git230720-4ubuntu2.5_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"4.5.1+git230720-4ubuntu2.5\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"liblzma5_5.6.1-p-really5.4.5-1ubuntu0.2_amd64\",\n\t\t\t\"name\": \"liblzma5\",\n\t\t\t\"sha256\": \"4c31cc76391ca47dbb4585edc740728f43fe7b6b090f5b3947fc8072db698aca\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/x/xz-utils/liblzma5_5.6.1+really5.4.5-1ubuntu0.2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"5.6.1+really5.4.5-1ubuntu0.2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"liblerc4_4.0.0-p-ds-4ubuntu2_amd64\",\n\t\t\t\"name\": \"liblerc4\",\n\t\t\t\"sha256\": \"f1b9dbfa28c56564f6b544f3757f5f3f4d549ce9962f39e897812c23b0a5d0e7\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/l/lerc/liblerc4_4.0.0+ds-4ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"4.0.0+ds-4ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libjpeg8_8c-2ubuntu11_amd64\",\n\t\t\t\"name\": \"libjpeg8\",\n\t\t\t\"sha256\": \"4d6ed682972bddf62af158a06d68a0dda497e421423b7ca92fb450b3d9ceaac9\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libj/libjpeg8-empty/libjpeg8_8c-2ubuntu11_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"8c-2ubuntu11\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libjpeg-turbo8_2.1.5-2ubuntu2_amd64\",\n\t\t\t\"name\": \"libjpeg-turbo8\",\n\t\t\t\"sha256\": \"f68b5b23bc8a1688fb787d2aed7e2cdf895a73022f6a5025e183162dac4500b2\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libj/libjpeg-turbo/libjpeg-turbo8_2.1.5-2ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.1.5-2ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libjbig0_2.1-6.1ubuntu2_amd64\",\n\t\t\t\"name\": \"libjbig0\",\n\t\t\t\"sha256\": \"074a760a86213a1286ad60f56394c90885cf45af070626a88c480d90b78c175a\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/j/jbigkit/libjbig0_2.1-6.1ubuntu2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.1-6.1ubuntu2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libdeflate0_1.19-1build1.1_amd64\",\n\t\t\t\"name\": \"libdeflate0\",\n\t\t\t\"sha256\": \"8e7dfa9e63a9b5058071b84da48bb2e30dea07de169e80fbc759fe0e68639269\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libdeflate/libdeflate0_1.19-1build1.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.19-1build1.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libheif1_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\"name\": \"libheif1\",\n\t\t\t\"sha256\": \"c41176242ae4a6a66fa50fab00dc6d951711f0cf8aab32cf13530c4a404a7026\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif1_1.17.6-1ubuntu4.2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libheif-plugin-libde265_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\"name\": \"libheif-plugin-libde265\",\n\t\t\t\"sha256\": \"f5284ae47a70538c503b15f458783df569ac7b8d5d16aaeac4e04c2d3b8e7341\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif-plugin-libde265_1.17.6-1ubuntu4.2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libde265-0_1.0.15-1build3_amd64\",\n\t\t\t\"name\": \"libde265-0\",\n\t\t\t\"sha256\": \"3b8cb1fb70933261d076d1b2882fb303aa8da1a951ad7614234f890468c90310\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libd/libde265/libde265-0_1.0.15-1build3_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.0.15-1build3\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libheif-plugin-aomdec_1.17.6-1ubuntu4.2_amd64\",\n\t\t\t\"name\": \"libheif-plugin-aomdec\",\n\t\t\t\"sha256\": \"65ce5cb8f2ee27127b7df6b358bde6e58ebcf00e1d9f5c92c32c842cfa260ef6\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libh/libheif/libheif-plugin-aomdec_1.17.6-1ubuntu4.2_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.17.6-1ubuntu4.2\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libaom3_3.8.2-2ubuntu0.1_amd64\",\n\t\t\t\"name\": \"libaom3\",\n\t\t\t\"sha256\": \"1623e49454a2981069ed4801c853630a63a68f77c73056dea11e3289a8467eb9\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/a/aom/libaom3_3.8.2-2ubuntu0.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"3.8.2-2ubuntu0.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libann0_1.1.2-p-doc-9build1_amd64\",\n\t\t\t\"name\": \"libann0\",\n\t\t\t\"sha256\": \"88347025b6292517dc591fd6a51c28b6a91a46c999505e3e54677c99038074e1\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/universe/a/ann/libann0_1.1.2+doc-9build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.1.2+doc-9build1\"\n\t\t}\n\t],\n\t\"version\": 1\n}", + "package_template": "@@rules_distroless+//apt/private:package.BUILD.tmpl" + } + }, + "tooling_sysroot_base-files_13ubuntu10.4_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/base-files/base-files_13ubuntu10.4_amd64.deb" + ], + "sha256": "94daf9ede91f6263d676611623d4c9edab695c728a584ab2fb1d11cabb8479e8" + } + }, + "tooling_sysroot_libcrypt1_1-4.4.36-4build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt1_4.4.36-4build1_amd64.deb" + ], + "sha256": "9474785cd6f398512bf8c305c3901dbb111569dccb6f5832002373c0a8ac5832" + } + }, + "tooling_sysroot_libc6_2.39-0ubuntu8.7_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6_2.39-0ubuntu8.7_amd64.deb" + ], + "sha256": "955644e8bc2930a9bf8eea5e4c2237c8a118c1e2ac2845b993b6f7f35eefd293" + } + }, + "tooling_sysroot_libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgcc-s1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "aa7fadbe33b78bcf99885318040601c550c208929565b179891d9a3cc2aa68cd" + } + }, + "tooling_sysroot_gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/gcc-14-base_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "b95c172411a7fdae70307cf33a9f5320ba5e056b556454543dd5b679d5ce1c4f" + } + }, + "tooling_sysroot_mawk_1.3.4.20240123-1build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/m/mawk/mawk_1.3.4.20240123-1build1_amd64.deb" + ], + "sha256": "dc7f7f4dad4b48f6012ea65de3198d8376604afef39f06d65ec6167740e203c9" + } + }, + "tooling_sysroot_libatomic1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libatomic1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "fe49cbbc7be753528380c724a8eef5f1e31dffa9221f692c5069048d81c7449d" + } + }, + "tooling_sysroot_libc6-dev_2.39-0ubuntu8.7_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6-dev_2.39-0ubuntu8.7_amd64.deb" + ], + "sha256": "bbf5a155039042634961a61276650631ee47b9e721f91f8dbb731b0bbe046df3" + } + }, + "tooling_sysroot_rpcsvc-proto_1.4.2-0ubuntu7_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/r/rpcsvc-proto/rpcsvc-proto_1.4.2-0ubuntu7_amd64.deb" + ], + "sha256": "7eb710fe148d224c159ddec1ceb0ba53ead52a80a6793dcdae1474acf20d8f71" + } + }, + "tooling_sysroot_libcrypt-dev_1-4.4.36-4build1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt-dev_4.4.36-4build1_amd64.deb" + ], + "sha256": "2edff420ef80b4a3f3751e65c33423ef30e563122a58b759e4854ea8d84ba1b1" + } + }, + "tooling_sysroot_linux-libc-dev_6.8.0-107.107_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/l/linux/linux-libc-dev_6.8.0-107.107_amd64.deb" + ], + "sha256": "fcc88782dc3857d661c7ae8b0435174cb41ce0bcda0d2c4c0fbfdadd9f03ff43" + } + }, + "tooling_sysroot_libc-dev-bin_2.39-0ubuntu8.7_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc-dev-bin_2.39-0ubuntu8.7_amd64.deb" + ], + "sha256": "83291a1d9b26262ac8f44a3bb188ce2cb796a0543134aae00e19db066c84dfdd" + } + }, + "tooling_sysroot_libstdc-p--p--13-dev_13.3.0-6ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/libstdc++-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "ee5633e863e19c3381ed97842ce35ed32ede96a3d1ae4e94c051d3036fe21347" + } + }, + "tooling_sysroot_libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libstdc++6_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "a51f8de7829211db961a31f02158058ad1a95f92ac6d0a5dff6350e2821c54c0" + } + }, + "tooling_sysroot_libgcc-13-dev_13.3.0-6ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/libgcc-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "cd689db2691edaa10f37329307292796bb599e722e0505c79e14caaa1fe9a93a" + } + }, + "tooling_sysroot_libquadmath0_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libquadmath0_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "dc8f0ca542e09d662f29370c8393c016440dd4bc5c996c5fcc19f632b63ce3b0" + } + }, + "tooling_sysroot_libhwasan0_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libhwasan0_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "2195318cfe68fe16b601913ef7b33c9a900372f57861643fdc9ae6fef84534cd" + } + }, + "tooling_sysroot_libubsan1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libubsan1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "a16dea3abe2dcac99bcfae27e7e5672fde64573c3c170dcb0cd55631238f9814" + } + }, + "tooling_sysroot_libtsan2_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libtsan2_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "8cbcc9b3ae5ef23b449383d47a9035b27596e307d7dce7df9b83d47a7acd1d91" + } + }, + "tooling_sysroot_liblsan0_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/liblsan0_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "dc0c2a1a053e833ba4d71e1ec2ba4244fe301761ad4a91d6725f927a52d86a14" + } + }, + "tooling_sysroot_libasan8_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libasan8_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "8321aac6230fa1da320e76eb6288b7436164624aec449ed3933ea6c4cc86daac" + } + }, + "tooling_sysroot_libitm1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libitm1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "1fca498129dd3510294809d77ee754f72a9de281111200e9b7b9a5adf37faa9f" + } + }, + "tooling_sysroot_libgomp1_14.2.0-4ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgomp1_14.2.0-4ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "e8a95ec58125b4933597f30ff56c2ae10edf90f287262e366d4b6edea3019144" + } + }, + "tooling_sysroot_gcc-13-base_13.3.0-6ubuntu2_24.04.1_amd64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_distroless//apt/private:deb_postfix.bzl\", \"deb_postfix\")\n\ndeb_postfix(\n name = \"data\",\n srcs = glob([\"data.tar*\"]),\n outs = [\"layer.tar.gz\"],\n mergedusr = False,\n\n visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n name = \"control\",\n srcs = glob([\"control.tar.*\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "urls": [ + "https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/gcc-13-base_13.3.0-6ubuntu2~24.04.1_amd64.deb" + ], + "sha256": "e859aca26585bb91113a451f1e66bc0e5283cb08797d679aacc1d936ae6dff8e" + } + }, + "tooling_sysroot_resolve": { + "repoRuleId": "@@rules_distroless+//apt/private:deb_resolve.bzl%deb_resolve", + "attributes": { + "manifest": "@@score_tooling+//third_party/tooling_sysroot:manifest.yaml", + "resolve_transitive": true + } + }, + "tooling_sysroot": { + "repoRuleId": "@@rules_distroless+//apt/private:deb_translate_lock.bzl%deb_translate_lock", + "attributes": { + "lock_content": "{\n\t\"packages\": [\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"mawk_1.3.4.20240123-1build1_amd64\",\n\t\t\t\t\t\"name\": \"mawk\",\n\t\t\t\t\t\"version\": \"1.3.4.20240123-1build1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"base-files_13ubuntu10.4_amd64\",\n\t\t\t\"name\": \"base-files\",\n\t\t\t\"sha256\": \"94daf9ede91f6263d676611623d4c9edab695c728a584ab2fb1d11cabb8479e8\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/b/base-files/base-files_13ubuntu10.4_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"13ubuntu10.4\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\"sha256\": \"9474785cd6f398512bf8c305c3901dbb111569dccb6f5832002373c0a8ac5832\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt1_4.4.36-4build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\"name\": \"libc6\",\n\t\t\t\"sha256\": \"955644e8bc2930a9bf8eea5e4c2237c8a118c1e2ac2845b993b6f7f35eefd293\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6_2.39-0ubuntu8.7_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\"sha256\": \"aa7fadbe33b78bcf99885318040601c550c208929565b179891d9a3cc2aa68cd\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgcc-s1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\"sha256\": \"b95c172411a7fdae70307cf33a9f5320ba5e056b556454543dd5b679d5ce1c4f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/gcc-14-base_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"mawk_1.3.4.20240123-1build1_amd64\",\n\t\t\t\"name\": \"mawk\",\n\t\t\t\"sha256\": \"dc7f7f4dad4b48f6012ea65de3198d8376604afef39f06d65ec6167740e203c9\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/m/mawk/mawk_1.3.4.20240123-1build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.3.4.20240123-1build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libatomic1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libatomic1\",\n\t\t\t\"sha256\": \"fe49cbbc7be753528380c724a8eef5f1e31dffa9221f692c5069048d81c7449d\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libatomic1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"rpcsvc-proto_1.4.2-0ubuntu7_amd64\",\n\t\t\t\t\t\"name\": \"rpcsvc-proto\",\n\t\t\t\t\t\"version\": \"1.4.2-0ubuntu7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt-dev_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt-dev\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"linux-libc-dev_6.8.0-107.107_amd64\",\n\t\t\t\t\t\"name\": \"linux-libc-dev\",\n\t\t\t\t\t\"version\": \"6.8.0-107.107\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc-dev-bin_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc-dev-bin\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libc6-dev_2.39-0ubuntu8.7_amd64\",\n\t\t\t\"name\": \"libc6-dev\",\n\t\t\t\"sha256\": \"bbf5a155039042634961a61276650631ee47b9e721f91f8dbb731b0bbe046df3\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc6-dev_2.39-0ubuntu8.7_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"rpcsvc-proto_1.4.2-0ubuntu7_amd64\",\n\t\t\t\"name\": \"rpcsvc-proto\",\n\t\t\t\"sha256\": \"7eb710fe148d224c159ddec1ceb0ba53ead52a80a6793dcdae1474acf20d8f71\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/r/rpcsvc-proto/rpcsvc-proto_1.4.2-0ubuntu7_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1.4.2-0ubuntu7\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libcrypt-dev_1-4.4.36-4build1_amd64\",\n\t\t\t\"name\": \"libcrypt-dev\",\n\t\t\t\"sha256\": \"2edff420ef80b4a3f3751e65c33423ef30e563122a58b759e4854ea8d84ba1b1\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/libx/libxcrypt/libcrypt-dev_4.4.36-4build1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"linux-libc-dev_6.8.0-107.107_amd64\",\n\t\t\t\"name\": \"linux-libc-dev\",\n\t\t\t\"sha256\": \"fcc88782dc3857d661c7ae8b0435174cb41ce0bcda0d2c4c0fbfdadd9f03ff43\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/l/linux/linux-libc-dev_6.8.0-107.107_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"6.8.0-107.107\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libc-dev-bin_2.39-0ubuntu8.7_amd64\",\n\t\t\t\"name\": \"libc-dev-bin\",\n\t\t\t\"sha256\": \"83291a1d9b26262ac8f44a3bb188ce2cb796a0543134aae00e19db066c84dfdd\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/glibc/libc-dev-bin_2.39-0ubuntu8.7_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6-dev_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6-dev\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"rpcsvc-proto_1.4.2-0ubuntu7_amd64\",\n\t\t\t\t\t\"name\": \"rpcsvc-proto\",\n\t\t\t\t\t\"version\": \"1.4.2-0ubuntu7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt-dev_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt-dev\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libcrypt1_1-4.4.36-4build1_amd64\",\n\t\t\t\t\t\"name\": \"libcrypt1\",\n\t\t\t\t\t\"version\": \"1:4.4.36-4build1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"linux-libc-dev_6.8.0-107.107_amd64\",\n\t\t\t\t\t\"name\": \"linux-libc-dev\",\n\t\t\t\t\t\"version\": \"6.8.0-107.107\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc-dev-bin_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc-dev-bin\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libstdc++6\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-13-dev_13.3.0-6ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-13-dev\",\n\t\t\t\t\t\"version\": \"13.3.0-6ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libquadmath0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libquadmath0\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libhwasan0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libhwasan0\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libubsan1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libubsan1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libtsan2_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libtsan2\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"liblsan0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"liblsan0\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libasan8_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libasan8\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libatomic1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libatomic1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libitm1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libitm1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgomp1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgomp1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-13-base_13.3.0-6ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-13-base\",\n\t\t\t\t\t\"version\": \"13.3.0-6ubuntu2~24.04.1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libstdc-p--p--13-dev_13.3.0-6ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libstdc++-13-dev\",\n\t\t\t\"sha256\": \"ee5633e863e19c3381ed97842ce35ed32ede96a3d1ae4e94c051d3036fe21347\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/libstdc++-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"13.3.0-6ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libgcc-s1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"libgcc-s1\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"libc6_2.39-0ubuntu8.7_amd64\",\n\t\t\t\t\t\"name\": \"libc6\",\n\t\t\t\t\t\"version\": \"2.39-0ubuntu8.7\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"key\": \"gcc-14-base_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\t\t\"name\": \"gcc-14-base\",\n\t\t\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"key\": \"libstdc-p--p-6_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libstdc++6\",\n\t\t\t\"sha256\": \"a51f8de7829211db961a31f02158058ad1a95f92ac6d0a5dff6350e2821c54c0\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libstdc++6_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgcc-13-dev_13.3.0-6ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libgcc-13-dev\",\n\t\t\t\"sha256\": \"cd689db2691edaa10f37329307292796bb599e722e0505c79e14caaa1fe9a93a\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/libgcc-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"13.3.0-6ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libquadmath0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libquadmath0\",\n\t\t\t\"sha256\": \"dc8f0ca542e09d662f29370c8393c016440dd4bc5c996c5fcc19f632b63ce3b0\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libquadmath0_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libhwasan0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libhwasan0\",\n\t\t\t\"sha256\": \"2195318cfe68fe16b601913ef7b33c9a900372f57861643fdc9ae6fef84534cd\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libhwasan0_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libubsan1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libubsan1\",\n\t\t\t\"sha256\": \"a16dea3abe2dcac99bcfae27e7e5672fde64573c3c170dcb0cd55631238f9814\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libubsan1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libtsan2_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libtsan2\",\n\t\t\t\"sha256\": \"8cbcc9b3ae5ef23b449383d47a9035b27596e307d7dce7df9b83d47a7acd1d91\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libtsan2_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"liblsan0_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"liblsan0\",\n\t\t\t\"sha256\": \"dc0c2a1a053e833ba4d71e1ec2ba4244fe301761ad4a91d6725f927a52d86a14\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/liblsan0_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libasan8_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libasan8\",\n\t\t\t\"sha256\": \"8321aac6230fa1da320e76eb6288b7436164624aec449ed3933ea6c4cc86daac\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libasan8_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libitm1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libitm1\",\n\t\t\t\"sha256\": \"1fca498129dd3510294809d77ee754f72a9de281111200e9b7b9a5adf37faa9f\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libitm1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"libgomp1_14.2.0-4ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"libgomp1\",\n\t\t\t\"sha256\": \"e8a95ec58125b4933597f30ff56c2ae10edf90f287262e366d4b6edea3019144\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-14/libgomp1_14.2.0-4ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"14.2.0-4ubuntu2~24.04.1\"\n\t\t},\n\t\t{\n\t\t\t\"arch\": \"amd64\",\n\t\t\t\"dependencies\": [],\n\t\t\t\"key\": \"gcc-13-base_13.3.0-6ubuntu2_24.04.1_amd64\",\n\t\t\t\"name\": \"gcc-13-base\",\n\t\t\t\"sha256\": \"e859aca26585bb91113a451f1e66bc0e5283cb08797d679aacc1d936ae6dff8e\",\n\t\t\t\"urls\": [\n\t\t\t\t\"https://snapshot.ubuntu.com/ubuntu/20260401T104001Z/pool/main/g/gcc-13/gcc-13-base_13.3.0-6ubuntu2~24.04.1_amd64.deb\"\n\t\t\t],\n\t\t\t\"version\": \"13.3.0-6ubuntu2~24.04.1\"\n\t\t}\n\t],\n\t\"version\": 1\n}", + "package_template": "@@rules_distroless+//apt/private:package.BUILD.tmpl" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_distroless+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_distroless+", + "bazel_lib", + "bazel_lib+" + ], + [ + "rules_distroless+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_distroless+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_distroless+", + "yq_linux_amd64", + "yq.bzl++yq+yq_linux_amd64" + ] + ] + } + }, + "@@rules_foreign_cc+//foreign_cc:extensions.bzl%tools": { + "general": { + "bzlTransitiveDigest": "Zyhrp9ZD1OkHXRpL1OG37IUnUmkiGpNNHJeqFTQ8aAM=", + "usagesDigest": "9LXdVp01HkdYQT8gYPjYLO6VLVJHo9uFfxWaU1ymiRE=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_foreign_cc_framework_toolchain_linux": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:linux_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:linux" + ] + } + }, + "rules_foreign_cc_framework_toolchain_freebsd": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:freebsd_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:freebsd" + ] + } + }, + "rules_foreign_cc_framework_toolchain_windows": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:windows_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:windows" + ] + } + }, + "rules_foreign_cc_framework_toolchain_macos": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository", + "attributes": { + "commands_src": "@rules_foreign_cc//foreign_cc/private/framework/toolchains:macos_commands.bzl", + "exec_compatible_with": [ + "@platforms//os:macos" + ] + } + }, + "rules_foreign_cc_framework_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//foreign_cc/private/framework:toolchain.bzl%framework_toolchain_repository_hub", + "attributes": {} + }, + "cmake_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "f316b40053466f9a416adf981efda41b160ca859e97f6a484b447ea299ff26aa", + "strip_prefix": "cmake-3.23.2", + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2.tar.gz" + ] + } + }, + "gnumake_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "581f4d4e872da74b3941c874215898a7d35802f03732bdccee1d4a7979105d18", + "strip_prefix": "make-4.4", + "urls": [ + "https://mirror.bazel.build/ftpmirror.gnu.org/gnu/make/make-4.4.tar.gz", + "http://ftpmirror.gnu.org/gnu/make/make-4.4.tar.gz" + ] + } + }, + "ninja_build_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "31747ae633213f1eda3842686f83c2aa1412e0f5691d1c14dbbcc67fe7400cea", + "strip_prefix": "ninja-1.11.1", + "urls": [ + "https://github.com/ninja-build/ninja/archive/v1.11.1.tar.gz" + ] + } + }, + "meson_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "exports_files([\"meson.py\"])\n\nfilegroup(\n name = \"runtime\",\n srcs = glob([\"mesonbuild/**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "strip_prefix": "meson-1.1.1", + "url": "https://github.com/mesonbuild/meson/releases/download/1.1.1/meson-1.1.1.tar.gz" + } + }, + "glib_dev": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nload(\"@rules_cc//cc:defs.bzl\", \"cc_library\")\n\ncc_import(\n name = \"glib_dev\",\n hdrs = glob([\"include/**\"]),\n shared_library = \"@glib_runtime//:bin/libglib-2.0-0.dll\",\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "bdf18506df304d38be98a4b3f18055b8b8cca81beabecad0eece6ce95319c369", + "urls": [ + "https://download.gnome.org/binaries/win64/glib/2.26/glib-dev_2.26.1-1_win64.zip" + ] + } + }, + "glib_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\ncc_import(\n name = \"msvc_hdr\",\n hdrs = [\"msvc_recommended_pragmas.h\"],\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "bc96f63112823b7d6c9f06572d2ad626ddac7eb452c04d762592197f6e07898e", + "strip_prefix": "glib-2.26.1", + "urls": [ + "https://download.gnome.org/sources/glib/2.26/glib-2.26.1.tar.gz" + ] + } + }, + "glib_runtime": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\nexports_files(\n [\n \"bin/libgio-2.0-0.dll\",\n \"bin/libglib-2.0-0.dll\",\n \"bin/libgmodule-2.0-0.dll\",\n \"bin/libgobject-2.0-0.dll\",\n \"bin/libgthread-2.0-0.dll\",\n ],\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "88d857087e86f16a9be651ee7021880b3f7ba050d34a1ed9f06113b8799cb973", + "urls": [ + "https://download.gnome.org/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip" + ] + } + }, + "gettext_runtime": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\ncc_import(\n name = \"gettext_runtime\",\n shared_library = \"bin/libintl-8.dll\",\n visibility = [\"//visibility:public\"],\n)\n ", + "sha256": "1f4269c0e021076d60a54e98da6f978a3195013f6de21674ba0edbc339c5b079", + "urls": [ + "https://download.gnome.org/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip" + ] + } + }, + "pkgconfig_src": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "filegroup(\n name = \"all_srcs\",\n srcs = glob([\"**\"]),\n visibility = [\"//visibility:public\"],\n)\n", + "sha256": "6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591", + "strip_prefix": "pkg-config-0.29.2", + "patches": [ + "@@rules_foreign_cc+//toolchains:pkgconfig-detectenv.patch", + "@@rules_foreign_cc+//toolchains:pkgconfig-makefile-vc.patch" + ], + "urls": [ + "https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz" + ] + } + }, + "bazel_skylib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz" + ], + "sha256": "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728" + } + }, + "rules_python": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "84aec9e21cc56fbc7f1335035a71c850d1b9b5cc6ff497306f84cced9a769841", + "strip_prefix": "rules_python-0.23.1", + "url": "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.23.1.tar.gz" + } + }, + "cmake-3.23.2-linux-aarch64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-aarch64.tar.gz" + ], + "sha256": "f2654bf780b53f170bbbec44d8ac67d401d24788e590faa53036a89476efa91e", + "strip_prefix": "cmake-3.23.2-linux-aarch64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-linux-x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-linux-x86_64.tar.gz" + ], + "sha256": "aaced6f745b86ce853661a595bdac6c5314a60f8181b6912a0a4920acfa32708", + "strip_prefix": "cmake-3.23.2-linux-x86_64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-macos-universal": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-macos-universal.tar.gz" + ], + "sha256": "853a0f9af148c5ef47282ffffee06c4c9f257be2635936755f39ca13c3286c88", + "strip_prefix": "cmake-3.23.2-macos-universal/CMake.app/Contents", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-windows-i386": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-windows-i386.zip" + ], + "sha256": "6a4fcd6a2315b93cb23c93507efccacc30c449c2bf98f14d6032bb226c582e07", + "strip_prefix": "cmake-3.23.2-windows-i386", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake.exe\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake-3.23.2-windows-x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Kitware/CMake/releases/download/v3.23.2/cmake-3.23.2-windows-x86_64.zip" + ], + "sha256": "2329387f3166b84c25091c86389fb891193967740c9bcf01e7f6d3306f7ffda0", + "strip_prefix": "cmake-3.23.2-windows-x86_64", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"cmake_data\",\n srcs = glob(\n [\n \"**\",\n ],\n exclude = [\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n \"BUILD\",\n \"BUILD.bazel\",\n ],\n ),\n)\n\nnative_tool_toolchain(\n name = \"cmake_tool\",\n path = \"bin/cmake.exe\",\n target = \":cmake_data\",\n)\n" + } + }, + "cmake_3.23.2_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//toolchains:prebuilt_toolchains_repository.bzl%prebuilt_toolchains_repository", + "attributes": { + "repos": { + "cmake-3.23.2-linux-aarch64": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ], + "cmake-3.23.2-linux-x86_64": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "cmake-3.23.2-macos-universal": [ + "@platforms//os:macos" + ], + "cmake-3.23.2-windows-i386": [ + "@platforms//cpu:x86_32", + "@platforms//os:windows" + ], + "cmake-3.23.2-windows-x86_64": [ + "@platforms//cpu:x86_64", + "@platforms//os:windows" + ] + }, + "tool": "cmake" + } + }, + "ninja_1.11.1_linux": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-linux.zip" + ], + "sha256": "b901ba96e486dce377f9a070ed4ef3f79deb45f4ffe2938f8e7ddc69cfb3df77", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_mac": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-mac.zip" + ], + "sha256": "482ecb23c59ae3d4f158029112de172dd96bb0e97549c4b1ca32d8fad11f873e", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_win": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/ninja-build/ninja/releases/download/v1.11.1/ninja-win.zip" + ], + "sha256": "524b344a1a9a55005eaf868d991e090ab8ce07fa109f1820d40e74642e289abc", + "strip_prefix": "", + "build_file_content": "load(\"@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl\", \"native_tool_toolchain\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nfilegroup(\n name = \"ninja_bin\",\n srcs = [\"ninja.exe\"],\n)\n\nnative_tool_toolchain(\n name = \"ninja_tool\",\n env = {\"NINJA\": \"$(execpath :ninja_bin)\"},\n path = \"$(execpath :ninja_bin)\",\n target = \":ninja_bin\",\n)\n" + } + }, + "ninja_1.11.1_toolchains": { + "repoRuleId": "@@rules_foreign_cc+//toolchains:prebuilt_toolchains_repository.bzl%prebuilt_toolchains_repository", + "attributes": { + "repos": { + "ninja_1.11.1_linux": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "ninja_1.11.1_mac": [ + "@platforms//cpu:x86_64", + "@platforms//os:macos" + ], + "ninja_1.11.1_win": [ + "@platforms//cpu:x86_64", + "@platforms//os:windows" + ] + }, + "tool": "ninja" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_foreign_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_foreign_cc+", + "rules_foreign_cc", + "rules_foreign_cc+" + ] + ] + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "HJP3wKFbPhB1mSYjJS6kbXEiP+OQxvsBdqpvyJN6I3s=", + "usagesDigest": "qTwqmKKUfWcPdvM0waG+CPWrxsbeAWVeUxavm7tEk9E=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v2.1.0/kotlin-compiler-2.1.0.zip" + ], + "sha256": "b6698d5728ad8f9edcdd01617d638073191d8a03139cc538a391b4e3759ad297" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "2.1.0" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/2.1.0-1.0.28/artifacts.zip" + ], + "sha256": "fc27b08cadc061a4a989af01cbeccb613feef1995f4aad68f2be0f886a3ee251", + "strip_version": "2.1.0-1.0.28" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "a9f923be58fbd32670a17f0b729b1df804af882fa57402165741cb26e5440ca1", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.1/ktlint" + ], + "executable": true + } + }, + "kotlinx_serialization_core_jvm": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "29c821a8d4e25cbfe4f2ce96cdd4526f61f8f4e69a135f9612a34a81d93b65f1", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core-jvm/1.6.3/kotlinx-serialization-core-jvm-1.6.3.jar" + ] + } + }, + "kotlinx_serialization_json": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "8c0016890a79ab5980dd520a5ab1a6738023c29aa3b6437c482e0e5fdc06dab1", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json/1.6.3/kotlinx-serialization-json-1.6.3.jar" + ] + } + }, + "kotlinx_serialization_json_jvm": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "d3234179bcff1886d53d67c11eca47f7f3cf7b63c349d16965f6db51b7f3dd9a", + "urls": [ + "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json-jvm/1.6.3/kotlinx-serialization-json-jvm-1.6.3.jar" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_nodejs+//nodejs:extensions.bzl%node": { + "general": { + "bzlTransitiveDigest": "4pUxCNc22K4I+6+4Nxu52Hur12tFRfa1JMsN5mdDv60=", + "usagesDigest": "GS0hrS+1xGO6wWmKTqytkZ6FWwnLFKCdsYVhZKvKNFA=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "nodejs_linux_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "linux_amd64" + } + }, + "nodejs_linux_arm64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "linux_arm64" + } + }, + "nodejs_linux_s390x": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "linux_s390x" + } + }, + "nodejs_linux_ppc64le": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "linux_ppc64le" + } + }, + "nodejs_darwin_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "darwin_amd64" + } + }, + "nodejs_darwin_arm64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "darwin_arm64" + } + }, + "nodejs_windows_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "windows_amd64" + } + }, + "nodejs_windows_arm64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "22.22.0", + "include_headers": false, + "platform": "windows_arm64" + } + }, + "nodejs": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_repo_host_os_alias.bzl%nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_host": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_repo_host_os_alias.bzl%nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_toolchains": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_toolchains_repo.bzl%nodejs_toolchains_repo", + "attributes": { + "user_node_repository_name": "nodejs" + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "TRGIl0CDmorwyNiblOYyhWuyKzi/kWFHT2uIofq7o9Y=", + "usagesDigest": "lDbpRfhoWmZCHSaNxwZv/8fF2y0wu2th0G0f/uqX7VM=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "pypi__build", + "rules_python++config+pypi__build" + ], + [ + "rules_python+", + "pypi__click", + "rules_python++config+pypi__click" + ], + [ + "rules_python+", + "pypi__colorama", + "rules_python++config+pypi__colorama" + ], + [ + "rules_python+", + "pypi__importlib_metadata", + "rules_python++config+pypi__importlib_metadata" + ], + [ + "rules_python+", + "pypi__installer", + "rules_python++config+pypi__installer" + ], + [ + "rules_python+", + "pypi__more_itertools", + "rules_python++config+pypi__more_itertools" + ], + [ + "rules_python+", + "pypi__packaging", + "rules_python++config+pypi__packaging" + ], + [ + "rules_python+", + "pypi__pep517", + "rules_python++config+pypi__pep517" + ], + [ + "rules_python+", + "pypi__pip", + "rules_python++config+pypi__pip" + ], + [ + "rules_python+", + "pypi__pip_tools", + "rules_python++config+pypi__pip_tools" + ], + [ + "rules_python+", + "pypi__pyproject_hooks", + "rules_python++config+pypi__pyproject_hooks" + ], + [ + "rules_python+", + "pypi__setuptools", + "rules_python++config+pypi__setuptools" + ], + [ + "rules_python+", + "pypi__tomli", + "rules_python++config+pypi__tomli" + ], + [ + "rules_python+", + "pypi__wheel", + "rules_python++config+pypi__wheel" + ], + [ + "rules_python+", + "pypi__zipp", + "rules_python++config+pypi__zipp" + ] + ] + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "r/qVanIsK8SWxQWkJBvpWw5XePYfj9hIHIKL9FTzAdk=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "platforms", + "platforms" + ] + ] + } + }, + "@@rules_rust+//crate_universe:extensions.bzl%crate": { + "general": { + "bzlTransitiveDigest": "8QfSf1kvCWSgBnQ9KgYFpBqDkBtjBBPru5O7fUT2Wyw=", + "usagesDigest": "wKDir5lt64+Fed9OkYwXdJMDafXvpjxTmVvguHrnF8g=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": { + "CARGO_BAZEL_DEBUG": null, + "CARGO_BAZEL_GENERATOR_SHA256": null, + "CARGO_BAZEL_GENERATOR_URL": null, + "CARGO_BAZEL_ISOLATED": null, + "CARGO_BAZEL_REPIN": null, + "CARGO_BAZEL_REPIN_ONLY": null, + "CARGO_BAZEL_TIMEOUT": null, + "REPIN": null + }, + "generatedRepoSpecs": { + "crates": { + "repoRuleId": "@@rules_rust+//crate_universe:extensions.bzl%_generate_repo", + "attributes": { + "contents": { + "BUILD.bazel": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\npackage(default_visibility = [\"//visibility:public\"])\n\nexports_files(\n [\n \"cargo-bazel.json\",\n \"crates.bzl\",\n \"defs.bzl\",\n ] + glob(\n allow_empty = True,\n include = [\"*.bazel\"],\n ),\n)\n\nfilegroup(\n name = \"srcs\",\n srcs = glob(\n allow_empty = True,\n include = [\n \"*.bazel\",\n \"*.bzl\",\n ],\n ),\n)\n\n# Workspace Member Dependencies\nalias(\n name = \"assert-json-diff-2.0.2\",\n actual = \"@crates__assert-json-diff-2.0.2//:assert_json_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"assert-json-diff\",\n actual = \"@crates__assert-json-diff-2.0.2//:assert_json_diff\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clang-1.0.3\",\n actual = \"@crates__clang-1.0.3//:clang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clang\",\n actual = \"@crates__clang-1.0.3//:clang\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clang-sys-1.8.1\",\n actual = \"@crates__clang-sys-1.8.1//:clang_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clang-sys\",\n actual = \"@crates__clang-sys-1.8.1//:clang_sys\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap-4.6.6\",\n actual = \"@crates__clap-4.6.6//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"clap\",\n actual = \"@crates__clap-4.6.6//:clap\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"env_logger-0.10.2\",\n actual = \"@crates__env_logger-0.10.2//:env_logger\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"env_logger\",\n actual = \"@crates__env_logger-0.10.2//:env_logger\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flatbuffers-25.12.19\",\n actual = \"@crates__flatbuffers-25.12.19//:flatbuffers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"flatbuffers\",\n actual = \"@crates__flatbuffers-25.12.19//:flatbuffers\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libloading-0.9.0\",\n actual = \"@crates__libloading-0.9.0//:libloading\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"libloading\",\n actual = \"@crates__libloading-0.9.0//:libloading\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"log-0.4.34\",\n actual = \"@crates__log-0.4.34//:log\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"log\",\n actual = \"@crates__log-0.4.34//:log\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell-1.21.4\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"once_cell\",\n actual = \"@crates__once_cell-1.21.4//:once_cell\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pest-2.9.1\",\n actual = \"@crates__pest-2.9.1//:pest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pest\",\n actual = \"@crates__pest-2.9.1//:pest\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pest_derive-2.9.1\",\n actual = \"@crates__pest_derive-2.9.1//:pest_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"pest_derive\",\n actual = \"@crates__pest_derive-2.9.1//:pest_derive\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde-1.0.229\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde\",\n actual = \"@crates__serde-1.0.229//:serde\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json-1.0.151\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_json\",\n actual = \"@crates__serde_json-1.0.151//:serde_json\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_yaml-0.9.34+deprecated\",\n actual = \"@crates__serde_yaml-0.9.34-deprecated//:serde_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"serde_yaml\",\n actual = \"@crates__serde_yaml-0.9.34-deprecated//:serde_yaml\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strsim-0.11.1\",\n actual = \"@crates__strsim-0.11.1//:strsim\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"strsim\",\n actual = \"@crates__strsim-0.11.1//:strsim\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror-1.0.69\",\n actual = \"@crates__thiserror-1.0.69//:thiserror\",\n tags = [\"manual\"],\n)\n\nalias(\n name = \"thiserror\",\n actual = \"@crates__thiserror-1.0.69//:thiserror\",\n tags = [\"manual\"],\n)\n", + "alias_rules.bzl": "\"\"\"Alias that transitions its target to `compilation_mode=opt`. Use `transition_alias=\"opt\"` to enable.\"\"\"\n\nload(\"@rules_cc//cc:defs.bzl\", \"CcInfo\")\nload(\"@rules_rust//rust:rust_common.bzl\", \"COMMON_PROVIDERS\")\n\ndef _transition_alias_impl(ctx):\n # `ctx.attr.actual` is a list of 1 item due to the transition\n providers = [ctx.attr.actual[0][provider] for provider in COMMON_PROVIDERS]\n if CcInfo in ctx.attr.actual[0]:\n providers.append(ctx.attr.actual[0][CcInfo])\n return providers\n\ndef _change_compilation_mode(compilation_mode):\n def _change_compilation_mode_impl(_settings, _attr):\n return {\n \"//command_line_option:compilation_mode\": compilation_mode,\n }\n\n return transition(\n implementation = _change_compilation_mode_impl,\n inputs = [],\n outputs = [\n \"//command_line_option:compilation_mode\",\n ],\n )\n\ndef _transition_alias_rule(compilation_mode):\n return rule(\n implementation = _transition_alias_impl,\n provides = COMMON_PROVIDERS,\n attrs = {\n \"actual\": attr.label(\n mandatory = True,\n doc = \"`rust_library()` target to transition to `compilation_mode=opt`.\",\n providers = COMMON_PROVIDERS,\n cfg = _change_compilation_mode(compilation_mode),\n ),\n \"_allowlist_function_transition\": attr.label(\n default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n ),\n },\n doc = \"Transitions a Rust library crate to the `compilation_mode=opt`.\",\n )\n\ntransition_alias_dbg = _transition_alias_rule(\"dbg\")\ntransition_alias_fastbuild = _transition_alias_rule(\"fastbuild\")\ntransition_alias_opt = _transition_alias_rule(\"opt\")\n", + "defs.bzl": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\"\"\"\n# `crates_repository` API\n\n- [aliases](#aliases)\n- [crate_deps](#crate_deps)\n- [all_crate_deps](#all_crate_deps)\n- [crate_repositories](#crate_repositories)\n\n\"\"\"\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"new_git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@rules_rust//crate_universe/private:local_crate_mirror.bzl\", \"local_crate_mirror\")\n\n###############################################################################\n# MACROS API\n###############################################################################\n\n# An identifier that represent common dependencies (unconditional).\n_COMMON_CONDITION = \"\"\n\ndef _flatten_dependency_maps(all_dependency_maps):\n \"\"\"Flatten a list of dependency maps into one dictionary.\n\n Dependency maps have the following structure:\n\n ```python\n DEPENDENCIES_MAP = {\n # The first key in the map is a Bazel package\n # name of the workspace this file is defined in.\n \"workspace_member_package\": {\n\n # Not all dependencies are supported for all platforms.\n # the condition key is the condition required to be true\n # on the host platform.\n \"condition\": {\n\n # An alias to a crate target. # The label of the crate target the\n # Aliases are only crate names. # package name refers to.\n \"package_name\": \"@full//:label\",\n }\n }\n }\n ```\n\n Args:\n all_dependency_maps (list): A list of dicts as described above\n\n Returns:\n dict: A dictionary as described above\n \"\"\"\n dependencies = {}\n\n for workspace_deps_map in all_dependency_maps:\n for pkg_name, conditional_deps_map in workspace_deps_map.items():\n if pkg_name not in dependencies:\n non_frozen_map = dict()\n for key, values in conditional_deps_map.items():\n non_frozen_map.update({key: dict(values.items())})\n dependencies.setdefault(pkg_name, non_frozen_map)\n continue\n\n for condition, deps_map in conditional_deps_map.items():\n # If the condition has not been recorded, do so and continue\n if condition not in dependencies[pkg_name]:\n dependencies[pkg_name].setdefault(condition, dict(deps_map.items()))\n continue\n\n # Alert on any miss-matched dependencies\n inconsistent_entries = []\n for crate_name, crate_label in deps_map.items():\n existing = dependencies[pkg_name][condition].get(crate_name)\n if existing and existing != crate_label:\n inconsistent_entries.append((crate_name, existing, crate_label))\n dependencies[pkg_name][condition].update({crate_name: crate_label})\n\n return dependencies\n\ndef crate_deps(deps, package_name = None):\n \"\"\"Finds the fully qualified label of the requested crates for the package where this macro is called.\n\n Args:\n deps (list): The desired list of crate targets.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()`.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if not deps:\n return []\n\n if package_name == None:\n package_name = native.package_name()\n\n # Join both sets of dependencies\n dependencies = _flatten_dependency_maps([\n _NORMAL_DEPENDENCIES,\n _NORMAL_DEV_DEPENDENCIES,\n _PROC_MACRO_DEPENDENCIES,\n _PROC_MACRO_DEV_DEPENDENCIES,\n _BUILD_DEPENDENCIES,\n _BUILD_PROC_MACRO_DEPENDENCIES,\n ]).pop(package_name, {})\n\n # Combine all conditional packages so we can easily index over a flat list\n # TODO: Perhaps this should actually return select statements and maintain\n # the conditionals of the dependencies\n flat_deps = {}\n for deps_set in dependencies.values():\n for crate_name, crate_label in deps_set.items():\n flat_deps.update({crate_name: crate_label})\n\n missing_crates = []\n crate_targets = []\n for crate_target in deps:\n if crate_target not in flat_deps:\n missing_crates.append(crate_target)\n else:\n crate_targets.append(flat_deps[crate_target])\n\n if missing_crates:\n fail(\"Could not find crates `{}` among dependencies of `{}`. Available dependencies were `{}`\".format(\n missing_crates,\n package_name,\n dependencies,\n ))\n\n return crate_targets\n\ndef all_crate_deps(\n normal = False, \n normal_dev = False, \n proc_macro = False, \n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Finds the fully qualified label of all requested direct crate dependencies \\\n for the package where this macro is called.\n\n If no parameters are set, all normal dependencies are returned. Setting any one flag will\n otherwise impact the contents of the returned list.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list.\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n list: A list of labels to generated rust targets (str)\n \"\"\"\n\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_dependency_maps = []\n if normal:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n if normal_dev:\n all_dependency_maps.append(_NORMAL_DEV_DEPENDENCIES)\n if proc_macro:\n all_dependency_maps.append(_PROC_MACRO_DEPENDENCIES)\n if proc_macro_dev:\n all_dependency_maps.append(_PROC_MACRO_DEV_DEPENDENCIES)\n if build:\n all_dependency_maps.append(_BUILD_DEPENDENCIES)\n if build_proc_macro:\n all_dependency_maps.append(_BUILD_PROC_MACRO_DEPENDENCIES)\n\n # Default to always using normal dependencies\n if not all_dependency_maps:\n all_dependency_maps.append(_NORMAL_DEPENDENCIES)\n\n dependencies = _flatten_dependency_maps(all_dependency_maps).pop(package_name, None)\n\n if not dependencies:\n if dependencies == None:\n fail(\"Tried to get all_crate_deps for package \" + package_name + \" but that package had no Cargo.toml file\")\n else:\n return []\n\n crate_deps = list(dependencies.pop(_COMMON_CONDITION, {}).values())\n for condition, deps in dependencies.items():\n crate_deps += selects.with_or({\n tuple(_CONDITIONS[condition]): deps.values(),\n \"//conditions:default\": [],\n })\n\n return crate_deps\n\ndef aliases(\n normal = False,\n normal_dev = False,\n proc_macro = False,\n proc_macro_dev = False,\n build = False,\n build_proc_macro = False,\n package_name = None):\n \"\"\"Produces a map of Crate alias names to their original label\n\n If no dependency kinds are specified, `normal` and `proc_macro` are used by default.\n Setting any one flag will otherwise determine the contents of the returned dict.\n\n Args:\n normal (bool, optional): If True, normal dependencies are included in the\n output list.\n normal_dev (bool, optional): If True, normal dev dependencies will be\n included in the output list..\n proc_macro (bool, optional): If True, proc_macro dependencies are included\n in the output list.\n proc_macro_dev (bool, optional): If True, dev proc_macro dependencies are\n included in the output list.\n build (bool, optional): If True, build dependencies are included\n in the output list.\n build_proc_macro (bool, optional): If True, build proc_macro dependencies are\n included in the output list.\n package_name (str, optional): The package name of the set of dependencies to look up.\n Defaults to `native.package_name()` when unset.\n\n Returns:\n dict: The aliases of all associated packages\n \"\"\"\n if package_name == None:\n package_name = native.package_name()\n\n # Determine the relevant maps to use\n all_aliases_maps = []\n if normal:\n all_aliases_maps.append(_NORMAL_ALIASES)\n if normal_dev:\n all_aliases_maps.append(_NORMAL_DEV_ALIASES)\n if proc_macro:\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n if proc_macro_dev:\n all_aliases_maps.append(_PROC_MACRO_DEV_ALIASES)\n if build:\n all_aliases_maps.append(_BUILD_ALIASES)\n if build_proc_macro:\n all_aliases_maps.append(_BUILD_PROC_MACRO_ALIASES)\n\n # Default to always using normal aliases\n if not all_aliases_maps:\n all_aliases_maps.append(_NORMAL_ALIASES)\n all_aliases_maps.append(_PROC_MACRO_ALIASES)\n\n aliases = _flatten_dependency_maps(all_aliases_maps).pop(package_name, None)\n\n if not aliases:\n return dict()\n\n common_items = aliases.pop(_COMMON_CONDITION, {}).items()\n\n # If there are only common items in the dictionary, immediately return them\n if not len(aliases.keys()) == 1:\n return dict(common_items)\n\n # Build a single select statement where each conditional has accounted for the\n # common set of aliases.\n crate_aliases = {\"//conditions:default\": dict(common_items)}\n for condition, deps in aliases.items():\n condition_triples = _CONDITIONS[condition]\n for triple in condition_triples:\n if triple in crate_aliases:\n crate_aliases[triple].update(deps)\n else:\n crate_aliases.update({triple: dict(deps.items() + common_items)})\n\n return select(crate_aliases)\n\n###############################################################################\n# WORKSPACE MEMBER DEPS AND ALIASES\n###############################################################################\n\n_NORMAL_DEPENDENCIES = {\n \"\": {\n _COMMON_CONDITION: {\n \"assert-json-diff\": Label(\"@crates//:assert-json-diff-2.0.2\"),\n \"clang\": Label(\"@crates//:clang-1.0.3\"),\n \"clang-sys\": Label(\"@crates//:clang-sys-1.8.1\"),\n \"clap\": Label(\"@crates//:clap-4.6.6\"),\n \"env_logger\": Label(\"@crates//:env_logger-0.10.2\"),\n \"flatbuffers\": Label(\"@crates//:flatbuffers-25.12.19\"),\n \"libloading\": Label(\"@crates//:libloading-0.9.0\"),\n \"log\": Label(\"@crates//:log-0.4.34\"),\n \"once_cell\": Label(\"@crates//:once_cell-1.21.4\"),\n \"pest\": Label(\"@crates//:pest-2.9.1\"),\n \"serde\": Label(\"@crates//:serde-1.0.229\"),\n \"serde_json\": Label(\"@crates//:serde_json-1.0.151\"),\n \"serde_yaml\": Label(\"@crates//:serde_yaml-0.9.34+deprecated\"),\n \"strsim\": Label(\"@crates//:strsim-0.11.1\"),\n \"thiserror\": Label(\"@crates//:thiserror-1.0.69\"),\n },\n },\n}\n\n\n_NORMAL_ALIASES = {\n \"\": {\n _COMMON_CONDITION: {\n },\n },\n}\n\n\n_NORMAL_DEV_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_NORMAL_DEV_ALIASES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEPENDENCIES = {\n \"\": {\n _COMMON_CONDITION: {\n \"pest_derive\": Label(\"@crates//:pest_derive-2.9.1\"),\n },\n },\n}\n\n\n_PROC_MACRO_ALIASES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEV_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_PROC_MACRO_DEV_ALIASES = {\n \"\": {\n },\n}\n\n\n_BUILD_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_BUILD_ALIASES = {\n \"\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_DEPENDENCIES = {\n \"\": {\n },\n}\n\n\n_BUILD_PROC_MACRO_ALIASES = {\n \"\": {\n },\n}\n\n\n_CONDITIONS = {\n \"aarch64-apple-darwin\": [\"@rules_rust//rust/platform:aarch64-apple-darwin\"],\n \"aarch64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\"],\n \"cfg(any())\": [],\n \"cfg(any(unix, target_os = \\\"wasi\\\"))\": [\"@rules_rust//rust/platform:aarch64-apple-darwin\",\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:wasm32-wasip1\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\"],\n \"cfg(target_os = \\\"hermit\\\")\": [],\n \"cfg(unix)\": [\"@rules_rust//rust/platform:aarch64-apple-darwin\",\"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\",\"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\"],\n \"cfg(windows)\": [\"@rules_rust//rust/platform:x86_64-pc-windows-msvc\"],\n \"wasm32-unknown-unknown\": [\"@rules_rust//rust/platform:wasm32-unknown-unknown\"],\n \"wasm32-wasip1\": [\"@rules_rust//rust/platform:wasm32-wasip1\"],\n \"x86_64-pc-windows-msvc\": [\"@rules_rust//rust/platform:x86_64-pc-windows-msvc\"],\n \"x86_64-unknown-linux-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\"],\n \"x86_64-unknown-nixos-gnu\": [\"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\"],\n}\n\n###############################################################################\n\ndef crate_repositories():\n \"\"\"A macro for defining repositories for all generated crates.\n\n Returns:\n A list of repos visible to the module through the module extension.\n \"\"\"\n maybe(\n http_archive,\n name = \"crates__aho-corasick-1.1.5\",\n sha256 = \"c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/aho-corasick/1.1.5/download\"],\n strip_prefix = \"aho-corasick-1.1.5\",\n build_file = Label(\"@crates//crates:BUILD.aho-corasick-1.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstream-1.0.0\",\n sha256 = \"824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstream/1.0.0/download\"],\n strip_prefix = \"anstream-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstream-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-1.0.14\",\n sha256 = \"940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle/1.0.14/download\"],\n strip_prefix = \"anstyle-1.0.14\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-1.0.14.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-parse-1.0.0\",\n sha256 = \"52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-parse/1.0.0/download\"],\n strip_prefix = \"anstyle-parse-1.0.0\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-parse-1.0.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-query-1.1.5\",\n sha256 = \"40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-query/1.1.5/download\"],\n strip_prefix = \"anstyle-query-1.1.5\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-query-1.1.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__anstyle-wincon-3.0.11\",\n sha256 = \"291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/anstyle-wincon/3.0.11/download\"],\n strip_prefix = \"anstyle-wincon-3.0.11\",\n build_file = Label(\"@crates//crates:BUILD.anstyle-wincon-3.0.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__assert-json-diff-2.0.2\",\n sha256 = \"47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/assert-json-diff/2.0.2/download\"],\n strip_prefix = \"assert-json-diff-2.0.2\",\n build_file = Label(\"@crates//crates:BUILD.assert-json-diff-2.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__bitflags-2.13.1\",\n sha256 = \"b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/bitflags/2.13.1/download\"],\n strip_prefix = \"bitflags-2.13.1\",\n build_file = Label(\"@crates//crates:BUILD.bitflags-2.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__cfg-if-1.0.4\",\n sha256 = \"9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/cfg-if/1.0.4/download\"],\n strip_prefix = \"cfg-if-1.0.4\",\n build_file = Label(\"@crates//crates:BUILD.cfg-if-1.0.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clang-1.0.3\",\n sha256 = \"34c6913be3a1c94f52fb975cdec7ef5a7b69de10a55de66dcbc30d7046b85fa1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clang/1.0.3/download\"],\n strip_prefix = \"clang-1.0.3\",\n build_file = Label(\"@crates//crates:BUILD.clang-1.0.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clang-sys-1.8.1\",\n sha256 = \"0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clang-sys/1.8.1/download\"],\n strip_prefix = \"clang-sys-1.8.1\",\n build_file = Label(\"@crates//crates:BUILD.clang-sys-1.8.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap-4.6.6\",\n sha256 = \"473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap/4.6.6/download\"],\n strip_prefix = \"clap-4.6.6\",\n build_file = Label(\"@crates//crates:BUILD.clap-4.6.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_builder-4.6.6\",\n sha256 = \"7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_builder/4.6.6/download\"],\n strip_prefix = \"clap_builder-4.6.6\",\n build_file = Label(\"@crates//crates:BUILD.clap_builder-4.6.6.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_derive-4.6.4\",\n sha256 = \"d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_derive/4.6.4/download\"],\n strip_prefix = \"clap_derive-4.6.4\",\n build_file = Label(\"@crates//crates:BUILD.clap_derive-4.6.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__clap_lex-1.1.0\",\n sha256 = \"c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/clap_lex/1.1.0/download\"],\n strip_prefix = \"clap_lex-1.1.0\",\n build_file = Label(\"@crates//crates:BUILD.clap_lex-1.1.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__colorchoice-1.0.5\",\n sha256 = \"1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/colorchoice/1.0.5/download\"],\n strip_prefix = \"colorchoice-1.0.5\",\n build_file = Label(\"@crates//crates:BUILD.colorchoice-1.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__env_logger-0.10.2\",\n sha256 = \"4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/env_logger/0.10.2/download\"],\n strip_prefix = \"env_logger-0.10.2\",\n build_file = Label(\"@crates//crates:BUILD.env_logger-0.10.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__equivalent-1.0.2\",\n sha256 = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/equivalent/1.0.2/download\"],\n strip_prefix = \"equivalent-1.0.2\",\n build_file = Label(\"@crates//crates:BUILD.equivalent-1.0.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__flatbuffers-25.12.19\",\n sha256 = \"35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/flatbuffers/25.12.19/download\"],\n strip_prefix = \"flatbuffers-25.12.19\",\n build_file = Label(\"@crates//crates:BUILD.flatbuffers-25.12.19.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__glob-0.3.4\",\n sha256 = \"e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/glob/0.3.4/download\"],\n strip_prefix = \"glob-0.3.4\",\n build_file = Label(\"@crates//crates:BUILD.glob-0.3.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hashbrown-0.17.1\",\n sha256 = \"ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hashbrown/0.17.1/download\"],\n strip_prefix = \"hashbrown-0.17.1\",\n build_file = Label(\"@crates//crates:BUILD.hashbrown-0.17.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__heck-0.5.0\",\n sha256 = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/heck/0.5.0/download\"],\n strip_prefix = \"heck-0.5.0\",\n build_file = Label(\"@crates//crates:BUILD.heck-0.5.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__hermit-abi-0.5.3\",\n sha256 = \"e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/hermit-abi/0.5.3/download\"],\n strip_prefix = \"hermit-abi-0.5.3\",\n build_file = Label(\"@crates//crates:BUILD.hermit-abi-0.5.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__humantime-2.4.0\",\n sha256 = \"15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/humantime/2.4.0/download\"],\n strip_prefix = \"humantime-2.4.0\",\n build_file = Label(\"@crates//crates:BUILD.humantime-2.4.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__indexmap-2.14.2\",\n sha256 = \"cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/indexmap/2.14.2/download\"],\n strip_prefix = \"indexmap-2.14.2\",\n build_file = Label(\"@crates//crates:BUILD.indexmap-2.14.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__is-terminal-0.4.17\",\n sha256 = \"3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/is-terminal/0.4.17/download\"],\n strip_prefix = \"is-terminal-0.4.17\",\n build_file = Label(\"@crates//crates:BUILD.is-terminal-0.4.17.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__is_terminal_polyfill-1.70.2\",\n sha256 = \"a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/is_terminal_polyfill/1.70.2/download\"],\n strip_prefix = \"is_terminal_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.is_terminal_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__itoa-1.0.18\",\n sha256 = \"8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/itoa/1.0.18/download\"],\n strip_prefix = \"itoa-1.0.18\",\n build_file = Label(\"@crates//crates:BUILD.itoa-1.0.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libc-0.2.189\",\n sha256 = \"3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libc/0.2.189/download\"],\n strip_prefix = \"libc-0.2.189\",\n build_file = Label(\"@crates//crates:BUILD.libc-0.2.189.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__libloading-0.9.0\",\n sha256 = \"754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/libloading/0.9.0/download\"],\n strip_prefix = \"libloading-0.9.0\",\n build_file = Label(\"@crates//crates:BUILD.libloading-0.9.0.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__log-0.4.34\",\n sha256 = \"f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/log/0.4.34/download\"],\n strip_prefix = \"log-0.4.34\",\n build_file = Label(\"@crates//crates:BUILD.log-0.4.34.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__memchr-2.8.3\",\n sha256 = \"cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/memchr/2.8.3/download\"],\n strip_prefix = \"memchr-2.8.3\",\n build_file = Label(\"@crates//crates:BUILD.memchr-2.8.3.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell-1.21.4\",\n sha256 = \"9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell/1.21.4/download\"],\n strip_prefix = \"once_cell-1.21.4\",\n build_file = Label(\"@crates//crates:BUILD.once_cell-1.21.4.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__once_cell_polyfill-1.70.2\",\n sha256 = \"384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/once_cell_polyfill/1.70.2/download\"],\n strip_prefix = \"once_cell_polyfill-1.70.2\",\n build_file = Label(\"@crates//crates:BUILD.once_cell_polyfill-1.70.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest-2.9.1\",\n sha256 = \"6d45aeb61b4bf818e12d4205f2466f8c4748f85f4fce0146d1c03d69d753f0ad\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest/2.9.1/download\"],\n strip_prefix = \"pest-2.9.1\",\n build_file = Label(\"@crates//crates:BUILD.pest-2.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_derive-2.9.1\",\n sha256 = \"89cc5a242e25ed4e7704d0be240f2cfbe20a8c27e7e252d94835be93d92dc39f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_derive/2.9.1/download\"],\n strip_prefix = \"pest_derive-2.9.1\",\n build_file = Label(\"@crates//crates:BUILD.pest_derive-2.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_generator-2.9.1\",\n sha256 = \"7abf21475cc3820fe4b2ca2dc2142902f67a02189f3b5b3a229f4febc01a43e5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_generator/2.9.1/download\"],\n strip_prefix = \"pest_generator-2.9.1\",\n build_file = Label(\"@crates//crates:BUILD.pest_generator-2.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__pest_meta-2.9.1\",\n sha256 = \"adba4db388f687393c18c51348d44a41d870ca9df71a2c98172ea3035dc6936e\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/pest_meta/2.9.1/download\"],\n strip_prefix = \"pest_meta-2.9.1\",\n build_file = Label(\"@crates//crates:BUILD.pest_meta-2.9.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__proc-macro2-1.0.107\",\n sha256 = \"985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/proc-macro2/1.0.107/download\"],\n strip_prefix = \"proc-macro2-1.0.107\",\n build_file = Label(\"@crates//crates:BUILD.proc-macro2-1.0.107.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__quote-1.0.47\",\n sha256 = \"1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/quote/1.0.47/download\"],\n strip_prefix = \"quote-1.0.47\",\n build_file = Label(\"@crates//crates:BUILD.quote-1.0.47.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-1.13.1\",\n sha256 = \"f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex/1.13.1/download\"],\n strip_prefix = \"regex-1.13.1\",\n build_file = Label(\"@crates//crates:BUILD.regex-1.13.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-automata-0.4.18\",\n sha256 = \"ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-automata/0.4.18/download\"],\n strip_prefix = \"regex-automata-0.4.18\",\n build_file = Label(\"@crates//crates:BUILD.regex-automata-0.4.18.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__regex-syntax-0.8.11\",\n sha256 = \"d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/regex-syntax/0.8.11/download\"],\n strip_prefix = \"regex-syntax-0.8.11\",\n build_file = Label(\"@crates//crates:BUILD.regex-syntax-0.8.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__rustc_version-0.4.1\",\n sha256 = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/rustc_version/0.4.1/download\"],\n strip_prefix = \"rustc_version-0.4.1\",\n build_file = Label(\"@crates//crates:BUILD.rustc_version-0.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ryu-1.0.23\",\n sha256 = \"9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ryu/1.0.23/download\"],\n strip_prefix = \"ryu-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.ryu-1.0.23.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__semver-1.0.28\",\n sha256 = \"8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/semver/1.0.28/download\"],\n strip_prefix = \"semver-1.0.28\",\n build_file = Label(\"@crates//crates:BUILD.semver-1.0.28.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde-1.0.229\",\n sha256 = \"4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde/1.0.229/download\"],\n strip_prefix = \"serde-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_core-1.0.229\",\n sha256 = \"67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_core/1.0.229/download\"],\n strip_prefix = \"serde_core-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_core-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_derive-1.0.229\",\n sha256 = \"e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_derive/1.0.229/download\"],\n strip_prefix = \"serde_derive-1.0.229\",\n build_file = Label(\"@crates//crates:BUILD.serde_derive-1.0.229.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_json-1.0.151\",\n sha256 = \"c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_json/1.0.151/download\"],\n strip_prefix = \"serde_json-1.0.151\",\n build_file = Label(\"@crates//crates:BUILD.serde_json-1.0.151.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__serde_yaml-0.9.34-deprecated\",\n sha256 = \"6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/serde_yaml/0.9.34+deprecated/download\"],\n strip_prefix = \"serde_yaml-0.9.34+deprecated\",\n build_file = Label(\"@crates//crates:BUILD.serde_yaml-0.9.34+deprecated.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__strsim-0.11.1\",\n sha256 = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/strsim/0.11.1/download\"],\n strip_prefix = \"strsim-0.11.1\",\n build_file = Label(\"@crates//crates:BUILD.strsim-0.11.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-2.0.119\",\n sha256 = \"872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/2.0.119/download\"],\n strip_prefix = \"syn-2.0.119\",\n build_file = Label(\"@crates//crates:BUILD.syn-2.0.119.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__syn-3.0.5\",\n sha256 = \"12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/syn/3.0.5/download\"],\n strip_prefix = \"syn-3.0.5\",\n build_file = Label(\"@crates//crates:BUILD.syn-3.0.5.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__termcolor-1.4.1\",\n sha256 = \"06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/termcolor/1.4.1/download\"],\n strip_prefix = \"termcolor-1.4.1\",\n build_file = Label(\"@crates//crates:BUILD.termcolor-1.4.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-1.0.69\",\n sha256 = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror/1.0.69/download\"],\n strip_prefix = \"thiserror-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__thiserror-impl-1.0.69\",\n sha256 = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/thiserror-impl/1.0.69/download\"],\n strip_prefix = \"thiserror-impl-1.0.69\",\n build_file = Label(\"@crates//crates:BUILD.thiserror-impl-1.0.69.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__ucd-trie-0.1.7\",\n sha256 = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/ucd-trie/0.1.7/download\"],\n strip_prefix = \"ucd-trie-0.1.7\",\n build_file = Label(\"@crates//crates:BUILD.ucd-trie-0.1.7.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unicode-ident-1.0.24\",\n sha256 = \"e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unicode-ident/1.0.24/download\"],\n strip_prefix = \"unicode-ident-1.0.24\",\n build_file = Label(\"@crates//crates:BUILD.unicode-ident-1.0.24.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__unsafe-libyaml-0.2.11\",\n sha256 = \"673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/unsafe-libyaml/0.2.11/download\"],\n strip_prefix = \"unsafe-libyaml-0.2.11\",\n build_file = Label(\"@crates//crates:BUILD.unsafe-libyaml-0.2.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__utf8parse-0.2.2\",\n sha256 = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/utf8parse/0.2.2/download\"],\n strip_prefix = \"utf8parse-0.2.2\",\n build_file = Label(\"@crates//crates:BUILD.utf8parse-0.2.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__winapi-util-0.1.11\",\n sha256 = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/winapi-util/0.1.11/download\"],\n strip_prefix = \"winapi-util-0.1.11\",\n build_file = Label(\"@crates//crates:BUILD.winapi-util-0.1.11.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-link-0.2.1\",\n sha256 = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-link/0.2.1/download\"],\n strip_prefix = \"windows-link-0.2.1\",\n build_file = Label(\"@crates//crates:BUILD.windows-link-0.2.1.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__windows-sys-0.61.2\",\n sha256 = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/windows-sys/0.61.2/download\"],\n strip_prefix = \"windows-sys-0.61.2\",\n build_file = Label(\"@crates//crates:BUILD.windows-sys-0.61.2.bazel\"),\n )\n\n maybe(\n http_archive,\n name = \"crates__zmij-1.0.23\",\n sha256 = \"29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b\",\n type = \"tar.gz\",\n urls = [\"https://static.crates.io/crates/zmij/1.0.23/download\"],\n strip_prefix = \"zmij-1.0.23\",\n build_file = Label(\"@crates//crates:BUILD.zmij-1.0.23.bazel\"),\n )\n\n return [\n struct(repo=\"crates__assert-json-diff-2.0.2\", is_dev_dep = False),\n struct(repo=\"crates__clang-1.0.3\", is_dev_dep = False),\n struct(repo=\"crates__clang-sys-1.8.1\", is_dev_dep = False),\n struct(repo=\"crates__clap-4.6.6\", is_dev_dep = False),\n struct(repo=\"crates__env_logger-0.10.2\", is_dev_dep = False),\n struct(repo=\"crates__flatbuffers-25.12.19\", is_dev_dep = False),\n struct(repo=\"crates__libloading-0.9.0\", is_dev_dep = False),\n struct(repo=\"crates__log-0.4.34\", is_dev_dep = False),\n struct(repo=\"crates__once_cell-1.21.4\", is_dev_dep = False),\n struct(repo=\"crates__pest-2.9.1\", is_dev_dep = False),\n struct(repo=\"crates__pest_derive-2.9.1\", is_dev_dep = False),\n struct(repo=\"crates__serde-1.0.229\", is_dev_dep = False),\n struct(repo=\"crates__serde_json-1.0.151\", is_dev_dep = False),\n struct(repo=\"crates__serde_yaml-0.9.34-deprecated\", is_dev_dep = False),\n struct(repo=\"crates__strsim-0.11.1\", is_dev_dep = False),\n struct(repo=\"crates__thiserror-1.0.69\", is_dev_dep = False),\n ]\n" + } + } + }, + "crates__aho-corasick-1.1.5": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/aho-corasick/1.1.5/download" + ], + "strip_prefix": "aho-corasick-1.1.5", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"aho_corasick\",\n deps = [\n \"@crates__memchr-2.8.3//:memchr\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"perf-literal\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=aho-corasick\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.1.5\",\n)\n" + } + }, + "crates__anstream-1.0.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anstream/1.0.0/download" + ], + "strip_prefix": "anstream-1.0.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"anstream\",\n deps = [\n \"@crates__anstyle-1.0.14//:anstyle\",\n \"@crates__anstyle-parse-1.0.0//:anstyle_parse\",\n \"@crates__anstyle-query-1.1.5//:anstyle_query\",\n \"@crates__colorchoice-1.0.5//:colorchoice\",\n \"@crates__is_terminal_polyfill-1.70.2//:is_terminal_polyfill\",\n \"@crates__utf8parse-0.2.2//:utf8parse\",\n ] + select({\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__anstyle-wincon-3.0.11//:anstyle_wincon\", # x86_64-pc-windows-msvc\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"auto\",\n \"default\",\n \"wincon\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=anstream\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.0\",\n)\n" + } + }, + "crates__anstyle-1.0.14": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anstyle/1.0.14/download" + ], + "strip_prefix": "anstyle-1.0.14", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"anstyle\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=anstyle\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.14\",\n)\n" + } + }, + "crates__anstyle-parse-1.0.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anstyle-parse/1.0.0/download" + ], + "strip_prefix": "anstyle-parse-1.0.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"anstyle_parse\",\n deps = [\n \"@crates__utf8parse-0.2.2//:utf8parse\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"utf8\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=anstyle-parse\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.0\",\n)\n" + } + }, + "crates__anstyle-query-1.1.5": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anstyle-query/1.1.5/download" + ], + "strip_prefix": "anstyle-query-1.1.5", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"anstyle_query\",\n deps = select({\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__windows-sys-0.61.2//:windows_sys\", # cfg(windows)\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=anstyle-query\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.1.5\",\n)\n" + } + }, + "crates__anstyle-wincon-3.0.11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/anstyle-wincon/3.0.11/download" + ], + "strip_prefix": "anstyle-wincon-3.0.11", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"anstyle_wincon\",\n deps = [\n \"@crates__anstyle-1.0.14//:anstyle\",\n ] + select({\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__once_cell_polyfill-1.70.2//:once_cell_polyfill\", # cfg(windows)\n \"@crates__windows-sys-0.61.2//:windows_sys\", # cfg(windows)\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=anstyle-wincon\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.0.11\",\n)\n" + } + }, + "crates__assert-json-diff-2.0.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/assert-json-diff/2.0.2/download" + ], + "strip_prefix": "assert-json-diff-2.0.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"assert_json_diff\",\n deps = [\n \"@crates__serde-1.0.229//:serde\",\n \"@crates__serde_json-1.0.151//:serde_json\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=assert-json-diff\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.0.2\",\n)\n" + } + }, + "crates__bitflags-2.13.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/bitflags/2.13.1/download" + ], + "strip_prefix": "bitflags-2.13.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"bitflags\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=bitflags\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.13.1\",\n)\n" + } + }, + "crates__cfg-if-1.0.4": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/cfg-if/1.0.4/download" + ], + "strip_prefix": "cfg-if-1.0.4", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"cfg_if\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=cfg-if\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.4\",\n)\n" + } + }, + "crates__clang-1.0.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "34c6913be3a1c94f52fb975cdec7ef5a7b69de10a55de66dcbc30d7046b85fa1", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clang/1.0.3/download" + ], + "strip_prefix": "clang-1.0.3", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"clang\",\n deps = [\n \"@crates__clang-sys-1.8.1//:clang_sys\",\n \"@crates__libc-0.2.189//:libc\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"runtime\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2015\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clang\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.3\",\n)\n" + } + }, + "crates__clang-sys-1.8.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clang-sys/1.8.1/download" + ], + "strip_prefix": "clang-sys-1.8.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"clang_sys\",\n deps = [\n \"@crates//:libloading\",\n \"@crates__clang-sys-1.8.1//:build_script_build\",\n \"@crates__glob-0.3.4//:glob\",\n \"@crates__libc-0.2.189//:libc\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"clang_18_0\",\n \"runtime\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clang-sys\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.8.1\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"clang_18_0\",\n \"runtime\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__glob-0.3.4//:glob\",\n ],\n edition = \"2021\",\n links = \"clang\",\n pkg_name = \"clang-sys\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clang-sys\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.8.1\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__clap-4.6.6": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "473c7e07f409a8d772161724aa8db6a765a2532a70f9667eeb7b49d3d02fbdca", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clap/4.6.6/download" + ], + "strip_prefix": "clap-4.6.6", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"clap\",\n deps = [\n \"@crates__clap_builder-4.6.6//:clap_builder\",\n ],\n proc_macro_deps = [\n \"@crates__clap_derive-4.6.4//:clap_derive\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"color\",\n \"default\",\n \"derive\",\n \"error-context\",\n \"help\",\n \"std\",\n \"suggestions\",\n \"usage\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clap\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"4.6.6\",\n)\n" + } + }, + "crates__clap_builder-4.6.6": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "7b48fea5a88e9ae728a2dcbedbfc0e730f7d60da42e1cb049a83c9fb8b789889", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clap_builder/4.6.6/download" + ], + "strip_prefix": "clap_builder-4.6.6", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"clap_builder\",\n deps = [\n \"@crates__anstream-1.0.0//:anstream\",\n \"@crates__anstyle-1.0.14//:anstyle\",\n \"@crates__clap_lex-1.1.0//:clap_lex\",\n \"@crates__strsim-0.11.1//:strsim\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"color\",\n \"error-context\",\n \"help\",\n \"std\",\n \"suggestions\",\n \"usage\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clap_builder\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"4.6.6\",\n)\n" + } + }, + "crates__clap_derive-4.6.4": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clap_derive/4.6.4/download" + ], + "strip_prefix": "clap_derive-4.6.4", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"clap_derive\",\n deps = [\n \"@crates__heck-0.5.0//:heck\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-3.0.5//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clap_derive\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"4.6.4\",\n)\n" + } + }, + "crates__clap_lex-1.1.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/clap_lex/1.1.0/download" + ], + "strip_prefix": "clap_lex-1.1.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"clap_lex\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=clap_lex\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.1.0\",\n)\n" + } + }, + "crates__colorchoice-1.0.5": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/colorchoice/1.0.5/download" + ], + "strip_prefix": "colorchoice-1.0.5", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"colorchoice\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=colorchoice\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.5\",\n)\n" + } + }, + "crates__env_logger-0.10.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/env_logger/0.10.2/download" + ], + "strip_prefix": "env_logger-0.10.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"env_logger\",\n deps = [\n \"@crates__humantime-2.4.0//:humantime\",\n \"@crates__is-terminal-0.4.17//:is_terminal\",\n \"@crates__log-0.4.34//:log\",\n \"@crates__regex-1.13.1//:regex\",\n \"@crates__termcolor-1.4.1//:termcolor\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"auto-color\",\n \"color\",\n \"default\",\n \"humantime\",\n \"regex\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=env_logger\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.10.2\",\n)\n" + } + }, + "crates__equivalent-1.0.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/equivalent/1.0.2/download" + ], + "strip_prefix": "equivalent-1.0.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"equivalent\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2015\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=equivalent\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.2\",\n)\n" + } + }, + "crates__flatbuffers-25.12.19": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/flatbuffers/25.12.19/download" + ], + "strip_prefix": "flatbuffers-25.12.19", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"flatbuffers\",\n deps = [\n \"@crates__bitflags-2.13.1//:bitflags\",\n \"@crates__flatbuffers-25.12.19//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=flatbuffers\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"25.12.19\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n deps = [\n \"@crates__rustc_version-0.4.1//:rustc_version\",\n ],\n edition = \"2018\",\n pkg_name = \"flatbuffers\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=flatbuffers\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"25.12.19\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__glob-0.3.4": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/glob/0.3.4/download" + ], + "strip_prefix": "glob-0.3.4", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"glob\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=glob\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.3.4\",\n)\n" + } + }, + "crates__hashbrown-0.17.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/hashbrown/0.17.1/download" + ], + "strip_prefix": "hashbrown-0.17.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"hashbrown\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=hashbrown\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.17.1\",\n)\n" + } + }, + "crates__heck-0.5.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/heck/0.5.0/download" + ], + "strip_prefix": "heck-0.5.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"heck\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=heck\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.5.0\",\n)\n" + } + }, + "crates__hermit-abi-0.5.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/hermit-abi/0.5.3/download" + ], + "strip_prefix": "hermit-abi-0.5.3", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"hermit_abi\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=hermit-abi\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.5.3\",\n)\n" + } + }, + "crates__humantime-2.4.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/humantime/2.4.0/download" + ], + "strip_prefix": "humantime-2.4.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"humantime\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=humantime\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.4.0\",\n)\n" + } + }, + "crates__indexmap-2.14.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/indexmap/2.14.2/download" + ], + "strip_prefix": "indexmap-2.14.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"indexmap\",\n deps = [\n \"@crates__equivalent-1.0.2//:equivalent\",\n \"@crates__hashbrown-0.17.1//:hashbrown\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2024\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=indexmap\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.14.2\",\n)\n" + } + }, + "crates__is-terminal-0.4.17": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/is-terminal/0.4.17/download" + ], + "strip_prefix": "is-terminal-0.4.17", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"is_terminal\",\n deps = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [\n \"@crates__libc-0.2.189//:libc\", # cfg(any(unix, target_os = \"wasi\"))\n ],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [\n \"@crates__libc-0.2.189//:libc\", # cfg(any(unix, target_os = \"wasi\"))\n ],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [\n \"@crates__libc-0.2.189//:libc\", # cfg(any(unix, target_os = \"wasi\"))\n ],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__windows-sys-0.61.2//:windows_sys\", # cfg(windows)\n ],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [\n \"@crates__libc-0.2.189//:libc\", # cfg(any(unix, target_os = \"wasi\"))\n ],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [\n \"@crates__libc-0.2.189//:libc\", # cfg(any(unix, target_os = \"wasi\"))\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=is-terminal\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.4.17\",\n)\n" + } + }, + "crates__is_terminal_polyfill-1.70.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/is_terminal_polyfill/1.70.2/download" + ], + "strip_prefix": "is_terminal_polyfill-1.70.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"is_terminal_polyfill\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=is_terminal_polyfill\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.70.2\",\n)\n" + } + }, + "crates__itoa-1.0.18": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/itoa/1.0.18/download" + ], + "strip_prefix": "itoa-1.0.18", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"itoa\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=itoa\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.18\",\n)\n" + } + }, + "crates__libc-0.2.189": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/libc/0.2.189/download" + ], + "strip_prefix": "libc-0.2.189", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"libc\",\n deps = [\n \"@crates__libc-0.2.189//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=libc\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.2.189\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"libc\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=libc\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"0.2.189\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__libloading-0.9.0": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/libloading/0.9.0/download" + ], + "strip_prefix": "libloading-0.9.0", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"libloading\",\n deps = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [\n \"@crates__cfg-if-1.0.4//:cfg_if\", # cfg(unix)\n ],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [\n \"@crates__cfg-if-1.0.4//:cfg_if\", # cfg(unix)\n ],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__windows-link-0.2.1//:windows_link\", # cfg(windows)\n ],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [\n \"@crates__cfg-if-1.0.4//:cfg_if\", # cfg(unix)\n ],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [\n \"@crates__cfg-if-1.0.4//:cfg_if\", # cfg(unix)\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=libloading\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.9.0\",\n)\n" + } + }, + "crates__log-0.4.34": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/log/0.4.34/download" + ], + "strip_prefix": "log-0.4.34", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"log\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=log\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.4.34\",\n)\n" + } + }, + "crates__memchr-2.8.3": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/memchr/2.8.3/download" + ], + "strip_prefix": "memchr-2.8.3", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"memchr\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=memchr\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.8.3\",\n)\n" + } + }, + "crates__once_cell-1.21.4": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/once_cell/1.21.4/download" + ], + "strip_prefix": "once_cell-1.21.4", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"once_cell\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"default\",\n \"race\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=once_cell\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.21.4\",\n)\n" + } + }, + "crates__once_cell_polyfill-1.70.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/once_cell_polyfill/1.70.2/download" + ], + "strip_prefix": "once_cell_polyfill-1.70.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"once_cell_polyfill\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=once_cell_polyfill\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.70.2\",\n)\n" + } + }, + "crates__pest-2.9.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "6d45aeb61b4bf818e12d4205f2466f8c4748f85f4fce0146d1c03d69d753f0ad", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pest/2.9.1/download" + ], + "strip_prefix": "pest-2.9.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"pest\",\n deps = [\n \"@crates__memchr-2.8.3//:memchr\",\n \"@crates__ucd-trie-0.1.7//:ucd_trie\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"memchr\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pest\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.9.1\",\n)\n" + } + }, + "crates__pest_derive-2.9.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "89cc5a242e25ed4e7704d0be240f2cfbe20a8c27e7e252d94835be93d92dc39f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pest_derive/2.9.1/download" + ], + "strip_prefix": "pest_derive-2.9.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"pest_derive\",\n deps = [\n \"@crates__pest-2.9.1//:pest\",\n \"@crates__pest_generator-2.9.1//:pest_generator\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pest_derive\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.9.1\",\n)\n" + } + }, + "crates__pest_generator-2.9.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "7abf21475cc3820fe4b2ca2dc2142902f67a02189f3b5b3a229f4febc01a43e5", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pest_generator/2.9.1/download" + ], + "strip_prefix": "pest_generator-2.9.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"pest_generator\",\n deps = [\n \"@crates__pest-2.9.1//:pest\",\n \"@crates__pest_meta-2.9.1//:pest_meta\",\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pest_generator\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.9.1\",\n)\n" + } + }, + "crates__pest_meta-2.9.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "adba4db388f687393c18c51348d44a41d870ca9df71a2c98172ea3035dc6936e", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/pest_meta/2.9.1/download" + ], + "strip_prefix": "pest_meta-2.9.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"pest_meta\",\n deps = [\n \"@crates__pest-2.9.1//:pest\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=pest_meta\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.9.1\",\n)\n" + } + }, + "crates__proc-macro2-1.0.107": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/proc-macro2/1.0.107/download" + ], + "strip_prefix": "proc-macro2-1.0.107", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"proc_macro2\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:build_script_build\",\n \"@crates__unicode-ident-1.0.24//:unicode_ident\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=proc-macro2\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.107\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"proc-macro\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"proc-macro2\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=proc-macro2\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.107\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__quote-1.0.47": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/quote/1.0.47/download" + ], + "strip_prefix": "quote-1.0.47", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"quote\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=quote\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.47\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"proc-macro\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"quote\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=quote\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.47\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__regex-1.13.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/regex/1.13.1/download" + ], + "strip_prefix": "regex-1.13.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"regex\",\n deps = [\n \"@crates__aho-corasick-1.1.5//:aho_corasick\",\n \"@crates__memchr-2.8.3//:memchr\",\n \"@crates__regex-automata-0.4.18//:regex_automata\",\n \"@crates__regex-syntax-0.8.11//:regex_syntax\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"perf\",\n \"perf-backtrack\",\n \"perf-cache\",\n \"perf-dfa\",\n \"perf-inline\",\n \"perf-literal\",\n \"perf-onepass\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.13.1\",\n)\n" + } + }, + "crates__regex-automata-0.4.18": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/regex-automata/0.4.18/download" + ], + "strip_prefix": "regex-automata-0.4.18", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"regex_automata\",\n deps = [\n \"@crates__aho-corasick-1.1.5//:aho_corasick\",\n \"@crates__memchr-2.8.3//:memchr\",\n \"@crates__regex-syntax-0.8.11//:regex_syntax\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"alloc\",\n \"dfa-onepass\",\n \"hybrid\",\n \"meta\",\n \"nfa-backtrack\",\n \"nfa-pikevm\",\n \"nfa-thompson\",\n \"perf-inline\",\n \"perf-literal\",\n \"perf-literal-multisubstring\",\n \"perf-literal-substring\",\n \"std\",\n \"syntax\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex-automata\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.4.18\",\n)\n" + } + }, + "crates__regex-syntax-0.8.11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/regex-syntax/0.8.11/download" + ], + "strip_prefix": "regex-syntax-0.8.11", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"regex_syntax\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=regex-syntax\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.8.11\",\n)\n" + } + }, + "crates__rustc_version-0.4.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/rustc_version/0.4.1/download" + ], + "strip_prefix": "rustc_version-0.4.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"rustc_version\",\n deps = [\n \"@crates__semver-1.0.28//:semver\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=rustc_version\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.4.1\",\n)\n" + } + }, + "crates__ryu-1.0.23": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/ryu/1.0.23/download" + ], + "strip_prefix": "ryu-1.0.23", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"ryu\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=ryu\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.23\",\n)\n" + } + }, + "crates__semver-1.0.28": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/semver/1.0.28/download" + ], + "strip_prefix": "semver-1.0.28", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"semver\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=semver\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.28\",\n)\n" + } + }, + "crates__serde-1.0.229": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde/1.0.229/download" + ], + "strip_prefix": "serde-1.0.229", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"serde\",\n deps = [\n \"@crates__serde-1.0.229//:build_script_build\",\n \"@crates__serde_core-1.0.229//:serde_core\",\n ],\n proc_macro_deps = [\n \"@crates__serde_derive-1.0.229//:serde_derive\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"derive\",\n \"rc\",\n \"serde_derive\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.229\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"derive\",\n \"rc\",\n \"serde_derive\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"serde\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.229\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__serde_core-1.0.229": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_core/1.0.229/download" + ], + "strip_prefix": "serde_core-1.0.229", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"serde_core\",\n deps = [\n \"@crates__serde_core-1.0.229//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"rc\",\n \"result\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_core\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.229\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"rc\",\n \"result\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"serde_core\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_core\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.229\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__serde_derive-1.0.229": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_derive/1.0.229/download" + ], + "strip_prefix": "serde_derive-1.0.229", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"serde_derive\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-3.0.5//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_derive\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.229\",\n)\n" + } + }, + "crates__serde_json-1.0.151": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_json/1.0.151/download" + ], + "strip_prefix": "serde_json-1.0.151", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"serde_json\",\n deps = [\n \"@crates__itoa-1.0.18//:itoa\",\n \"@crates__memchr-2.8.3//:memchr\",\n \"@crates__serde_core-1.0.229//:serde_core\",\n \"@crates__serde_json-1.0.151//:build_script_build\",\n \"@crates__zmij-1.0.23//:zmij\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_json\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.151\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n \"std\",\n ],\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"serde_json\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_json\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.151\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__serde_yaml-0.9.34-deprecated": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/serde_yaml/0.9.34+deprecated/download" + ], + "strip_prefix": "serde_yaml-0.9.34+deprecated", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"serde_yaml\",\n deps = [\n \"@crates__indexmap-2.14.2//:indexmap\",\n \"@crates__itoa-1.0.18//:itoa\",\n \"@crates__ryu-1.0.23//:ryu\",\n \"@crates__serde-1.0.229//:serde\",\n \"@crates__unsafe-libyaml-0.2.11//:unsafe_libyaml\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=serde_yaml\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.9.34+deprecated\",\n)\n" + } + }, + "crates__strsim-0.11.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/strsim/0.11.1/download" + ], + "strip_prefix": "strsim-0.11.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"strsim\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2015\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=strsim\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.11.1\",\n)\n" + } + }, + "crates__syn-2.0.119": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/syn/2.0.119/download" + ], + "strip_prefix": "syn-2.0.119", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"syn\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__unicode-ident-1.0.24//:unicode_ident\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"clone-impls\",\n \"default\",\n \"derive\",\n \"parsing\",\n \"printing\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=syn\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"2.0.119\",\n)\n" + } + }, + "crates__syn-3.0.5": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/syn/3.0.5/download" + ], + "strip_prefix": "syn-3.0.5", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"syn\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__unicode-ident-1.0.24//:unicode_ident\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"clone-impls\",\n \"default\",\n \"derive\",\n \"full\",\n \"parsing\",\n \"printing\",\n \"proc-macro\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=syn\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"3.0.5\",\n)\n" + } + }, + "crates__termcolor-1.4.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/termcolor/1.4.1/download" + ], + "strip_prefix": "termcolor-1.4.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"termcolor\",\n deps = select({\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__winapi-util-0.1.11//:winapi_util\", # cfg(windows)\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=termcolor\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.4.1\",\n)\n" + } + }, + "crates__thiserror-1.0.69": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/thiserror/1.0.69/download" + ], + "strip_prefix": "thiserror-1.0.69", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"thiserror\",\n deps = [\n \"@crates__thiserror-1.0.69//:build_script_build\",\n ],\n proc_macro_deps = [\n \"@crates__thiserror-impl-1.0.69//:thiserror_impl\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=thiserror\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.69\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"thiserror\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=thiserror\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.69\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + }, + "crates__thiserror-impl-1.0.69": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/thiserror-impl/1.0.69/download" + ], + "strip_prefix": "thiserror-impl-1.0.69", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_proc_macro\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_proc_macro(\n name = \"thiserror_impl\",\n deps = [\n \"@crates__proc-macro2-1.0.107//:proc_macro2\",\n \"@crates__quote-1.0.47//:quote\",\n \"@crates__syn-2.0.119//:syn\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=thiserror-impl\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.69\",\n)\n" + } + }, + "crates__ucd-trie-0.1.7": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/ucd-trie/0.1.7/download" + ], + "strip_prefix": "ucd-trie-0.1.7", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"ucd_trie\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"std\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=ucd-trie\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.1.7\",\n)\n" + } + }, + "crates__unicode-ident-1.0.24": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/unicode-ident/1.0.24/download" + ], + "strip_prefix": "unicode-ident-1.0.24", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"unicode_ident\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=unicode-ident\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.24\",\n)\n" + } + }, + "crates__unsafe-libyaml-0.2.11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/unsafe-libyaml/0.2.11/download" + ], + "strip_prefix": "unsafe-libyaml-0.2.11", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"unsafe_libyaml\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=unsafe-libyaml\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.2.11\",\n)\n" + } + }, + "crates__utf8parse-0.2.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/utf8parse/0.2.2/download" + ], + "strip_prefix": "utf8parse-0.2.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"utf8parse\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2018\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=utf8parse\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.2.2\",\n)\n" + } + }, + "crates__winapi-util-0.1.11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/winapi-util/0.1.11/download" + ], + "strip_prefix": "winapi-util-0.1.11", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"winapi_util\",\n deps = select({\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [\n \"@crates__windows-sys-0.61.2//:windows_sys\", # cfg(windows)\n ],\n \"//conditions:default\": [],\n }),\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=winapi-util\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.1.11\",\n)\n" + } + }, + "crates__windows-link-0.2.1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/windows-link/0.2.1/download" + ], + "strip_prefix": "windows-link-0.2.1", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"windows_link\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=windows-link\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.2.1\",\n)\n" + } + }, + "crates__windows-sys-0.61.2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/windows-sys/0.61.2/download" + ], + "strip_prefix": "windows-sys-0.61.2", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\"@rules_rust//cargo:defs.bzl\", \"cargo_toml_env_vars\")\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"windows_sys\",\n deps = [\n \"@crates__windows-link-0.2.1//:windows_link\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_features = [\n \"Win32\",\n \"Win32_Foundation\",\n \"Win32_Storage\",\n \"Win32_Storage_FileSystem\",\n \"Win32_System\",\n \"Win32_System_Console\",\n \"Win32_System_SystemInformation\",\n \"default\",\n ],\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=windows-sys\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"0.61.2\",\n)\n" + } + }, + "crates__zmij-1.0.23": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "patch_args": [], + "patch_tool": "", + "patches": [], + "remote_patch_strip": 1, + "sha256": "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b", + "type": "tar.gz", + "urls": [ + "https://static.crates.io/crates/zmij/1.0.23/download" + ], + "strip_prefix": "zmij-1.0.23", + "build_file_content": "###############################################################################\n# @generated\n# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To \n# regenerate this file, run the following:\n#\n# bazel mod show_repo 'score_tooling'\n###############################################################################\n\nload(\n \"@rules_rust//cargo:defs.bzl\",\n \"cargo_build_script\",\n \"cargo_toml_env_vars\",\n)\n\nload(\"@rules_rust//rust:defs.bzl\", \"rust_library\")\n\n# buildifier: disable=bzl-visibility\nload(\"@rules_rust//crate_universe/private:selects.bzl\", \"selects\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\ncargo_toml_env_vars(\n name = \"cargo_toml_env_vars\",\n src = \"Cargo.toml\",\n)\n\nrust_library(\n name = \"zmij\",\n deps = [\n \"@crates__zmij-1.0.23//:build_script_build\",\n ],\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_root = \"src/lib.rs\",\n edition = \"2021\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=zmij\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n target_compatible_with = select({\n \"@rules_rust//rust/platform:aarch64-apple-darwin\": [],\n \"@rules_rust//rust/platform:aarch64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:wasm32-unknown-unknown\": [],\n \"@rules_rust//rust/platform:wasm32-wasip1\": [],\n \"@rules_rust//rust/platform:x86_64-pc-windows-msvc\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-linux-gnu\": [],\n \"@rules_rust//rust/platform:x86_64-unknown-nixos-gnu\": [],\n \"//conditions:default\": [\"@platforms//:incompatible\"],\n }),\n version = \"1.0.23\",\n)\n\ncargo_build_script(\n name = \"_bs\",\n compile_data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \"**/*.rs\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n crate_name = \"build_script_build\",\n crate_root = \"build.rs\",\n data = glob(\n allow_empty = True,\n include = [\"**\"],\n exclude = [\n \"**/* *\",\n \".tmp_git_root/**/*\",\n \"BUILD\",\n \"BUILD.bazel\",\n \"WORKSPACE\",\n \"WORKSPACE.bazel\",\n ],\n ),\n edition = \"2021\",\n pkg_name = \"zmij\",\n rustc_env_files = [\n \":cargo_toml_env_vars\",\n ],\n rustc_flags = [\n \"--cap-lints=allow\",\n ],\n srcs = glob(\n allow_empty = True,\n include = [\"**/*.rs\"],\n ),\n tags = [\n \"cargo-bazel\",\n \"crate-name=zmij\",\n \"manual\",\n \"noclippy\",\n \"norustfmt\",\n ],\n version = \"1.0.23\",\n visibility = [\"//visibility:private\"],\n)\n\nalias(\n name = \"build_script_build\",\n actual = \":_bs\",\n tags = [\"manual\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_cc+", + "cc_compatibility_proxy", + "rules_cc++compatibility_proxy+cc_compatibility_proxy" + ], + [ + "rules_cc+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_cc++compatibility_proxy+cc_compatibility_proxy", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_rust+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_rust+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_rust+", + "cargo_bazel_bootstrap", + "rules_rust++cu_nr+cargo_bazel_bootstrap" + ], + [ + "rules_rust+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "rules_rust", + "rules_rust+" + ] + ] + } + }, + "@@rules_rust+//crate_universe/private:internal_extensions.bzl%cu_nr": { + "general": { + "bzlTransitiveDigest": "Z7p+lTI47yj/ZpgLpEKob+c3lW+QLrMSpbG4Qo89LIo=", + "usagesDigest": "1ieIYuafZ1pmP+ncVvISMfB3Em0hv9LCmCRwIH7gL8E=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "cargo_bazel_bootstrap": { + "repoRuleId": "@@rules_rust+//cargo/private:cargo_bootstrap.bzl%cargo_bootstrap_repository", + "attributes": { + "srcs": [ + "@@rules_rust+//crate_universe:src/api.rs", + "@@rules_rust+//crate_universe:src/api/lockfile.rs", + "@@rules_rust+//crate_universe:src/cli.rs", + "@@rules_rust+//crate_universe:src/cli/generate.rs", + "@@rules_rust+//crate_universe:src/cli/query.rs", + "@@rules_rust+//crate_universe:src/cli/render.rs", + "@@rules_rust+//crate_universe:src/cli/splice.rs", + "@@rules_rust+//crate_universe:src/cli/vendor.rs", + "@@rules_rust+//crate_universe:src/config.rs", + "@@rules_rust+//crate_universe:src/context.rs", + "@@rules_rust+//crate_universe:src/context/crate_context.rs", + "@@rules_rust+//crate_universe:src/context/platforms.rs", + "@@rules_rust+//crate_universe:src/lib.rs", + "@@rules_rust+//crate_universe:src/lockfile.rs", + "@@rules_rust+//crate_universe:src/main.rs", + "@@rules_rust+//crate_universe:src/metadata.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_bin.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_resolver.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.bat", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.sh", + "@@rules_rust+//crate_universe:src/metadata/dependency.rs", + "@@rules_rust+//crate_universe:src/metadata/metadata_annotation.rs", + "@@rules_rust+//crate_universe:src/rendering.rs", + "@@rules_rust+//crate_universe:src/rendering/template_engine.rs", + "@@rules_rust+//crate_universe:src/rendering/templates/module_bzl.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/header.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/aliases_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/deps_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_git.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_http.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/vendor_module.j2", + "@@rules_rust+//crate_universe:src/rendering/verbatim/alias_rules.bzl", + "@@rules_rust+//crate_universe:src/select.rs", + "@@rules_rust+//crate_universe:src/splicing.rs", + "@@rules_rust+//crate_universe:src/splicing/cargo_config.rs", + "@@rules_rust+//crate_universe:src/splicing/crate_index_lookup.rs", + "@@rules_rust+//crate_universe:src/splicing/splicer.rs", + "@@rules_rust+//crate_universe:src/test.rs", + "@@rules_rust+//crate_universe:src/utils.rs", + "@@rules_rust+//crate_universe:src/utils/starlark.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/glob.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/label.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_dict.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_list.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_scalar.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_set.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/serialize.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/target_compatible_with.rs", + "@@rules_rust+//crate_universe:src/utils/symlink.rs", + "@@rules_rust+//crate_universe:src/utils/target_triple.rs" + ], + "binary": "cargo-bazel", + "cargo_lockfile": "@@rules_rust+//crate_universe:Cargo.lock", + "cargo_toml": "@@rules_rust+//crate_universe:Cargo.toml", + "version": "1.86.0", + "timeout": 900, + "rust_toolchain_cargo_template": "@rust_host_tools//:bin/{tool}", + "rust_toolchain_rustc_template": "@rust_host_tools//:bin/{tool}", + "compressed_windows_toolchain_names": false + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [ + "cargo_bazel_bootstrap" + ], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_cc+", + "cc_compatibility_proxy", + "rules_cc++compatibility_proxy+cc_compatibility_proxy" + ], + [ + "rules_cc+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_cc++compatibility_proxy+cc_compatibility_proxy", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_rust+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_rust+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_rust+", + "cargo_bazel_bootstrap", + "rules_rust++cu_nr+cargo_bazel_bootstrap" + ], + [ + "rules_rust+", + "cui", + "rules_rust++cu+cui" + ], + [ + "rules_rust+", + "rrc", + "rules_rust++i2+rrc" + ], + [ + "rules_rust+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "rules_rust", + "rules_rust+" + ] + ] + } + }, + "@@rules_swift+//swift:extensions.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "6axDCXf6fQoPav8hojnUBxGA0FAMqLvtpC1cRsisCdw=", + "usagesDigest": "mhACFnrdMv9Wi0Mt67bxocJqviRkDSV+Ee5Mqdj5akA=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_apple_swift_protobuf": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-protobuf/archive/1.20.2.tar.gz" + ], + "sha256": "3fb50bd4d293337f202d917b6ada22f9548a0a0aed9d9a4d791e6fbd8a246ebb", + "strip_prefix": "swift-protobuf-1.20.2/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_protobuf/BUILD.overlay" + } + }, + "com_github_grpc_grpc_swift": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/grpc/grpc-swift/archive/1.16.0.tar.gz" + ], + "sha256": "58b60431d0064969f9679411264b82e40a217ae6bd34e17096d92cc4e47556a5", + "strip_prefix": "grpc-swift-1.16.0/", + "build_file": "@@rules_swift+//third_party:com_github_grpc_grpc_swift/BUILD.overlay" + } + }, + "com_github_apple_swift_docc_symbolkit": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-docc-symbolkit/archive/refs/tags/swift-5.10-RELEASE.tar.gz" + ], + "sha256": "de1d4b6940468ddb53b89df7aa1a81323b9712775b0e33e8254fa0f6f7469a97", + "strip_prefix": "swift-docc-symbolkit-swift-5.10-RELEASE", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_docc_symbolkit/BUILD.overlay" + } + }, + "com_github_apple_swift_nio": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio/archive/2.42.0.tar.gz" + ], + "sha256": "e3304bc3fb53aea74a3e54bd005ede11f6dc357117d9b1db642d03aea87194a0", + "strip_prefix": "swift-nio-2.42.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_http2": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-http2/archive/1.26.0.tar.gz" + ], + "sha256": "f0edfc9d6a7be1d587e5b403f2d04264bdfae59aac1d74f7d974a9022c6d2b25", + "strip_prefix": "swift-nio-http2-1.26.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_http2/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_transport_services": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-transport-services/archive/1.15.0.tar.gz" + ], + "sha256": "f3498dafa633751a52b9b7f741f7ac30c42bcbeb3b9edca6d447e0da8e693262", + "strip_prefix": "swift-nio-transport-services-1.15.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_transport_services/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_extras": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-extras/archive/1.4.0.tar.gz" + ], + "sha256": "4684b52951d9d9937bb3e8ccd6b5daedd777021ef2519ea2f18c4c922843b52b", + "strip_prefix": "swift-nio-extras-1.4.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_extras/BUILD.overlay" + } + }, + "com_github_apple_swift_log": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-log/archive/1.4.4.tar.gz" + ], + "sha256": "48fe66426c784c0c20031f15dc17faf9f4c9037c192bfac2f643f65cb2321ba0", + "strip_prefix": "swift-log-1.4.4/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_log/BUILD.overlay" + } + }, + "com_github_apple_swift_nio_ssl": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-nio-ssl/archive/2.23.0.tar.gz" + ], + "sha256": "4787c63f61dd04d99e498adc3d1a628193387e41efddf8de19b8db04544d016d", + "strip_prefix": "swift-nio-ssl-2.23.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_ssl/BUILD.overlay" + } + }, + "com_github_apple_swift_collections": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-collections/archive/1.0.4.tar.gz" + ], + "sha256": "d9e4c8a91c60fb9c92a04caccbb10ded42f4cb47b26a212bc6b39cc390a4b096", + "strip_prefix": "swift-collections-1.0.4/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_collections/BUILD.overlay" + } + }, + "com_github_apple_swift_atomics": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/apple/swift-atomics/archive/1.1.0.tar.gz" + ], + "sha256": "1bee7f469f7e8dc49f11cfa4da07182fbc79eab000ec2c17bfdce468c5d276fb", + "strip_prefix": "swift-atomics-1.1.0/", + "build_file": "@@rules_swift+//third_party:com_github_apple_swift_atomics/BUILD.overlay" + } + }, + "build_bazel_rules_swift_index_import": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@rules_swift+//third_party:build_bazel_rules_swift_index_import/BUILD.overlay", + "canonical_id": "index-import-5.8", + "urls": [ + "https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz" + ], + "sha256": "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15" + } + }, + "build_bazel_rules_swift_local_config": { + "repoRuleId": "@@rules_swift+//swift/internal:swift_autoconfiguration.bzl%swift_autoconfiguration", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_swift+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_swift+", + "build_bazel_rules_swift", + "rules_swift+" + ] + ] + } + }, + "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_ext": { + "general": { + "bzlTransitiveDigest": "9k8SLwP4ec9xXjFivq0Kn0FradTQhcEA+j/WsLxfVPM=", + "usagesDigest": "1G+0hoRkZx33aQUiAxx8GdGErOPGCHHQXn5lO7fZxgI=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "ferrocene_x86_64_unknown_linux_gnu_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_x86_64_unknown_linux_gnu", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ] + } + }, + "ferrocene_aarch64_unknown_linux_gnu_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_aarch64_unknown_linux_gnu", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ] + } + }, + "ferrocene_x86_64_pc_nto_qnx800_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_x86_64_pc_nto_qnx800", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx" + ] + } + }, + "ferrocene_aarch64_unknown_nto_qnx800_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_aarch64_unknown_nto_qnx800", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx" + ] + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_ext": { + "general": { + "bzlTransitiveDigest": "9k8SLwP4ec9xXjFivq0Kn0FradTQhcEA+j/WsLxfVPM=", + "usagesDigest": "ANsCxJ1KIL4fXiEiWcWT5l5bMcnUM7xjtLQrHfOO6G4=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "ferrocene_x86_64_unknown_linux_gnu": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "sha256": "6fd7c7053a80463b2bfd24202de02e16959b18ed185c55b738148e9caac42eff", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "x86_64-unknown-linux-gnu", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lstdc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "miri_sysroot_sha256": "143260fe3873249160d57b370717005828e129d3b6782448a32d8cc578384fe0", + "miri_sysroot_strip_prefix": "x86_64-unknown-linux-gnu" + } + }, + "ferrocene_aarch64_unknown_linux_gnu": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-linux-gnu.tar.gz", + "sha256": "06ee88a935083068325b69028e9d4e9adc696542cea9b4322642a55dafcae552", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "aarch64-unknown-linux-gnu", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lstdc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc", + "-Clink-arg=-lgcc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-linux-gnu.tar.gz", + "miri_sysroot_sha256": "4059e74c79147b942eb595c14a5f998ebdb1063764ea756b4f32c21bf5903a16", + "miri_sysroot_strip_prefix": "aarch64-unknown-linux-gnu" + } + }, + "ferrocene_x86_64_pc_nto_qnx800": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-pc-nto-qnx800.tar.gz", + "sha256": "655ad0d212baf63f4dd03065735ca55cddadc86cf6bd005aeb19689e348a0023", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "x86_64-pc-nto-qnx800", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-pc-nto-qnx800.tar.gz", + "miri_sysroot_sha256": "9684ea089c883a0739f402165fc6aa374a69641e763957c314688779e8124931", + "miri_sysroot_strip_prefix": "x86_64-pc-nto-qnx800" + } + }, + "ferrocene_aarch64_unknown_nto_qnx800": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-nto-qnx800.tar.gz", + "sha256": "a8e80da21c6abebfb31063f3815cd3a4bbb5a1466855a12043d7c243ef152715", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "aarch64-unknown-nto-qnx800", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-nto-qnx800.tar.gz", + "miri_sysroot_sha256": "3077170b7384d6bcf2cf8f53db8b670d48fc7e2237285b4fd799c64e7412bdff", + "miri_sysroot_strip_prefix": "aarch64-unknown-nto-qnx800" + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@yq.bzl+//yq:extensions.bzl%yq": { + "general": { + "bzlTransitiveDigest": "61Uz+o5PnlY0jJfPZEUNqsKxnM/UCLeWsn5VVCc8u5Y=", + "usagesDigest": "1CP5kLHwnlFZ3obmnV0eEOp+80JltkcSimeCHXe8/+E=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "yq_darwin_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "darwin_amd64", + "version": "4.45.1" + } + }, + "yq_darwin_arm64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "darwin_arm64", + "version": "4.45.1" + } + }, + "yq_linux_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_amd64", + "version": "4.45.1" + } + }, + "yq_linux_arm64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_arm64", + "version": "4.45.1" + } + }, + "yq_linux_s390x": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_s390x", + "version": "4.45.1" + } + }, + "yq_linux_riscv64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_riscv64", + "version": "4.45.1" + } + }, + "yq_linux_ppc64le": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_ppc64le", + "version": "4.45.1" + } + }, + "yq_windows_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "windows_amd64", + "version": "4.45.1" + } + }, + "yq_toolchains": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:toolchain.bzl%yq_toolchains_repo", + "attributes": { + "user_repository_name": "yq" + } + } + }, + "recordedRepoMappingEntries": [] + } + } + }, + "facts": {} +} diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..9c933ea --- /dev/null +++ b/NOTICE @@ -0,0 +1,38 @@ + + +# Notices for Eclipse Safe Open Vehicle Core + +This content is produced and maintained by the Eclipse Safe Open Vehicle Core project. + + * Project home: https://projects.eclipse.org/projects/automotive.score + +## Trademarks + +Eclipse, and the Eclipse Logo are registered trademarks of the Eclipse Foundation. + +## Copyright + +All content is the property of the respective authors or their employers. +For more information regarding authorship of content, please consult the +listed source code repository logs. + +## Declared Project Licenses + +This program and the accompanying materials are made available under the terms +of the Apache License Version 2.0 which is available at +https://www.apache.org/licenses/LICENSE-2.0. + +SPDX-License-Identifier: Apache-2.0 + +## Cryptography + +Content may contain encryption software. The country in which you are currently +may have restrictions on the import, possession, and use, and/or re-export to +another country, of encryption software. BEFORE using any encryption software, +please check the country's laws, regulations and policies concerning the import, +possession, or use, and re-export of encryption software, to see if this is +permitted. diff --git a/README.md b/README.md index 180c738..b7484c1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,76 @@ -# coverage_tool -LLVM source-based code coverage pipeline for Eclipse S-CORE (Bazel module score_coverage) + + +# coverage_tool — Bazel module `score_coverage` + +LLVM source-based code coverage pipeline for Eclipse S-CORE: one +`bazel coverage` run gives one line and branch coverage report for C++ and +Rust, untested in-scope files at exact 0 %, reviewed justifications with an +effective-coverage metric, and a CI threshold gate. + +The tool is developed as a software tool under the S-CORE tool-management +process (ISO 26262-8 clause 11). It is the successor of +`@score_tooling//coverage`. + +## Documentation + +The documentation is docs-as-code under [`docs/`](docs/) and published at +: + +- **User manual** — adoption guide (six steps), command reference, + [constraints of use](docs/manual/constraints.rst) and + [known problems](docs/manual/known_problems.rst). +- **Requirements** — use cases, potential errors (HazOp style) and the tool + requirements the tests verify. +- **Architecture** — the two-phase pipeline and the module/consumer split. +- **Verification report** — test inventory, structural coverage of the tool, + static analysis, end-to-end validation, deviations. + +Build it locally with `bazel run //docs:docs` (output in `docs/_build/`) or +`bazel run //docs:live_preview`. + +## Quick start + +```bash +bazel coverage --config=llvm_cov //... --build_tests_only +bazel run @score_coverage//:generate_coverage_html -- \ + --yaml tools/coverage/coverage_justifications.yaml --archive-dir coverage_artifact +``` + +Exit codes: `0` gate passed, `1` gate failed, `2` no verdict possible. + +## Repository layout + +- `defs.bzl`, `BUILD` — the public API (`score_coverage_scope`, + `score_coverage_reporter`, `//:merger`, `//:generate_coverage_html`, + `//:enable_llvm_coverage_for_death_tests`). The root package loads only + runtime dependencies so it stays loadable for consumers. +- `score_coverage/` — implementation (Python report tooling, Starlark rules) and + unit tests, including Starlark analysis tests. +- `integration_tests/` — a self-contained consumer workspace (C++ + Rust) + exercised end to end by `run_integration_test.sh` against a hand-derived + ground truth (`expected_lcov.dat`); also the reference for the adoption guide. +- `tools/` — repository hygiene (copyright, format, lint aspects) and the + self-coverage gate. +- `docs/` — the docs-as-code tree. + +## Development + +```bash +bazel test //score_coverage/... //tools/... # unit + analysis tests +bazel build --config=lint //score_coverage/... //tools/... # ruff, pylint, ty +bazel coverage --combined_report=lcov //score_coverage/tests:all +bazel run //tools:self_coverage_gate -- --min-lines 95 --min-branches 87 +integration_tests/run_integration_test.sh # end-to-end (downloads LLVM + Ferrocene) +bazel run //tools:format.fix && bazel run //tools:copyright.check +``` diff --git a/defs.bzl b/defs.bzl new file mode 100644 index 0000000..ce5b882 --- /dev/null +++ b/defs.bzl @@ -0,0 +1,90 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Public API of the score_coverage LLVM source-based coverage pipeline. + +Consumers instantiate two targets in their own repository (typically in a +tools/coverage/BUILD file): + + load("@score_coverage//:defs.bzl", + "score_coverage_reporter", "score_coverage_scope") + + score_coverage_scope( + name = "coverage_scope", + testonly = True, + deps = ["//src/mylib", "//src/rust/mycrate"], + ) + + score_coverage_reporter( + name = "reporter_wrapper", + testonly = True, + coverage_scope = ":coverage_scope", + llvm_cov = "@llvm_toolchain//:llvm-cov", + llvm_profdata = "@llvm_toolchain//:llvm-profdata", + llvm_cxxfilt = "@llvm_toolchain_llvm//:bin/llvm-cxxfilt", + ) + +and point Bazel at them from their coverage bazelrc config: + + coverage:llvm_cov --coverage_output_generator=@score_coverage//:merger + coverage:llvm_cov --coverage_report_generator=//tools/coverage:reporter_wrapper + +See README.md for the complete adoption guide (toolchains, bazelrc, +justifications, CI) and COVERAGE_GUIDE.md for how the pipeline works. +""" + +load("//score_coverage:coverage_scope.bzl", _coverage_scope = "coverage_scope") +load("//score_coverage:reporter_wrapper.bzl", _reporter_wrapper = "reporter_wrapper") + +score_coverage_scope = _coverage_scope + +def score_coverage_reporter( + name, + coverage_scope, + llvm_cov, + llvm_profdata, + llvm_cxxfilt = None, + module_bazel = "//:MODULE.bazel", + **kwargs): + """Declare the consumer-side coverage report generator. + + The generated executable is passed to Bazel as + --coverage_report_generator=//:. It wires the consumer's + coverage scope, workspace root and LLVM tools into score_coverage's + reporter. + + Args: + name: Target name, referenced by --coverage_report_generator. + coverage_scope: A score_coverage_scope target listing the production + targets that define the coverage scope. + llvm_cov: Label of the llvm-cov binary (the consumer's LLVM toolchain, + e.g. "@llvm_toolchain//:llvm-cov"). Must come from the same LLVM + major version that produced the coverage instrumentation. + llvm_profdata: Label of the llvm-profdata binary. + llvm_cxxfilt: Optional label of llvm-cxxfilt for symbol demangling + (C++ Itanium and Rust v0/legacy). toolchains_llvm exposes it as + "@llvm_toolchain_llvm//:bin/llvm-cxxfilt". + module_bazel: The consumer's root MODULE.bazel, used at runtime to + locate the real workspace root. Requires + exports_files(["MODULE.bazel"]) in the consumer's root BUILD file. + **kwargs: Common rule attributes (testonly, visibility, tags, ...). + """ + _reporter_wrapper( + name = name, + coverage_scope = coverage_scope, + module_bazel = module_bazel, + llvm_cov = llvm_cov, + llvm_profdata = llvm_profdata, + llvm_cxxfilt = llvm_cxxfilt, + **kwargs + ) diff --git a/docs/BUILD b/docs/BUILD new file mode 100644 index 0000000..55c6dd1 --- /dev/null +++ b/docs/BUILD @@ -0,0 +1,27 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@score_docs_as_code//:docs.bzl", "docs") + +# Documentation (docs-as-code). Lives in its own package on purpose: the root +# package must not load from dev dependencies (consumers do not have them). +# Targets: //docs:docs, //docs:incremental, //docs:live_preview, //docs:ide_support. +docs( + external_needs = ["@score_process_description//:needs_json"], + project = "score_coverage", + project_url = "https://eclipse-score.github.io/coverage_tool", + source_dir = ".", + # Only these test.xml files become testcase needs (JUnit results under + # bazel-testlogs/ or tests-report/ at the workspace root). + test_sources = ["score_coverage/tests"], +) diff --git a/docs/architecture/index.rst b/docs/architecture/index.rst new file mode 100644 index 0000000..1353b6a --- /dev/null +++ b/docs/architecture/index.rst @@ -0,0 +1,169 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Architecture +============ + +.. document:: score_coverage architecture + :id: doc__coverage_architecture + :version: 1 + :status: draft + :safety: ASIL_B + :security: NO + :realizes: wp__sw_implementation + +The pipeline replaces Bazel's two coverage hooks, ``--coverage_output_generator`` +and ``--coverage_report_generator``, with its own tools and adds a +justification and gating layer on top. It has two phases. + +.. uml:: + + @startuml + skinparam componentStyle rectangle + package "Phase 1: bazel coverage --config=llvm_cov" { + [Clang / rustc\ncovmap instrumentation] --> [test binaries] + [test binaries] --> (profraw per test) + (profraw per test) --> [merger.py\n--coverage_output_generator] + [merger.py\n--coverage_output_generator] --> (coverage.dat zip\nprofdata + meta.json) + [score_coverage_scope\naspect] --> (allowlist.txt\nobjects.txt) + (coverage.dat zip\nprofdata + meta.json) --> [reporter.py\n--coverage_report_generator] + (allowlist.txt\nobjects.txt) --> [reporter.py\n--coverage_report_generator] + [reporter.py\n--coverage_report_generator] --> (_coverage_report.dat zip\nhtml_report, lcov_report, text_report) + } + package "Phase 2: bazel run //:generate_coverage_html" { + (_coverage_report.dat zip\nhtml_report, lcov_report, text_report) --> [generate_coverage_html.py] + [generate_coverage_html.py] --> [justify.py] + [justify.py] --> (manifest.json) + (manifest.json) --> [effective_coverage.py] + [effective_coverage.py] --> (report.json\nsummary.txt) + [generate_coverage_html.py] --> [coverage_summary.py] + [generate_coverage_html.py] --> (gate verdict\nexit 0 / 1 / 2) + [generate_coverage_html.py] --> (archive dir) + } + @enduml + +Phase 1: collection +------------------- + +The ``llvm_cov`` bazelrc config, copied by the consumer from the integration +workspace, does four things: + +1. **Swaps the compilers.** C++ is compiled with a hermetic Clang/LLVM toolchain + instead of GCC; Rust with the Ferrocene toolchain of ``score_toolchains_rust``, + which has LLVM coverage tools attached. Both emit the same covmap format. +2. **Turns on instrumentation.** ``--experimental_use_llvm_covmap`` plus the + ``coverage`` feature for C++; ``rules_rust`` adds ``-Cinstrument-coverage`` to + rustc once the toolchain declares coverage tools. Runtime counter relocation + (``-mllvm -runtime-counter-relocation`` via the ``cc_feature``, + ``-Cllvm-args=-runtime-counter-relocation`` for Rust) enables continuous mode + so coverage survives abnormal termination. Rust branch regions need + ``-Zcoverage-options=branch`` on a rolling Ferrocene. +3. **Installs the per-test tool.** ``merger.py`` merges the test's ``profraw`` + files with ``llvm-profdata``, records the instrumented objects, and zips both + as the test's ``coverage.dat``. +4. **Installs the final tool.** The consumer's ``score_coverage_reporter`` target + wraps ``reporter.py`` with the scope, workspace root and LLVM tool labels. + The reporter merges all per-test profiles and runs ``llvm-cov`` three times: + ``show`` (HTML), ``export`` (LCOV), ``report`` (text). + +**Scope.** Covmap instruments everything. Filtering happens at report time +through the allowlist written by ``score_coverage_scope``: an aspect walks the +dependency graph from the listed production targets and collects every +in-workspace source file they own. Everything else, test sources, googletest, +external dependencies, is excluded. + +**Baseline.** A file that no test executes produces no profile data. The scope +aspect therefore also collects the compiled archives and executables, and the +reporter runs ``llvm-cov --empty-profile`` over them, so untested files show up +with exact 0 % entries whose denominators come from the compiler's coverage +map. Rust rlibs are expanded into their object members first because their +leading ``lib.rmeta`` member makes ``llvm-cov`` reject the archive. + +Phase 2: report generation and gate +----------------------------------- + +``generate_coverage_html.py`` unpacks the HTML from the zip and, when a +justification YAML is given, calls ``justify.py`` (YAML plus in-code markers to +a manifest of justified lines) and ``effective_coverage.py`` (recolours justified +lines, computes raw and effective figures, flags stale justifications, writes +``report.json`` and ``summary.txt``). The markdown summary is written next, then +the gate compares the unrounded gated percentage against ``COVERAGE_THRESHOLD``. +Optionally the HTML, LCOV, justification report and JUnit XMLs are assembled +into an artifacts tree. + +Exit code 2 is reserved for runs without a verdict, so a broken report, a bad +threshold or a tool failure can never look like a pass. + +Module and consumer split +------------------------- + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Lives in ``@score_coverage`` + - Role + * - ``score_coverage/merger.py`` + - per-test profraw to profdata; C++ ``objects_list.txt`` and Rust ELF + manifest discovery + * - ``score_coverage/reporter.py`` + - final merge, llvm-cov show/export/report, allowlist filtering, + ``--empty-profile`` baselines, rlib expansion, path normalisation + * - ``score_coverage/coverage_scope.bzl`` + - the scope aspect and rule (CcInfo and CrateInfo) + * - ``score_coverage/reporter_wrapper.bzl``, ``defs.bzl`` + - the consumer-facing ``score_coverage_scope`` / ``score_coverage_reporter`` + API + * - ``score_coverage/justify.py``, ``effective_coverage.py``, + ``coverage_summary.py``, ``generate_coverage_html.py`` + - justification, summary and gating layer + * - ``//:enable_llvm_coverage_for_death_tests`` + - ``cc_feature`` for continuous-mode profiling + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Lives in the consumer repository + - Why it cannot move + * - ``score_coverage_scope(deps = [...])`` + - names the repository's production targets + * - ``score_coverage_reporter(...)`` + - carries the repository's LLVM tool labels and workspace root + * - ``coverage_justifications.yaml`` + - reviewed, repository-specific engineering arguments + * - MODULE.bazel toolchain blocks + - LLVM and Ferrocene pins are per-repository decisions + * - the ``coverage:llvm_cov`` bazelrc block + - bazelrc cannot be imported across modules + +Two wiring details make the external hosting work: every path in the generated +reporter launcher uses rlocation form because it mixes files from the consumer +(``_main``), ``score_coverage`` and toolchain repositories, and the baseline +manifest is resolved against ``_main`` explicitly because its entries are +consumer files. + +Design decisions +---------------- + +- **Report-time filtering, not instrumentation filtering.** Instrumenting + everything and filtering by allowlist is what makes exact 0 % baselines + possible; ``--instrumentation_filter`` would hide untested files. +- **Fail loud, never fail green.** Every input problem ends in exit 2. The gate + compares unrounded values and floors displayed percentages. +- **Gate on the LCOV, not on llvm-cov's text summary.** The text summary omits + baseline-only files; the LCOV includes them. +- **In-process tool calls.** ``generate_coverage_html`` imports the justification + tools instead of nesting ``bazel run``; this keeps one process, one exit code + and testable seams. diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..9911690 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,50 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +score_coverage +============== + +``score_coverage`` is the LLVM source-based code coverage pipeline of Eclipse +S-CORE: one ``bazel coverage`` run produces one line and branch coverage report +for C++ and Rust, lists every in-scope file that no test executes at exactly +0 %, tracks reviewed justifications in an effective-coverage metric and gates +CI on a threshold. + +The tool produces the structural-coverage evidence (statement and branch +coverage, C0 and C1) that S-CORE module verification reports rely on. It is +therefore developed and documented as a software tool under the S-CORE +tool-management process (ISO 26262-8, clause 11); its Tool Verification Report +lives in the S-CORE platform documentation and links here. + +.. toctree:: + :maxdepth: 2 + :caption: Contents + + manual/index + requirements/index + architecture/index + verification/index + release/index + +Quick reference +--------------- + +.. code-block:: bash + + bazel coverage --config=llvm_cov //... --build_tests_only + bazel run @score_coverage//:generate_coverage_html -- \ + --yaml tools/coverage/coverage_justifications.yaml --archive-dir coverage_artifact + +Exit codes of ``generate_coverage_html``: ``0`` gate passed, ``1`` gate failed, +``2`` no verdict possible (broken input, invalid threshold, tool failure). diff --git a/docs/manual/constraints.rst b/docs/manual/constraints.rst new file mode 100644 index 0000000..714024a --- /dev/null +++ b/docs/manual/constraints.rst @@ -0,0 +1,118 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +.. _coverage_constraints: + +Constraints of use +================== + +The correctness of the coverage figures depends on the environment and on how +the tool is invoked. Each constraint below mitigates one of the potential errors +in :doc:`../requirements/potential_errors`; the Tool Verification Report refers +to them by their anchors. + +.. _cstr_coverage_environment: + +CSTR-01 Qualified environment +----------------------------- + +Use the tool only in the environment it was validated in: Linux x86_64 host, +Bazel 8.6, ``toolchains_llvm`` 1.8.0 with LLVM 22.1.7 for C++, the standard +Ferrocene toolchain of ``score_toolchains_rust`` 0.10.0 or newer (built by +``ferrocene_toolchain_builder`` 1.3.1 or newer) for Rust. QNX on-target coverage +is outside this environment. Mitigates ERR-08. + +.. _cstr_coverage_scope_list: + +CSTR-02 Maintain the scope list +------------------------------- + +List every shipped production library or binary in ``score_coverage_scope``. +A target missing from the list is not reported at all, not even at 0 %. Add +new libraries when they are created; document exclusions in writing next to the +target. For large repositories, run a completeness check comparing the +reachable universe against the scope. Mitigates ERR-01. + +.. _cstr_coverage_build_tests_only: + +CSTR-03 Run coverage with ``--build_tests_only`` +------------------------------------------------ + +Always invoke ``bazel coverage --config=llvm_cov --build_tests_only``. +Without the flag Bazel builds manual-tagged or incompatible test binaries, which +fails or pollutes the run. Mitigates ERR-08. + +.. _cstr_coverage_toolchain_config: + +CSTR-04 Do not combine with other toolchain configs +--------------------------------------------------- + +Never combine ``--config=llvm_cov`` with a config that registers another C++ +toolchain (for example a GCC host config). The last ``--extra_toolchains`` wins +resolution; a GCC toolchain produces no covmap data and the run is rejected +with exit 2. Mitigates ERR-08. + +.. _cstr_coverage_dynamic_mode: + +CSTR-05 Keep ``--dynamic_mode=off`` +----------------------------------- + +The canonical ``llvm_cov`` config disables dynamic linking. Per-test shared +objects can carry clashing instrumentation between production and test code, +and the first object loaded wins, causing flaky coverage gaps. Mitigates ERR-02. + +.. _cstr_coverage_lockfile: + +CSTR-06 Pin dependencies +------------------------ + +Run CI with ``--lockfile_mode=error`` so the LLVM and Ferrocene versions that +produced the evidence cannot drift silently. Mitigates ERR-08 and ERR-09. + +.. _cstr_coverage_review_justifications: + +CSTR-07 Review justifications +----------------------------- + +A justification is a reviewed engineering argument. Every entry in the YAML +needs an id, a category, the platforms it applies to and a written reason, and +every change to the YAML or to ``COV_JUSTIFIED`` markers is reviewed like code. +Remove justifications the report flags as stale. Mitigates ERR-04 and ERR-05. + +.. _cstr_coverage_check_baselines: + +CSTR-08 Check the baseline entries +---------------------------------- + +When a file is known to be untested, confirm it appears in the LCOV +(``coverage_report.dat``) with an ``SF:`` record and ``LH:0``. If an expected +file is missing entirely, the baseline mechanism is broken; stop and diagnose +instead of accepting the percentage. Mitigates ERR-01 and ERR-07. + +.. _cstr_coverage_archive: + +CSTR-09 Archive the report with the verification report +------------------------------------------------------- + +Use ``--archive-dir`` and upload the directory as the CI artifact. The archived +``coverage_report.dat`` and ``justification_report/`` are the evidence a module +verification report cites; the HTML alone is not sufficient. Mitigates ERR-09. + +.. _cstr_coverage_exit_codes: + +CSTR-10 Treat exit code 2 as a failed run +----------------------------------------- + +Exit code 2 means the tool could not produce a verdict. CI must fail on it +exactly like on exit code 1. Never map it to a pass. Mitigates ERR-03. diff --git a/docs/manual/index.rst b/docs/manual/index.rst new file mode 100644 index 0000000..faeec19 --- /dev/null +++ b/docs/manual/index.rst @@ -0,0 +1,23 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +User manual +=========== + +.. toctree:: + :maxdepth: 2 + + user_manual + constraints + known_problems diff --git a/docs/manual/known_problems.rst b/docs/manual/known_problems.rst new file mode 100644 index 0000000..c418afc --- /dev/null +++ b/docs/manual/known_problems.rst @@ -0,0 +1,68 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Known problems +============== + +Known problems of the current release, with detection and workaround. Entries +are removed when a release fixes them; problems in the underlying LLVM tools +stay listed with their upstream references. + +.. list-table:: + :header-rows: 1 + :widths: 25 35 40 + + * - Problem + - Detection + - Workaround / status + * - **Per-instantiation counting in llvm-cov.** Template-heavy C++ files can + show lower line coverage than under gcov; ``LF``/``LH`` totals may + disagree with the file's own ``DA`` rows. + - Compare the per-file summary with the ``DA`` rows of the LCOV. + - Upstream behaviour (llvm-project #93843, #111743, #119299). The error is + towards **under**-reporting; numbers are reported as llvm-cov produces + them. + * - **Rust branch coverage needs an unstable rustc flag.** + ``-Zcoverage-options=branch`` works on rolling (nightly-based) Ferrocene + builds only. + - Rust rows show ``-`` in the branch columns. + - On a stable-channel Ferrocene drop the flag; Rust branch coverage is then + not available. + * - **Clang warns where GCC does not.** Repositories with + ``treat_warnings_as_errors`` fail to compile under the coverage config. + - ``-Werror`` failures only under ``--config=llvm_cov``. + - Add ``--features=-treat_warnings_as_errors`` and + ``--host_features=-treat_warnings_as_errors`` to the coverage config. + * - **Containerised tests produce no coverage.** Instrumented binaries inside + stock containers lack runtime dependencies and profraw files never reach + the host. + - Exit 127 in the test log; no profraw. + - Exclude containerised or system tests from the coverage run; they keep + running in the regular test jobs. + * - **QNX on-target coverage is not supported by this tool.** The + orchestrator accepts only the LLVM zip report. The gcovr-based HTML + post-processing exists but is reachable only through the consumer-side + flow of the ``communication`` repository (tooling issue #427). + - Exit 2 with ``is not the LLVM pipeline zip report`` on a gcov run. + - Use the Linux host pipeline; QNX centralisation is tracked in tooling + issue #427. + * - **Rust rlib archives are rejected by llvm-cov** because of the leading + ``lib.rmeta`` member. + - ``no coverage data found`` on a Rust archive. + - Handled since the pipeline expands rlibs into their object members; if + seen, the installed version predates the fix. + * - **Instrumentation filter appears ignored.** + - ``--instrumentation_filter`` has no visible effect. + - Expected: ``--experimental_use_llvm_covmap`` instruments everything; + filtering happens at report time through the scope allowlist. diff --git a/docs/manual/user_manual.rst b/docs/manual/user_manual.rst new file mode 100644 index 0000000..39eedc1 --- /dev/null +++ b/docs/manual/user_manual.rst @@ -0,0 +1,268 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Adoption guide +============== + +.. document:: score_coverage user manual + :id: doc__coverage_user_manual + :version: 1 + :status: draft + :safety: ASIL_B + :security: NO + :realizes: wp__sw_development_plan + +What the pipeline provides +-------------------------- + +- **One report for C++ and Rust** (line and branch coverage), produced by + ``llvm-cov`` directly from covmap instrumentation, without gcov or genhtml. +- **Untested in-scope files appear at exact 0 %**: all targets are instrumented + at build time, and the reporter runs ``llvm-cov --empty-profile`` over the + archives of libraries no test links against. The denominators come from the + compiler's own coverage map, not from a source-text heuristic. +- **Justifications**: ``COV_JUSTIFIED`` in-code markers plus a YAML database turn + intentionally uncovered lines into *justified* lines, tracked in an + **effective coverage** metric with stale-justification detection. +- **Gating**: the report generator exits non-zero when the gated coverage is + below ``COVERAGE_THRESHOLD`` (default 100). + +A complete working consumer setup is the ``integration_tests/`` workspace of the +repository; every snippet below is taken from it. + +Components +---------- + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Target + - Purpose + * - ``@score_coverage//:merger`` + - Per-test coverage output generator (profraw to profdata plus object + metadata). Referenced directly from the consumer's bazelrc. + * - ``score_coverage_scope`` (``defs.bzl``) + - Declares which targets are in scope; emits the source allowlist and the + baseline-archive manifest through an aspect. + * - ``score_coverage_reporter`` (``defs.bzl``) + - Consumer-side wrapper wiring scope, workspace root and LLVM tools into + the final report generator. + * - ``@score_coverage//:generate_coverage_html`` + - Orchestration: unpacks the report, applies justifications, writes the + summary, enforces the threshold, optionally archives. + * - ``@score_coverage//:justify``, ``//:effective_coverage``, ``//:coverage_summary`` + - Standalone entry points of the justification and summary layer (called + in-process by ``generate_coverage_html``). + * - ``@score_coverage//:enable_llvm_coverage_for_death_tests`` + - ``cc_feature`` adding ``-mllvm -runtime-counter-relocation`` (continuous + mode profiling for death tests). + +Prerequisites +------------- + +1. A Bzlmod workspace (``MODULE.bazel``). +2. A Linux x86_64 host. The pipeline runs on the host platform; do not combine + it with QNX or other cross-platform configs. +3. For Rust: a Ferrocene toolchain built by ``ferrocene_toolchain_builder`` + 1.3.1 or newer, wired through ``score_toolchains_rust`` 0.10.0 or newer. + Its coverage-tools tarball ships ``llvm-cov`` and ``llvm-profdata`` built + from the same LLVM as ``rustc``. + +Step 1: depend on score_coverage +-------------------------------- + +.. code-block:: starlark + + bazel_dep(name = "score_coverage", version = "") + +Add one line to the **root** ``BUILD`` file so the reporter can locate the +workspace root at runtime: + +.. code-block:: starlark + + exports_files(["MODULE.bazel"]) + +Step 2: declare the coverage toolchains +--------------------------------------- + +.. code-block:: starlark + + bazel_dep(name = "score_toolchains_rust", version = "0.10.0", dev_dependency = True) + bazel_dep(name = "toolchains_llvm", version = "1.8.0", dev_dependency = True) + + llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True) + llvm.toolchain( + cxx_standard = {"": "c++17"}, + extra_known_features = ["@score_coverage//:enable_llvm_coverage_for_death_tests"], + llvm_version = "22.1.7", + stdlib = {"": "stdc++"}, + ) + use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") + +For Rust no coverage-specific toolchain is needed. Register the standard +Ferrocene toolchain as usual: + +.. code-block:: text + + common --extra_toolchains=@score_toolchains_rust//toolchains/ferrocene:ferrocene_x86_64_unknown_linux_gnu + +``rules_rust`` only instruments crates when the ``rust_toolchain`` declares +``llvm_cov``. A Ferrocene toolchain from an older ``score_toolchains_rust``, or a +custom instance without ``coverage_tools_url``, silently produces no Rust +coverage (see :ref:`coverage_constraints`). + +Step 3: declare scope and reporter +---------------------------------- + +In ``tools/coverage/BUILD``: + +.. code-block:: starlark + + load("@score_coverage//:defs.bzl", "score_coverage_reporter", "score_coverage_scope") + + score_coverage_scope( + name = "coverage_scope", + testonly = True, + deps = [ + "//src/mylib", # cc_library + "//src/rust/mycrate", # rust_library + "//src/rust/tool:tool", # rust_binary + ], + ) + + score_coverage_reporter( + name = "reporter_wrapper", + testonly = True, + coverage_scope = ":coverage_scope", + llvm_cov = "@llvm_toolchain//:llvm-cov", + llvm_profdata = "@llvm_toolchain//:llvm-profdata", + llvm_cxxfilt = "@llvm_toolchain_llvm//:bin/llvm-cxxfilt", + ) + +The scope aspect walks the listed targets and their transitive in-workspace +dependencies, collecting source files (allowlist) and compiled archives +(baselines). Everything in scope but untested shows up at 0 %; everything +outside the scope (tests, mocks, external dependencies) is filtered out of the +report. The scope list is the written record of what is covered: a production +library missing from it silently vanishes from the report, so every new +library must be added, and exclusions need a written decision. + +Step 4: import the bazelrc config +--------------------------------- + +Copy the ``coverage:llvm_cov`` block from ``integration_tests/.bazelrc`` into the +repository's bazelrc, directly or via ``import``. Place the import **before** any +``try-import %workspace%/user.bazelrc``: bazelrc resolves last-wins and the local +override file must stay last. The two labels to adapt: + +.. code-block:: text + + coverage:llvm_cov --coverage_output_generator=@score_coverage//:merger + coverage:llvm_cov --coverage_report_generator=//tools/coverage:reporter_wrapper + +Do **not** combine ``--config=llvm_cov`` with configs that append other +``--extra_toolchains`` (for example a GCC host config): the last toolchain wins +resolution and a GCC toolchain produces no covmap data. + +Step 5 (optional): justifications +--------------------------------- + +``tools/coverage/coverage_justifications.yaml``: + +.. code-block:: yaml + + version: 1 + justifications: + - id: hw-unreachable-on-x86 + category: platform_specific + platforms: [linux] + reason: | + ARM-only error path; cannot be exercised by x86 CI. + +Mark the code in place: + +.. code-block:: cpp + + return false; // COV_JUSTIFIED hw-unreachable-on-x86 + + // or a region: + // COV_JUSTIFIED_START hw-unreachable-on-x86 + if (running_on_arm()) { ... } + // COV_JUSTIFIED_STOP + +Valid categories: ``defensive_programming``, ``tool_false_positive``, +``platform_specific``, ``other``. Ids are kebab-case. Justified lines render +orange in the HTML and count as covered in the *effective* metric. A +justification on a line that is meanwhile covered is flagged as **stale**. A +marker whose id is unknown is reported as a warning and does not count. + +Step 6: run it +-------------- + +.. code-block:: bash + + bazel coverage --config=llvm_cov //... --build_tests_only + + bazel run @score_coverage//:generate_coverage_html -- \ + --yaml tools/coverage/coverage_justifications.yaml + + # CI variant: HTML + LCOV + JUnit XMLs for artifact upload, gate at 95 % + COVERAGE_THRESHOLD=95 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml tools/coverage/coverage_justifications.yaml \ + --archive-dir coverage_artifacts + +``--yaml`` is optional: without it, justification processing is skipped and the +gate applies to the **raw** line coverage computed from the LCOV data. +``--build_tests_only`` is mandatory: without it, coverage builds every target +matched by the pattern, including manual-tagged or platform-incompatible test +binaries. + +Inside GitHub Actions a markdown summary is appended to ``GITHUB_STEP_SUMMARY`` +automatically when ``--summary-md`` is absent. The summary is written before the +gate decides the exit code, so a failing gate still leaves it on the run page. + +Command reference +----------------- + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Option + - Effect + * - ``COVERAGE_THRESHOLD=`` + - Minimum gated coverage in percent (default 100). Effective line coverage + with ``--yaml``, raw line coverage without. Must be a number in + ``[0, 100]``; anything else is rejected with exit 2. + * - ``--yaml `` + - Justification YAML, relative to the workspace root. + * - ``--archive-dir `` + - Assemble HTML report, ``coverage_report.dat`` (LCOV), justification + report and JUnit XMLs into ```` for artifact upload. + * - ``--archive `` + - Same content as a local ``.zip`` (do not upload it: upload-artifact + zips again). + * - ``--testlogs-subdir `` + - Subtree of ``bazel-testlogs`` whose ``test.xml`` files are archived. + * - ``--platform linux|qnx`` + - Platform filter for justifications and default output directory + ``coverage_``. + * - ``--summary-md `` + - Write the markdown summary to ```` instead of the step summary. + * - ``output-dir`` + - HTML output directory (default ``coverage_``). + +Exit codes: ``0`` gate passed, ``1`` gate failed, ``2`` no verdict possible +(missing or non-zip report, invalid threshold, justification or tool failure). diff --git a/docs/release/index.rst b/docs/release/index.rst new file mode 100644 index 0000000..9fc326e --- /dev/null +++ b/docs/release/index.rst @@ -0,0 +1,21 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Release +======= + +.. toctree:: + :maxdepth: 2 + + release_notes diff --git a/docs/release/release_notes.rst b/docs/release/release_notes.rst new file mode 100644 index 0000000..6fb298d --- /dev/null +++ b/docs/release/release_notes.rst @@ -0,0 +1,47 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Release notes +============= + +.. document:: score_coverage release notes + :id: doc__coverage_release_notes + :version: 1 + :status: draft + :safety: ASIL_B + :security: NO + :realizes: wp__module_sw_release_note + +0.1.0 (unreleased) +------------------ + +First release as a standalone module, extracted from ``@score_tooling//coverage`` +(tooling commit ``9a61f42``). + +Changes relative to the pipeline in score_tooling 2.2.x: + +- Consumer labels move to the module root: ``@score_coverage//:defs.bzl``, + ``//:merger``, ``//:generate_coverage_html``, + ``//:enable_llvm_coverage_for_death_tests``. +- ``generate_coverage_html`` is Python and returns exit code 2 for runs without + a verdict; the gate compares unrounded percentages; malformed thresholds and + corrupt LCOV data are rejected. +- Justifications match files at path-component boundaries (a justification for + ``bar.cpp`` no longer applies to ``foobar.cpp``). +- gcovr reports: the index totals of gcovr 8.x are read correctly without + ``--lcov``; ``summary.txt`` is written for gcovr reports too. +- The repository-bound ``combined_report`` and ``llvm_profile_wrapper`` helpers + are not part of the module. + +Known problems: see :doc:`../manual/known_problems`. diff --git a/docs/requirements/index.rst b/docs/requirements/index.rst new file mode 100644 index 0000000..712474a --- /dev/null +++ b/docs/requirements/index.rst @@ -0,0 +1,27 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Requirements +============ + +The tool requirements follow the chain the S-CORE tool-management process asks +for: use cases, the potential errors derived from them, and the tool +requirements that mitigate those errors. Tests link to the tool requirements. + +.. toctree:: + :maxdepth: 2 + + use_cases + potential_errors + tool_requirements diff --git a/docs/requirements/potential_errors.rst b/docs/requirements/potential_errors.rst new file mode 100644 index 0000000..1dc06bd --- /dev/null +++ b/docs/requirements/potential_errors.rst @@ -0,0 +1,128 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Potential errors +================ + +Potential errors of the tool, derived from the use cases with the HazOp guide +words *invalid*, *changed*, *more* and *less* applied to inputs, outputs and +actions. The dangerous direction for a coverage tool is always **more coverage +than real**: an error in that direction hides a verification gap. Errors +towards less coverage cost effort but no safety. + +Tool impact is *high* when the error can make a violated structural-coverage +requirement go undetected. *Detection before qualification* describes what a +user could notice without the mitigations; the last column lists the tool +requirements and constraints of use that mitigate the error. + +.. list-table:: + :header-rows: 1 + :widths: 8 32 8 12 40 + + * - Id + - Error + - Impact + - Detection + - Mitigation + * - ERR-01 + - An in-scope file is silently missing from the report (the scope aspect + misses a dependency, a ``select`` branch, or visibility hides a target). + - high + - weak + - :need:`tool_req__coverage_scope_transitive`, + :need:`tool_req__coverage_scope_baseline_objects`, + :need:`tool_req__coverage_report_baseline_zero`, + :ref:`CSTR-02 `, + :ref:`CSTR-08 ` + * - ERR-02 + - A line or branch is reported covered although it was never executed + (stale profile data, wrong object, wrong test merged, clashing + instrumentation of shared objects). + - high + - none + - :need:`tool_req__coverage_merge_profraw`, + :need:`tool_req__coverage_report_merged_profile`, + :need:`tool_req__coverage_validation_ground_truth`, + :ref:`CSTR-05 ` + * - ERR-03 + - The gate passes although the threshold is not met (rounding, parsing, + unset or malformed threshold, tool failure mistaken for a pass). + - high + - none + - :need:`tool_req__coverage_gate_threshold`, + :need:`tool_req__coverage_gate_unrounded`, + :need:`tool_req__coverage_gate_exit_codes`, + :need:`tool_req__coverage_gate_no_verdict`, + :ref:`CSTR-10 ` + * - ERR-04 + - A justification is applied to the wrong lines, to a file with the same + name, or a stale marker is counted as covered. + - high + - weak + - :need:`tool_req__coverage_just_markers`, + :need:`tool_req__coverage_just_unknown_id`, + :need:`tool_req__coverage_eff_stale`, + :need:`tool_req__coverage_eff_path_match`, + :ref:`CSTR-07 ` + * - ERR-05 + - The effective metric overstates coverage (justified and covered lines + double counted, rounding up). + - medium + - weak + - :need:`tool_req__coverage_eff_metric`, + :need:`tool_req__coverage_eff_branch_only` + * - ERR-06 + - Path normalisation maps two source files onto one record. + - medium + - weak + - :need:`tool_req__coverage_report_relative_paths`, + :need:`tool_req__coverage_eff_path_match` + * - ERR-07 + - A Rust rlib is skipped, so its crate appears complete by absence. + - high + - none + - :need:`tool_req__coverage_report_rlib_expansion`, + :need:`tool_req__coverage_validation_ground_truth`, + :ref:`CSTR-08 ` + * - ERR-08 + - The wrong toolchain wins resolution; gcov data is silently mixed in or + dropped. + - high + - weak + - :need:`tool_req__coverage_gate_no_verdict`, + :ref:`CSTR-01 `, + :ref:`CSTR-03 `, + :ref:`CSTR-04 ` + * - ERR-09 + - The report is regenerated from stale data or unpinned tool versions. + - low + - good + - :need:`tool_req__coverage_artifacts`, + :ref:`CSTR-06 `, + :ref:`CSTR-09 ` + * - ERR-10 + - Coverage is reported too low (false gaps). + - none + - good + - Informational; costs review effort only. + +Classification +-------------- + +Tool impact: **yes**. An error in the *more coverage than real* direction lets a +violation of the structural-coverage verification requirement go undetected. +Tool error detection before qualification: **no** for ERR-02, ERR-03 and +ERR-07. The expected tool confidence level is therefore **TCL LOW**, and the +qualification method of the S-CORE process, validation of the software tool, +applies. The evaluation itself is recorded in the Tool Verification Report. diff --git a/docs/requirements/tool_requirements.rst b/docs/requirements/tool_requirements.rst new file mode 100644 index 0000000..c034027 --- /dev/null +++ b/docs/requirements/tool_requirements.rst @@ -0,0 +1,459 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Tool requirements +================= + +Every requirement satisfies a use case or a process requirement and carries the +potential errors it mitigates as tags. The verification report lists the tests +that verify each requirement. + +.. needtable:: Tool requirements overview + :types: tool_req + :columns: id;title;tags;implemented + :style: table + +Scope +----- + +.. tool_req:: Transitive in-workspace sources define the scope + :id: tool_req__coverage_scope_transitive + :version: 1 + :implemented: YES + :tags: scope, ERR-01 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + ``score_coverage_scope`` shall collect, for the listed targets and their + transitive in-workspace dependencies reached through ``deps``, + ``implementation_deps``, ``exported_deps``, ``components`` and + ``implementation``, the checked-in source and header files of ``cc_library`` + and ``rust_library`` targets (``srcs``, ``hdrs``) and the ``CrateInfo`` + sources of ``rust_binary`` targets, and shall write them sorted and + deduplicated, one workspace-relative path per line, to the allowlist file. + +.. tool_req:: External and generated sources are excluded from the scope + :id: tool_req__coverage_scope_excludes + :version: 1 + :implemented: YES + :tags: scope + :safety: QM + :satisfies: stkh_req__coverage__uc_scope_completeness + + ``score_coverage_scope`` shall not list files from external repositories or + generated files in the allowlist. + +.. tool_req:: Baseline objects accompany the scope + :id: tool_req__coverage_scope_baseline_objects + :version: 1 + :implemented: YES + :tags: scope, ERR-01 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + ``score_coverage_scope`` shall list the static archives of in-workspace + ``cc_library`` and ``rust_library`` targets and the coverage-built executable + of ``rust_binary`` targets in the objects file, so the reporter can produce + zero-coverage baselines for files no test links against. + +Collection +---------- + +.. tool_req:: Per-test profiles are merged with llvm-profdata + :id: tool_req__coverage_merge_profraw + :version: 1 + :implemented: YES + :tags: collection, ERR-02 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_unified_report + + For each test, the merger shall merge all ``*.profraw`` files of the test into + one ``profdata`` file with ``llvm-profdata merge --sparse``, record the real + paths of the instrumented objects of the test in ``meta/meta.json``, and + package both into the test's coverage output. Object files come from the + ``objects_list.txt`` entries of the coverage manifest (C++) or from ELF + binaries listed in the manifest (Rust); entries under ``external/`` are + skipped. + +.. tool_req:: A test without instrumentation produces no coverage output + :id: tool_req__coverage_merge_no_data + :version: 1 + :implemented: YES + :tags: collection + :safety: QM + :satisfies: stkh_req__coverage__uc_unified_report + + When a test has no instrumented objects or no ``profraw`` files, the merger + shall exit 0 without writing an output file and shall say so on stderr, so + non-instrumented tests (for example Python tests) do not fail the run. + +.. tool_req:: A missing or failing llvm-profdata fails the test's collection + :id: tool_req__coverage_merge_tool_error + :version: 1 + :implemented: YES + :tags: collection, ERR-02 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + When ``llvm-profdata`` cannot be located through ``LLVM_PROFDATA`` or + ``RUST_LLVM_PROFDATA``, or exits non-zero, the merger shall exit 1 without + writing an output file. + +Report +------ + +.. tool_req:: One merged profile for all tests + :id: tool_req__coverage_report_merged_profile + :version: 1 + :implemented: YES + :tags: report, ERR-02 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_unified_report + + The reporter shall extract the ``profdata`` and object lists of all valid + per-test outputs, skip invalid or empty ones with a warning, merge the + profiles into one, and produce the HTML, LCOV and text reports from that + merged profile and the union of the instrumented objects. + +.. tool_req:: The report is restricted to the scope allowlist + :id: tool_req__coverage_report_allowlist + :version: 1 + :implemented: YES + :tags: report + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + The reporter shall exclude every file with coverage data that is not in the + allowlist from all three report formats. An empty allowlist shall be an + error (exit non-zero), not an empty report. + +.. tool_req:: Untested in-scope files appear at exact 0 % + :id: tool_req__coverage_report_baseline_zero + :version: 1 + :implemented: YES + :tags: report, ERR-01 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + For every allowlisted file that appears in the baseline objects but in no + test binary, the reporter shall run ``llvm-cov`` with ``--empty-profile`` over + the baseline objects and shall include the file in the HTML and LCOV output + with all instrumented lines and branches at zero hits, so that the LCOV + record shows ``LH:0``. + +.. tool_req:: Rust rlib archives are expanded into object members + :id: tool_req__coverage_report_rlib_expansion + :version: 1 + :implemented: YES + :tags: report, ERR-07 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + Before passing baseline archives to ``llvm-cov``, the reporter shall detect + archives with a ``lib.rmeta`` member and replace them by their ``.o`` + members, so that Rust libraries are not rejected as having no coverage data. + +.. tool_req:: A missing baseline object is an error + :id: tool_req__coverage_report_missing_baseline + :version: 1 + :implemented: YES + :tags: report, ERR-01 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_scope_completeness + + When an entry of the baseline objects manifest cannot be resolved to an + existing file, the reporter shall exit non-zero instead of silently dropping + the object. + +.. tool_req:: Report paths are workspace-relative + :id: tool_req__coverage_report_relative_paths + :version: 1 + :implemented: YES + :tags: report, ERR-06 + :safety: QM + :satisfies: stkh_req__coverage__uc_archive + + The reporter shall rewrite the absolute workspace root and the compiler's + ``/proc/self/cwd/`` prefix in LCOV ``SF:`` records and in HTML page titles to + workspace-relative paths, so that the archived report is portable and file + identity does not depend on the machine. + +.. tool_req:: Report contents + :id: tool_req__coverage_report_outputs + :version: 1 + :implemented: YES + :tags: report + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_unified_report + + The reporter's output shall be a zip containing ``html_report/`` (llvm-cov + HTML with branch counts), ``lcov_report/lcov.dat`` (LCOV with line and + branch records) and ``text_report/summary.txt`` (llvm-cov text summary), with + ``llvm-cov`` warnings kept out of the LCOV data. When no valid per-test + output exists, the output shall be an empty zip. + +Justifications +-------------- + +.. tool_req:: Justification YAML is validated + :id: tool_req__coverage_just_yaml + :version: 1 + :implemented: YES + :tags: justification, ERR-04 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + The justification processor shall reject, with exit 1 and a message per + finding, a YAML that is not a mapping with an integer ``version`` and a + ``justifications`` list, or that contains an entry without a kebab-case + string ``id``, a known ``category``, a non-empty list of known ``platforms`` + or a non-blank ``reason``, or with malformed ``locations``. Duplicate ids + shall be rejected. + +.. tool_req:: In-code markers + :id: tool_req__coverage_just_markers + :version: 1 + :implemented: YES + :tags: justification, ERR-04 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + The justification processor shall resolve ``COV_JUSTIFIED `` to the + marker's line and ``COV_JUSTIFIED_START `` / ``COV_JUSTIFIED_STOP`` to the + lines strictly between the markers, in checked-in sources with the + configured extensions, skipping Bazel output directories, and shall combine + them with the explicit ``locations`` of the YAML into a manifest keyed by + workspace-relative file and line. + +.. tool_req:: Unknown marker ids do not justify anything + :id: tool_req__coverage_just_unknown_id + :version: 1 + :implemented: YES + :tags: justification, ERR-04 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + A marker whose id is not in the (platform-filtered) YAML, a ``STOP`` without + ``START`` and a ``START`` without ``STOP`` shall be reported as warnings and + shall justify no line. + +.. tool_req:: Platform filter + :id: tool_req__coverage_just_platform + :version: 1 + :implemented: YES + :tags: justification + :safety: QM + :satisfies: stkh_req__coverage__uc_justifications + + When a platform is given, only justifications listing that platform shall + apply. + +.. tool_req:: Justified locations exist + :id: tool_req__coverage_just_missing_file + :version: 1 + :implemented: YES + :tags: justification, ERR-04 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + A YAML location whose file does not exist shall be reported as an error and + the processor shall exit 1 after writing the manifest. + +Effective coverage +------------------ + +.. tool_req:: Effective coverage metric + :id: tool_req__coverage_eff_metric + :version: 1 + :implemented: YES + :tags: effective, ERR-05 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + Effective line coverage shall be ``(covered + justified) / total`` and + effective branch coverage ``(covered + justified branches) / total branches``, + with the totals taken from the report's own totals (llvm-cov index page, or + the LCOV for gcovr reports), both floored to two decimals, never rounded up. + Raw figures shall be reported alongside. + +.. tool_req:: Stale justifications are reported and not counted + :id: tool_req__coverage_eff_stale + :version: 1 + :implemented: YES + :tags: effective, ERR-04 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + A justified line that is covered in any instantiation and has no uncovered + branch shall be reported as stale and shall not increase the effective + coverage. + +.. tool_req:: Branch-only justifications + :id: tool_req__coverage_eff_branch_only + :version: 1 + :implemented: YES + :tags: effective, ERR-05 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + A justified line that is covered but has a branch direction no instantiation + covers shall count its truly uncovered directions once as justified branches + and shall not count as a justified line. + +.. tool_req:: Justifications match files at path-component boundaries + :id: tool_req__coverage_eff_path_match + :version: 1 + :implemented: YES + :tags: effective, ERR-04, ERR-06 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_justifications + + A justification for a file shall apply to a report page only when the page's + source path equals the justified path or ends with it at a path-component + boundary; ``bar.cpp`` shall not apply to ``foobar.cpp``. + +.. tool_req:: Justified lines are visible in the HTML + :id: tool_req__coverage_eff_html + :version: 1 + :implemented: YES + :tags: effective + :safety: QM + :satisfies: stkh_req__coverage__uc_justifications + + Justified lines shall be restyled in the HTML report with a ``J`` marker, the + justification id and reason as tooltip and a distinct colour, the index page + shall show the effective figures, and stale justifications shall be listed in + ``summary.txt``. + +.. tool_req:: gcovr HTML reports are supported + :id: tool_req__coverage_eff_gcovr + :version: 1 + :implemented: YES + :tags: effective + :safety: QM + :satisfies: stkh_req__coverage__uc_justifications + + The post-processor shall detect gcovr ``--html-details`` reports and apply + the same justification logic to them, reading totals from the LCOV file when + given and from the summary rows of the index page otherwise. + +Gate +---- + +.. tool_req:: Threshold from the environment + :id: tool_req__coverage_gate_threshold + :version: 1 + :implemented: YES + :tags: gate, ERR-03 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + The threshold shall be read from ``COVERAGE_THRESHOLD`` and default to 100 %. + A value that is not a number in ``[0, 100]`` shall be rejected before any + report is produced (exit 2). + +.. tool_req:: Gated metric + :id: tool_req__coverage_gate_metric + :version: 1 + :implemented: YES + :tags: gate, ERR-01 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + With ``--yaml`` the gate shall use the effective line coverage from the + justification report; without it the raw line coverage summed over all + ``LF``/``LH`` records of the LCOV data, so that baseline-only files count. + The llvm-cov text summary, which omits baseline files, shall not be used. + +.. tool_req:: Unrounded comparison + :id: tool_req__coverage_gate_unrounded + :version: 1 + :implemented: YES + :tags: gate, ERR-03 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + The gate shall compare the unrounded percentage with the threshold; a value + that prints as 100.00 but is below 100 shall fail a threshold of 100. + +.. tool_req:: Exit codes + :id: tool_req__coverage_gate_exit_codes + :version: 1 + :implemented: YES + :tags: gate, ERR-03 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + ``generate_coverage_html`` shall exit 0 when the gate passes, 1 when it fails, + and 2 when no verdict is possible. A tool failure shall never end in exit 0. + +.. tool_req:: Broken input yields no verdict + :id: tool_req__coverage_gate_no_verdict + :version: 1 + :implemented: YES + :tags: gate, ERR-03, ERR-08 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_gate + + A missing or non-zip coverage report, a report without ``html_report/``, LCOV + data without instrumented lines, ``LH`` exceeding ``LF``, a missing + justification YAML, a failing justification tool, or a missing + ``summary.txt`` shall end the run with exit 2. + +Summary and archive +------------------- + +.. tool_req:: Summary is written before the verdict + :id: tool_req__coverage_summary_first + :version: 1 + :implemented: YES + :tags: summary + :safety: QM + :satisfies: stkh_req__coverage__uc_summary, gd_req__verification_reporting + + The markdown summary (``--summary-md``, or appended to ``GITHUB_STEP_SUMMARY`` + when the flag is absent) shall be written before the gate decides, so a + failing gate still leaves the summary; the explicit flag shall take + precedence over the environment variable. + +.. tool_req:: Artifacts tree + :id: tool_req__coverage_artifacts + :version: 1 + :implemented: YES + :tags: archive, ERR-09 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_archive, gd_req__verification_report_archiving + + With ``--archive-dir`` the tool shall assemble the HTML report, the LCOV data + as ``coverage_report.dat``, the justification report directory and the + ``test.xml`` files of the selected ``bazel-testlogs`` subtree with their + paths preserved, also when the gate fails; a missing test-logs directory + shall be an error. + +Validation +---------- + +.. tool_req:: Ground-truth validation + :id: tool_req__coverage_validation_ground_truth + :version: 1 + :implemented: YES + :tags: validation, ERR-02, ERR-07 + :safety: ASIL_B + :satisfies: stkh_req__coverage__uc_unified_report, stkh_req__coverage__uc_scope_completeness + + The pipeline shall be validated end to end against a fixture workspace with + C++ and Rust units whose line and branch counts are derived by hand: the + produced LCOV shall match the expected records exactly (``DA``, ``BRDA``, + ``LF``, ``LH``, ``BRF``, ``BRH`` per file), including exact-0 % records for an + untested C++ library and an untested Rust binary. diff --git a/docs/requirements/use_cases.rst b/docs/requirements/use_cases.rst new file mode 100644 index 0000000..1d5531f --- /dev/null +++ b/docs/requirements/use_cases.rst @@ -0,0 +1,101 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Use cases +========= + +The use cases are modelled as stakeholder requirements of the tool user, a +module CI pipeline or a developer on a Linux host. Tool requirements satisfy +them. + +.. stkh_req:: UC1 One report for C++ and Rust + :id: stkh_req__coverage__uc_unified_report + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: ASIL_B + :security: NO + :status: valid + :rationale: Module verification reports need one C0/C1 figure per unit regardless of language. + + The user shall obtain, from one ``bazel coverage`` run, one report with line + and branch coverage for the C++ and Rust units of the module. + +.. stkh_req:: UC2 Untested code is visible + :id: stkh_req__coverage__uc_scope_completeness + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: ASIL_B + :security: NO + :status: valid + :rationale: A file no test executes must not disappear from the evidence; it must count with 0 %. + + The user shall see every source file of the declared coverage scope in the + report, including files that no test links against, with exact 0 % line and + branch coverage for those. + +.. stkh_req:: UC3 Reviewed justifications + :id: stkh_req__coverage__uc_justifications + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: ASIL_B + :security: NO + :status: valid + :rationale: Intentionally uncovered code needs a written, reviewable argument instead of a lowered threshold. + + The user shall be able to justify intentionally uncovered lines with a + reviewed argument, and obtain an effective coverage figure that counts + justified lines as covered while reporting the raw figure alongside. + +.. stkh_req:: UC4 CI gate + :id: stkh_req__coverage__uc_gate + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: ASIL_B + :security: NO + :status: valid + :rationale: The platform quality criteria (85 % QM, 100 % safety) are enforced automatically. + + The user shall be able to fail a CI job when the gated coverage is below a + configured threshold, and shall be able to tell a failed gate from a run + that could not be evaluated. + +.. stkh_req:: UC5 Archived evidence + :id: stkh_req__coverage__uc_archive + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: ASIL_B + :security: NO + :status: valid + :rationale: The module verification report cites the archived LCOV and justification report. + + The user shall be able to archive the HTML report, the LCOV data, the + justification report and the JUnit results of a run as one CI artifact. + +.. stkh_req:: UC6 Job summary + :id: stkh_req__coverage__uc_summary + :version: 1 + :valid_from: v0.1.0 + :reqtype: Functional + :safety: QM + :security: NO + :status: valid + :rationale: Reviewers read the numbers on the workflow page without downloading artifacts. + + The user shall obtain a markdown summary of the run, on the GitHub Actions + step summary or in a file, even when the gate fails. diff --git a/docs/verification/index.rst b/docs/verification/index.rst new file mode 100644 index 0000000..9ff043f --- /dev/null +++ b/docs/verification/index.rst @@ -0,0 +1,21 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Verification +============ + +.. toctree:: + :maxdepth: 2 + + verification_report diff --git a/docs/verification/verification_report.rst b/docs/verification/verification_report.rst new file mode 100644 index 0000000..5f8edb8 --- /dev/null +++ b/docs/verification/verification_report.rst @@ -0,0 +1,187 @@ +.. + # ******************************************************************************* + # Copyright (c) 2026 Contributors to the Eclipse Foundation + # + # See the NOTICE file(s) distributed with this work for additional + # information regarding copyright ownership. + # + # This program and the accompanying materials are made available under the + # terms of the Apache License Version 2.0 which is available at + # https://www.apache.org/licenses/LICENSE-2.0 + # + # SPDX-License-Identifier: Apache-2.0 + # ******************************************************************************* + +Verification report +=================== + +.. document:: score_coverage verification report + :id: doc__coverage_verification_report + :version: 1 + :status: draft + :safety: ASIL_B + :security: NO + :realizes: wp__verification_module_ver_report + +This report is regenerated with every release. It doubles as the qualification +verification report of the tool: the Tool Verification Report in the S-CORE +platform documentation refers to it as the evidence of the validation. + +Scope and environment +--------------------- + +Validated environment: Linux x86_64, Bazel 8.6.0, ``toolchains_llvm`` 1.8.0 +with LLVM 22.1.7, ``score_toolchains_rust`` 0.10.0 (Ferrocene built by +``ferrocene_toolchain_builder`` 1.3.1), Python 3.12 (``rules_python`` 1.8.5), ``rules_rust`` 0.68.2-score. + +Test inventory +-------------- + +.. list-table:: + :header-rows: 1 + :widths: 45 15 40 + + * - Test target + - Cases + - Verifies + * - ``//score_coverage/tests:merger_test`` + - 20 + - merge_profraw, merge_no_data, merge_tool_error + * - ``//score_coverage/tests:reporter_test`` + - 34 + - report_merged_profile, report_allowlist, report_rlib_expansion, + report_missing_baseline, report_relative_paths, report_outputs + * - ``//score_coverage/tests:justify_test`` + - 41 + - just_yaml, just_markers, just_unknown_id, just_platform, + just_missing_file + * - ``//score_coverage/tests:effective_coverage_test`` + - 52 + - eff_metric, eff_stale, eff_branch_only, eff_path_match, eff_html, + eff_gcovr + * - ``//score_coverage/tests:generate_coverage_html_test`` + - 43 + - gate_threshold, gate_metric, gate_unrounded, gate_exit_codes, + gate_no_verdict, summary_first, artifacts + * - ``//score_coverage/tests:coverage_summary_test`` + - 17 + - summary_first + * - ``//score_coverage/tests/starlark:coverage_scope_tests`` (8 analysis tests) + - 8 + - scope_transitive, scope_excludes, scope_baseline_objects + * - ``integration_tests/run_integration_test.sh`` (15 end-to-end checks) + - 15 + - validation_ground_truth, report_baseline_zero, gate_exit_codes, + gate_no_verdict, just_unknown_id, artifacts, summary_first + +Requirement coverage +-------------------- + +The links from test cases to requirements are generated: every unit test class +carries ``@verifies()``, which writes ``PartiallyVerifies``, +``TestType`` and ``DerivationTechnique`` into the JUnit XML of the test run, and +docs-as-code turns the results into ``testcase`` needs with back-links on the +requirements (``testlink`` column below, with the execution result of each +case). The links reflect the test run that preceded the documentation build. + +.. needtable:: Requirements and the tests that verify them + :types: tool_req + :columns: id;title;testlink + :style: table + +Four requirements are verified outside the pytest suites and therefore carry no +generated link: + +- :need:`tool_req__coverage_scope_transitive`, + :need:`tool_req__coverage_scope_excludes` and + :need:`tool_req__coverage_scope_baseline_objects` are verified by the eight + Starlark analysis tests in ``score_coverage/tests/starlark`` (rules_testing + produces no test properties). +- :need:`tool_req__coverage_validation_ground_truth` is verified by the + end-to-end run ``integration_tests/run_integration_test.sh`` (golden LCOV + comparison, see below). + +.. needpie:: Test results of the linked test cases + :labels: passed, failed, skipped + :colors: green, red, orange + + type == 'testcase' and result == 'passed' + type == 'testcase' and result == 'failed' + type == 'testcase' and result == 'skipped' + +Structural coverage of the tool +------------------------------- + +Measured with coverage.py through ``bazel coverage --combined_report=lcov`` and +gated in CI by ``//tools:self_coverage_gate`` (current ratchet 95 % lines, +87 % branches; target 100 % with documented deviations). + +.. list-table:: + :header-rows: 1 + :widths: 40 30 30 + + * - File + - Lines (C0) + - Branches (C1) + * - ``score_coverage/coverage_summary.py`` + - 95.65 % (198/207) + - 88.78 % (87/98) + * - ``score_coverage/effective_coverage.py`` + - 95.09 % (523/550) + - 81.16 % (224/276) + * - ``score_coverage/generate_coverage_html.py`` + - 98.56 % (205/208) + - 92.59 % (75/81) + * - ``score_coverage/justify.py`` + - 98.35 % (238/242) + - 94.56 % (139/147) + * - ``score_coverage/merger.py`` + - 98.35 % (119/121) + - 93.65 % (59/63) + * - ``score_coverage/reporter.py`` + - 91.95 % (354/385) + - 84.97 % (164/193) + * - **Total** + - **95.56 % (1637/1713)** + - **87.18 % (748/858)** + +Static analysis +--------------- + +ruff (rule set of the S-CORE Python guideline: E, W, F, I, B, C90, UP, SIM, +RET; McCabe ceiling 15), pylint and ty run as Bazel aspects with findings +failing the build. Current state: zero findings. buildifier checks the Starlark, +yamlfmt the workflows; copyright headers are checked on every file. + +End-to-end validation +--------------------- + +``integration_tests/run_integration_test.sh`` builds a consumer workspace with a +tested and an untested C++ library, a tested Rust library and an untested Rust +binary, one justified line, and asserts: + +1. the gate fails at 100 % and passes at 10 % (effective and raw mode); +2. the HTML, the summary and the archive tree are produced, the summary also + when the gate fails; +3. the untested C++ file and the untested Rust binary appear with ``LH:0``; +4. the LCOV matches ``expected_lcov.dat``, a hand-derived ground truth, record + by record; +5. the justified line raises effective above raw coverage; +6. fault injection: a corrupt report and a non-numeric threshold exit 2, and a + misspelt justification id is reported and does not raise the effective + coverage. + +Deviations +---------- + +- Structural coverage of the Python is below 100 %. The remaining lines are + error-handling and llvm-cov fallback paths in ``reporter.py`` and + ``effective_coverage.py``; they are covered by the fault-injection checks of + the integration test where they are reachable and will be closed or justified + before the first qualified release. +- Starlark (``coverage_scope.bzl``, ``reporter_wrapper.bzl``) has no structural + coverage tooling. The rule and aspect are verified by eight analysis tests + and by the end-to-end run. +- The gcovr backend of ``effective_coverage.py`` is unit-tested against real + gcovr 8.6 markup but is not reachable through ``generate_coverage_html`` in + this release (QNX flow, tooling issue #427). diff --git a/integration_tests/.bazelrc b/integration_tests/.bazelrc new file mode 100644 index 0000000..22291f9 --- /dev/null +++ b/integration_tests/.bazelrc @@ -0,0 +1,78 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/ +common --registry=https://bcr.bazel.build + +# Rust toolchain for regular builds and coverage alike: score_toolchains_rust's +# standard Ferrocene toolchain ships with llvm-cov/llvm-profdata attached +# (>= 0.10.0), which is what activates Rust coverage instrumentation. +common --extra_toolchains=@score_toolchains_rust//toolchains/ferrocene:ferrocene_x86_64_unknown_linux_gnu + +test --test_output=errors + +# ============================================================================ +# LLVM source-based coverage (Linux, Clang + Ferrocene) — unified Rust + C++ +# This is the CANONICAL consumer snippet: copy this block (adjusting the +# --coverage_report_generator label) into your repository's bazelrc. +# Use with: bazel coverage --config=llvm_cov //... --build_tests_only +# ============================================================================ + +coverage:llvm_cov --nocache_test_results +coverage:llvm_cov --cxxopt=-O0 +coverage:llvm_cov --combined_report=lcov +coverage:llvm_cov --experimental_fetch_all_coverage_outputs + +# Per-test .so files can carry clashing instrumentation between production +# and test code; the first object loaded wins, causing flaky coverage gaps. +# Static linking avoids this entirely. +coverage:llvm_cov --dynamic_mode=off + +coverage:llvm_cov --experimental_generate_llvm_lcov +# NOTE: --experimental_use_llvm_covmap causes Bazel to instrument ALL targets. +# Source filtering is handled at report time using the allowlist generated by +# the score_coverage_scope target. +coverage:llvm_cov --experimental_use_llvm_covmap +coverage:llvm_cov --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux + +# The merger lives in score_coverage (no consumer-specific wiring needed); the +# reporter_wrapper is instantiated in THIS repository (tools/coverage/BUILD) +# because it carries the coverage scope and LLVM tool labels. +coverage:llvm_cov --coverage_output_generator=@score_coverage//:merger +coverage:llvm_cov --coverage_report_generator=//tools/coverage:reporter_wrapper + +# Keep raw profraw files instead of converting to LCOV; the merger handles +# profraw -> profdata directly. +coverage:llvm_cov --test_env=GENERATE_LLVM_LCOV=0 +coverage:llvm_cov --test_env=COVERAGE_GCOV_PATH=/usr/bin/true + +# Continuous-mode profiling: required to cover abnormal termination (death +# tests). Needs runtime counter relocation in both languages. +coverage:llvm_cov --test_env=LLVM_PROFILE_CONTINUOUS_MODE=1 +coverage:llvm_cov --features=enable_llvm_coverage_for_death_tests +coverage:llvm_cov --@rules_rust//rust/settings:extra_rustc_flag=-Cllvm-args=-runtime-counter-relocation + +# Under the LLVM toolchain the `coverage` feature expands to +# -fprofile-instr-generate -fcoverage-mapping — exactly the covmap +# instrumentation this pipeline needs. +coverage:llvm_cov --features=coverage + +# Keep unlinked functions in the coverage map so unreferenced code shows as +# uncovered instead of vanishing. +coverage:llvm_cov --@rules_rust//rust/settings:extra_rustc_flag=-Clink-dead-code + +# Enable branch coverage instrumentation for Rust. NOTE: -Z flags are +# unstable rustc options; they work here because the Ferrocene toolchain in +# use is a rolling (nightly-based) build. If you pin a stable-channel +# Ferrocene release, drop this flag (losing the Rust branch column). +coverage:llvm_cov --@rules_rust//rust/settings:extra_rustc_flag=-Zcoverage-options=branch diff --git a/integration_tests/.bazelversion b/integration_tests/.bazelversion new file mode 100644 index 0000000..acd405b --- /dev/null +++ b/integration_tests/.bazelversion @@ -0,0 +1 @@ +8.6.0 diff --git a/integration_tests/BUILD b/integration_tests/BUILD new file mode 100644 index 0000000..047af1d --- /dev/null +++ b/integration_tests/BUILD @@ -0,0 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Required by score_coverage_reporter: the reporter locates the real +# workspace root at runtime through the MODULE.bazel runfile. +exports_files(["MODULE.bazel"]) diff --git a/integration_tests/MODULE.bazel b/integration_tests/MODULE.bazel new file mode 100644 index 0000000..5d2f65a --- /dev/null +++ b/integration_tests/MODULE.bazel @@ -0,0 +1,68 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +# Integration test workspace for the score_coverage LLVM coverage pipeline. +# This module mirrors EXACTLY what a consumer repository has to declare — +# its MODULE.bazel, .bazelrc and tools/coverage/BUILD are the reference +# implementation for the adoption guide in //:README.md. +module(name = "coverage_integration_tests") + +bazel_dep(name = "score_coverage", version = "0.1.0") +local_path_override( + module_name = "score_coverage", + path = "..", +) + +bazel_dep(name = "platforms", version = "1.0.0") +bazel_dep(name = "rules_cc", version = "0.2.17") +bazel_dep(name = "rules_python", version = "1.8.5") +bazel_dep(name = "rules_rust", version = "0.68.2-score") + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + is_default = True, + python_version = "3.12", +) + +# ******************************************************************************* +# Coverage toolchains (only active during `bazel coverage --config=llvm_cov`) +# ******************************************************************************* + +bazel_dep(name = "score_toolchains_rust", version = "0.10.0", dev_dependency = True) +bazel_dep(name = "toolchains_llvm", version = "1.8.0", dev_dependency = True) + +# C++ LLVM/Clang toolchain used for coverage builds (source-based covmap). +llvm = use_extension( + "@toolchains_llvm//toolchain/extensions:llvm.bzl", + "llvm", + dev_dependency = True, +) +llvm.toolchain( + cxx_standard = {"": "c++17"}, + extra_known_features = [ + # Provided by score_coverage; enables runtime counter relocation for + # continuous-mode profiling (death test coverage). + "@score_coverage//:enable_llvm_coverage_for_death_tests", + ], + llvm_version = "22.1.7", + stdlib = {"": "stdc++"}, +) +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") + +# NOTE: no custom Ferrocene instance is needed for Rust coverage. The +# standard toolchains shipped by score_toolchains_rust >= 0.10.0 already +# attach llvm-cov/llvm-profdata from the ferrocene_toolchain_builder +# coverage-tools tarball (built from the same LLVM as rustc), and +# rules_rust instruments crates under `bazel coverage` whenever the +# rust_toolchain declares llvm_cov. Registration happens in .bazelrc: +# common --extra_toolchains=@score_toolchains_rust//toolchains/ferrocene:ferrocene_x86_64_unknown_linux_gnu diff --git a/integration_tests/MODULE.bazel.lock b/integration_tests/MODULE.bazel.lock new file mode 100644 index 0000000..2d25a5a --- /dev/null +++ b/integration_tests/MODULE.bazel.lock @@ -0,0 +1,1373 @@ +{ + "lockFileVersion": 24, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/apple_support/1.17.1/MODULE.bazel": "655c922ab1209978a94ef6ca7d9d43e940cd97d9c172fb55f94d91ac53f8610b", + "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", + "https://bcr.bazel.build/modules/apple_support/1.24.1/MODULE.bazel": "f46e8ddad60aef170ee92b2f3d00ef66c147ceafea68b6877cb45bd91737f5f8", + "https://bcr.bazel.build/modules/apple_support/1.24.1/source.json": "cf725267cbacc5f028ef13bb77e7f2c2e0066923a4dab1025e4a0511b1ed258a", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.16.0/MODULE.bazel": "852f9ebbda017572a7c113a2434592dd3b2f55cd9a0faea3d4be5a09a59e4900", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/aspect_rules_py/1.4.0/MODULE.bazel": "6fd29b93207a31445d5d3ab9d9882fd5511e43c95e8e82e7492872663720fd44", + "https://bcr.bazel.build/modules/aspect_rules_py/1.4.0/source.json": "fb1ba946478fb6dbb26d49307d756b0fd2ff88be339af23c39c0397d59143d2c", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", + "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", + "https://bcr.bazel.build/modules/bazel_features/1.38.0/MODULE.bazel": "f9b8a9c890ebd216b4049fd12a31d3c2602e3403c7af636b04fbbd7453edc9c9", + "https://bcr.bazel.build/modules/bazel_features/1.38.0/source.json": "31ba776c122b54a2885e23651642e32f087a87bf025465f8040751894b571277", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/source.json": "7051768079aa19302df2b9446ad0889839fd08b7d59851eba2c99234d665c9ba", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildifier_prebuilt/7.3.1/MODULE.bazel": "537faf0ad9f5892910074b8e43b4c91c96f1d5d86b6ed04bdbe40cf68aa48b68", + "https://bcr.bazel.build/modules/buildifier_prebuilt/8.2.0.2/MODULE.bazel": "a9b689711d5b69f9db741649b218c119b9fdf82924ba390415037e09798edd03", + "https://bcr.bazel.build/modules/buildifier_prebuilt/8.2.0.2/source.json": "51eb0a4b38aaaeab7fa64361576d616c4d8bfd0f17a0a10184aeab7084d79f8e", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/helly25_bzl/0.4.3/MODULE.bazel": "9c20052fd3f1fb767c48b78c1bbc46f501a4ca69d14558429d1234e68e449f68", + "https://bcr.bazel.build/modules/helly25_bzl/0.4.3/source.json": "e8c54d81e72633fb6f1d23c7e2d44e0b39b1caef2a256141136a2f63e6204b78", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/source.json": "e53a759a72488d2c0576f57491ef2da0cf4aab05ac0997314012495935531b73", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", + "https://bcr.bazel.build/modules/rules_java/8.15.1/MODULE.bazel": "5071eebf0fd602ab0617f846e0e0d8f388d66c961513c736e0ac4a1dcde3ff2c", + "https://bcr.bazel.build/modules/rules_java/8.15.1/source.json": "e48286d5819767bc5b3d457539ae7f94e28a9b3e55d092d5c47176cb6a2a289b", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_multitool/1.11.1/MODULE.bazel": "f826d2d394e8d964e44ebb4a75ebcfe4e9cd4eb150e2ddcd60398ffeb939696a", + "https://bcr.bazel.build/modules/rules_multitool/1.11.1/source.json": "201f43de1d35bd17f25a4fed3ba5a2ec500ef5e08b7d4b341bb9fd39cef0cbc6", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.1.0/MODULE.bazel": "9db8031e71b6ef32d1846106e10dd0ee2deac042bd9a2de22b4761b0c3036453", + "https://bcr.bazel.build/modules/rules_pkg/1.1.0/source.json": "fef768df13a92ce6067e1cd0cdc47560dace01354f1d921cfb1d632511f7d608", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.8.5/MODULE.bazel": "28b2d79ed8368d7d45b34bacc220e3c0b99cbcd9392641961b849e4c3f55dd30", + "https://bcr.bazel.build/modules/rules_python/1.8.5/source.json": "e261b03c8804f2582c9536013f987e1ea105a2b38c238aa2ac8f98fc34c8b18a", + "https://bcr.bazel.build/modules/rules_rust/0.56.0/MODULE.bazel": "3295b00757db397122092322fe1e920be7f5c9fbfb8619138977e820f2cbbbae", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/sphinxdocs/2.2.0/MODULE.bazel": "e046c573919d72605d62c352a08d9223a10aafef3a7cb70d0fe253ebdd97019e", + "https://bcr.bazel.build/modules/sphinxdocs/2.2.0/source.json": "b1da19a3d14a1dd8aa6a9ccaedc42bbe0313c8160a77ba5cca336cca1315298d", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/source.json": "4a620381df075a16cb3a7ed57bd1d05f7480222394c64a20fa51bdb636fda658", + "https://bcr.bazel.build/modules/toolchains_llvm/1.8.0/MODULE.bazel": "68259b66e5fb84f94fa37125ad476c3eb8edf602a34bf58377cde9a16dd8fa98", + "https://bcr.bazel.build/modules/toolchains_llvm/1.8.0/source.json": "70d80fe5b626a3fadf812af41dda4a028640a1184f5a3c7e6cb20130d93ed783", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20210324.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20211102.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230125.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20230802.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/abseil-cpp/20240116.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.17.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/apple_support/1.24.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.16.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/aspect_rules_py/1.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.10.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.15.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.17.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.18.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.21.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.30.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.32.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.34.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.38.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_features/1.9.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/bazel_skylib/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/7.3.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildifier_prebuilt/8.2.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/buildozer/7.1.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/google_benchmark/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/googletest/1.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/helly25_bzl/0.4.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jq.bzl/0.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/jsoncpp/1.9.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/libpfm/4.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/package_metadata/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/0.0.9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/platforms/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/27.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0-rc2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0-rc3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/29.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/protobuf/3.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/pybind11_bazel/2.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/re2/2023-09-01/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_android/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.13/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.14/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.15/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.17/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.0.9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.17/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_fuzzing/0.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/5.3.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/6.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.10.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.12.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/7.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.15.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_java/8.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/4.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_jvm_external/6.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_kotlin/1.9.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/0.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_license/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_multitool/1.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/6.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_proto/7.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.10.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.25.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.29.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.31.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/0.40.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_python/1.8.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.56.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.68.2-score/MODULE.bazel": "37be8dee6df19d666c1d4266e1266d82012aa83bd82de38b3100fd7f641d064b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_rust/0.68.2-score/source.json": "f88ad98dd08f296a546677e86ad42b20f61851e41a9fd3e0449971162fcaf784", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_shell/0.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_platforms/0.0.3/MODULE.bazel": "14c96e378c08705a46abe0799d6236fe3095c342c34f83f8d1b3f6046ce00651", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_platforms/0.0.3/source.json": "1a853ab23455388d550a9aecf3d8b53ec73de50e7fe2914d9269a3c698bf3624", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_devcontainer/1.11.0/MODULE.bazel": "fb6041c96e949a151307b4690ee81cf5d9254d6bf79540184b16567b04397171", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_devcontainer/1.11.0/source.json": "b379a2499cf06f16de65c2981665c3723afba9e858ed16b453f044882067f56f", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.0.1/MODULE.bazel": "446b0462f893021e3133b2f95672ae37dfe2ade434b6052c91530043e4d89993", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.1.1/MODULE.bazel": "4740f5e4229753b2ec023df5ce9c24c3472ad1e6d700a970e3e96f7347e65a1b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_docs_as_code/8.1.1/source.json": "189c748d57a732e0653af377bb7635253ed7fc135f33c2f107c4d8a4a17259c5", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_process_description/2.1.2/MODULE.bazel": "1076b36d2d05ab1a18df0746f6a545869eec6927019d651af99d99ef056e2023", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_process_description/2.1.2/source.json": "f76099f076243e2641803971e2a95ed27f24756c9bdda5d10a808c664996f0fc", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.10.0/MODULE.bazel": "535296e6cdef55a506c580ca2ce541aa9ddefb354de1a24ab2bd4addc939282b", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_toolchains_rust/0.10.0/source.json": "8bda773be264da16d2a82a03ebb737421dd4a35855f1e9a5d03d9722d84c1df5", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/sphinxdocs/2.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.5.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.6.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/stardoc/0.7.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/tar.bzl/0.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/tar.bzl/0.6.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/toolchains_llvm/1.8.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/yq.bzl/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.2.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/zlib/1.3.1/MODULE.bazel": "not found" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@aspect_rules_py+//py:extensions.bzl%py_tools": { + "general": { + "bzlTransitiveDigest": "uh/OnBspuZDYzeAio/cE3jPFXYyt5/s0JxMJ1pkhoMo=", + "usagesDigest": "NC1b49l5tenTBVWEUGzzC0j5Kg1GH+l5lBw5JRCldIU=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "bsd_tar_darwin_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "bsd_tar_darwin_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_linux_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "bsd_tar_linux_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "bsd_tar_windows_amd64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "bsd_tar_windows_arm64": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_arm64" + } + }, + "bsd_tar_toolchains": { + "repoRuleId": "@@aspect_bazel_lib+//lib/private:tar_toolchain.bzl%tar_toolchains_repo", + "attributes": { + "user_repository_name": "bsd_tar" + } + }, + "rules_py_tools.darwin_amd64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "rules_py_tools.darwin_arm64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "rules_py_tools.linux_amd64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "rules_py_tools.linux_arm64": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:tools.bzl%prebuilt_tool_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "rules_py_tools": { + "repoRuleId": "@@aspect_rules_py+//py/private/toolchain:repo.bzl%toolchains_repo", + "attributes": { + "user_repository_name": "rules_py_tools" + } + }, + "rules_py_pex_2_3_1": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "urls": [ + "https://files.pythonhosted.org/packages/e7/d0/fbda2a4d41d62d86ce53f5ae4fbaaee8c34070f75bb7ca009090510ae874/pex-2.3.1-py2.py3-none-any.whl" + ], + "sha256": "64692a5bf6f298403aab930d22f0d836ae4736c5bc820e262e9092fe8c56f830", + "downloaded_file_path": "pex-2.3.1-py2.py3-none-any.whl" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_rules_py+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "aspect_rules_py+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@pybind11_bazel+//:python_configure.bzl%extension": { + "general": { + "bzlTransitiveDigest": "D2/qWHU6yQFwRG7Bb+caqrYMha5avsASao2vERrxK24=", + "usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=", + "recordedFileInputs": { + "@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_python": { + "repoRuleId": "@@pybind11_bazel+//:python_configure.bzl%python_configure", + "attributes": {} + }, + "pybind11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@pybind11_bazel+//:pybind11.BUILD", + "strip_prefix": "pybind11-2.11.1", + "urls": [ + "https://github.com/pybind/pybind11/archive/v2.11.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "pybind11_bazel+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "4LouzhF/yT117s7peGnNs9ROomiJXC6Zl5R0oI21jho=", + "usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "platforms": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz" + ], + "sha256": "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74" + } + }, + "rules_python": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "d70cd72a7a4880f0000a6346253414825c19cdd40a28289bdf67b8e6480edff8", + "strip_prefix": "rules_python-0.28.0", + "url": "https://github.com/bazelbuild/rules_python/releases/download/0.28.0/rules_python-0.28.0.tar.gz" + } + }, + "bazel_skylib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz" + ] + } + }, + "com_google_absl": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240116.1.zip" + ], + "strip_prefix": "abseil-cpp-20240116.1", + "integrity": "sha256-7capMWOvWyoYbUaHF/b+I2U6XLMaHmky8KugWvfXYuk=" + } + }, + "rules_fuzzing_oss_fuzz": { + "repoRuleId": "@@rules_fuzzing+//fuzzing/private/oss_fuzz:repository.bzl%oss_fuzz_repository", + "attributes": {} + }, + "honggfuzz": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@rules_fuzzing+//:honggfuzz.BUILD", + "sha256": "6b18ba13bc1f36b7b950c72d80f19ea67fbadc0ac0bb297ec89ad91f2eaa423e", + "url": "https://github.com/google/honggfuzz/archive/2.5.zip", + "strip_prefix": "honggfuzz-2.5" + } + }, + "rules_fuzzing_jazzer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "ee6feb569d88962d59cb59e8a31eb9d007c82683f3ebc64955fd5b96f277eec2", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer/0.20.1/jazzer-0.20.1.jar" + } + }, + "rules_fuzzing_jazzer_api": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "f5a60242bc408f7fa20fccf10d6c5c5ea1fcb3c6f44642fec5af88373ae7aa1b", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer-api/0.20.1/jazzer-api-0.20.1.jar" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_fuzzing+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "nvW/NrBXlAmiQw99EMGKkLaD2KbNp2mQDlxdfpr+0Ls=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_kotlin+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "TRGIl0CDmorwyNiblOYyhWuyKzi/kWFHT2uIofq7o9Y=", + "usagesDigest": "lDbpRfhoWmZCHSaNxwZv/8fF2y0wu2th0G0f/uqX7VM=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "pypi__build", + "rules_python++config+pypi__build" + ], + [ + "rules_python+", + "pypi__click", + "rules_python++config+pypi__click" + ], + [ + "rules_python+", + "pypi__colorama", + "rules_python++config+pypi__colorama" + ], + [ + "rules_python+", + "pypi__importlib_metadata", + "rules_python++config+pypi__importlib_metadata" + ], + [ + "rules_python+", + "pypi__installer", + "rules_python++config+pypi__installer" + ], + [ + "rules_python+", + "pypi__more_itertools", + "rules_python++config+pypi__more_itertools" + ], + [ + "rules_python+", + "pypi__packaging", + "rules_python++config+pypi__packaging" + ], + [ + "rules_python+", + "pypi__pep517", + "rules_python++config+pypi__pep517" + ], + [ + "rules_python+", + "pypi__pip", + "rules_python++config+pypi__pip" + ], + [ + "rules_python+", + "pypi__pip_tools", + "rules_python++config+pypi__pip_tools" + ], + [ + "rules_python+", + "pypi__pyproject_hooks", + "rules_python++config+pypi__pyproject_hooks" + ], + [ + "rules_python+", + "pypi__setuptools", + "rules_python++config+pypi__setuptools" + ], + [ + "rules_python+", + "pypi__tomli", + "rules_python++config+pypi__tomli" + ], + [ + "rules_python+", + "pypi__wheel", + "rules_python++config+pypi__wheel" + ], + [ + "rules_python+", + "pypi__zipp", + "rules_python++config+pypi__zipp" + ] + ] + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "c4BCoL7WnccEomzDYulDuOys9pd6N93KaNI4mTVbqi0=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "platforms", + "platforms" + ] + ] + } + }, + "@@rules_rust+//crate_universe/private:internal_extensions.bzl%cu_nr": { + "general": { + "bzlTransitiveDigest": "WNUB8qSmmMiopwWLL8yFJfPo7jD6XWsX7vPeKfhaw5A=", + "usagesDigest": "1ieIYuafZ1pmP+ncVvISMfB3Em0hv9LCmCRwIH7gL8E=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "cargo_bazel_bootstrap": { + "repoRuleId": "@@rules_rust+//cargo/private:cargo_bootstrap.bzl%cargo_bootstrap_repository", + "attributes": { + "srcs": [ + "@@rules_rust+//crate_universe:src/api.rs", + "@@rules_rust+//crate_universe:src/api/lockfile.rs", + "@@rules_rust+//crate_universe:src/cli.rs", + "@@rules_rust+//crate_universe:src/cli/generate.rs", + "@@rules_rust+//crate_universe:src/cli/query.rs", + "@@rules_rust+//crate_universe:src/cli/render.rs", + "@@rules_rust+//crate_universe:src/cli/splice.rs", + "@@rules_rust+//crate_universe:src/cli/vendor.rs", + "@@rules_rust+//crate_universe:src/config.rs", + "@@rules_rust+//crate_universe:src/context.rs", + "@@rules_rust+//crate_universe:src/context/crate_context.rs", + "@@rules_rust+//crate_universe:src/context/platforms.rs", + "@@rules_rust+//crate_universe:src/lib.rs", + "@@rules_rust+//crate_universe:src/lockfile.rs", + "@@rules_rust+//crate_universe:src/main.rs", + "@@rules_rust+//crate_universe:src/metadata.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_bin.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_resolver.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.bat", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.sh", + "@@rules_rust+//crate_universe:src/metadata/dependency.rs", + "@@rules_rust+//crate_universe:src/metadata/metadata_annotation.rs", + "@@rules_rust+//crate_universe:src/rendering.rs", + "@@rules_rust+//crate_universe:src/rendering/template_engine.rs", + "@@rules_rust+//crate_universe:src/rendering/templates/module_bzl.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/header.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/aliases_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/deps_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_git.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_http.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/vendor_module.j2", + "@@rules_rust+//crate_universe:src/rendering/verbatim/alias_rules.bzl", + "@@rules_rust+//crate_universe:src/select.rs", + "@@rules_rust+//crate_universe:src/splicing.rs", + "@@rules_rust+//crate_universe:src/splicing/cargo_config.rs", + "@@rules_rust+//crate_universe:src/splicing/crate_index_lookup.rs", + "@@rules_rust+//crate_universe:src/splicing/splicer.rs", + "@@rules_rust+//crate_universe:src/test.rs", + "@@rules_rust+//crate_universe:src/utils.rs", + "@@rules_rust+//crate_universe:src/utils/starlark.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/glob.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/label.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_dict.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_list.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_scalar.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_set.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/serialize.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/target_compatible_with.rs", + "@@rules_rust+//crate_universe:src/utils/symlink.rs", + "@@rules_rust+//crate_universe:src/utils/target_triple.rs" + ], + "binary": "cargo-bazel", + "cargo_lockfile": "@@rules_rust+//crate_universe:Cargo.lock", + "cargo_toml": "@@rules_rust+//crate_universe:Cargo.toml", + "version": "1.86.0", + "timeout": 900, + "rust_toolchain_cargo_template": "@rust_host_tools//:bin/{tool}", + "rust_toolchain_rustc_template": "@rust_host_tools//:bin/{tool}", + "compressed_windows_toolchain_names": false + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [ + "cargo_bazel_bootstrap" + ], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_cc+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_cc+", + "cc_compatibility_proxy", + "rules_cc++compatibility_proxy+cc_compatibility_proxy" + ], + [ + "rules_cc+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_cc++compatibility_proxy+cc_compatibility_proxy", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_rust+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_rust+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_rust+", + "cargo_bazel_bootstrap", + "rules_rust++cu_nr+cargo_bazel_bootstrap" + ], + [ + "rules_rust+", + "cui", + "rules_rust++cu+cui" + ], + [ + "rules_rust+", + "rrc", + "rules_rust++i2+rrc" + ], + [ + "rules_rust+", + "rules_cc", + "rules_cc+" + ], + [ + "rules_rust+", + "rules_rust", + "rules_rust+" + ] + ] + } + }, + "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_ext": { + "general": { + "bzlTransitiveDigest": "9k8SLwP4ec9xXjFivq0Kn0FradTQhcEA+j/WsLxfVPM=", + "usagesDigest": "1G+0hoRkZx33aQUiAxx8GdGErOPGCHHQXn5lO7fZxgI=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "ferrocene_x86_64_unknown_linux_gnu_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_x86_64_unknown_linux_gnu", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ] + } + }, + "ferrocene_aarch64_unknown_linux_gnu_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_aarch64_unknown_linux_gnu", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ] + } + }, + "ferrocene_x86_64_pc_nto_qnx800_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_x86_64_pc_nto_qnx800", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx" + ] + } + }, + "ferrocene_aarch64_unknown_nto_qnx800_rules_rust_miri": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_rules_rust_miri_toolchain_repo", + "attributes": { + "ferrocene_repo_name": "ferrocene_aarch64_unknown_nto_qnx800", + "toolchain_name": "rust_ferrocene", + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx" + ] + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_ext": { + "general": { + "bzlTransitiveDigest": "9k8SLwP4ec9xXjFivq0Kn0FradTQhcEA+j/WsLxfVPM=", + "usagesDigest": "ANsCxJ1KIL4fXiEiWcWT5l5bMcnUM7xjtLQrHfOO6G4=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "ferrocene_x86_64_unknown_linux_gnu": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "sha256": "6fd7c7053a80463b2bfd24202de02e16959b18ed185c55b738148e9caac42eff", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "x86_64-unknown-linux-gnu", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lstdc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "miri_sysroot_sha256": "143260fe3873249160d57b370717005828e129d3b6782448a32d8cc578384fe0", + "miri_sysroot_strip_prefix": "x86_64-unknown-linux-gnu" + } + }, + "ferrocene_aarch64_unknown_linux_gnu": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-linux-gnu.tar.gz", + "sha256": "06ee88a935083068325b69028e9d4e9adc696542cea9b4322642a55dafcae552", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "aarch64-unknown-linux-gnu", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lstdc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc", + "-Clink-arg=-lgcc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:linux" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-linux-gnu.tar.gz", + "miri_sysroot_sha256": "4059e74c79147b942eb595c14a5f998ebdb1063764ea756b4f32c21bf5903a16", + "miri_sysroot_strip_prefix": "aarch64-unknown-linux-gnu" + } + }, + "ferrocene_x86_64_pc_nto_qnx800": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-pc-nto-qnx800.tar.gz", + "sha256": "655ad0d212baf63f4dd03065735ca55cddadc86cf6bd005aeb19689e348a0023", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "x86_64-pc-nto-qnx800", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-pc-nto-qnx800.tar.gz", + "miri_sysroot_sha256": "9684ea089c883a0739f402165fc6aa374a69641e763957c314688779e8124931", + "miri_sysroot_strip_prefix": "x86_64-pc-nto-qnx800" + } + }, + "ferrocene_aarch64_unknown_nto_qnx800": { + "repoRuleId": "@@score_toolchains_rust+//extensions:ferrocene_toolchain_ext.bzl%ferrocene_toolchain_repo", + "attributes": { + "url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/ferrocene-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-nto-qnx800.tar.gz", + "sha256": "a8e80da21c6abebfb31063f3815cd3a4bbb5a1466855a12043d7c243ef152715", + "strip_prefix": "", + "toolchain_name": "rust_ferrocene", + "target_triple": "aarch64-unknown-nto-qnx800", + "exec_triple": "x86_64-unknown-linux-gnu", + "staticlib_ext": ".a", + "dylib_ext": ".so", + "binary_ext": "", + "default_edition": "2021", + "stdlib_linkflags": [], + "extra_rustc_flags": [ + "-Clink-arg=-Wl,--no-as-needed", + "-Clink-arg=-lc++", + "-Clink-arg=-lm", + "-Clink-arg=-lc" + ], + "extra_exec_rustc_flags": [], + "env": {}, + "exec_compatible_with": [ + "@platforms//cpu:x86_64", + "@platforms//os:linux" + ], + "target_compatible_with": [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx" + ], + "coverage_tools_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/coverage-tools-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-x86_64-unknown-linux-gnu.tar.gz", + "coverage_tools_sha256": "9cf5d76b2e505bf2a8b2b47c60f191ac1273f87851ed387e53080b8e5d14dedf", + "coverage_tools_strip_prefix": "779fbed05ae9e9fe2a04137929d99cc9b3d516fd/x86_64-unknown-linux-gnu", + "miri_sysroot_url": "https://github.com/eclipse-score/ferrocene_toolchain_builder/releases/download/1.3.1/miri-sysroot-779fbed05ae9e9fe2a04137929d99cc9b3d516fd-aarch64-unknown-nto-qnx800.tar.gz", + "miri_sysroot_sha256": "3077170b7384d6bcf2cf8f53db8b670d48fc7e2237285b4fd799c64e7412bdff", + "miri_sysroot_strip_prefix": "aarch64-unknown-nto-qnx800" + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@toolchains_llvm+//toolchain/extensions:distributions.bzl%llvm_distributions": { + "general": { + "bzlTransitiveDigest": "gCdXpBt3HBBc280OILOFheHmO7lXWXJYnPgYiTtyapI=", + "usagesDigest": "VyKGZSw79ryPJ9gt0sqBfIkA7qGOU6tnlDHd7awkb6Q=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "llvm_distributions_data": { + "repoRuleId": "@@toolchains_llvm+//toolchain/internal:distributions_repo.bzl%llvm_distributions_repo", + "attributes": { + "srcs": [ + "@@toolchains_llvm+//toolchain/distributions:pre_github.jsonc", + "@@toolchains_llvm+//toolchain/distributions:github_legacy.jsonc", + "@@toolchains_llvm+//toolchain/distributions:github.jsonc", + "@@toolchains_llvm+//toolchain/distributions:extra.jsonc" + ] + } + } + }, + "recordedRepoMappingEntries": [] + } + } + }, + "facts": {} +} diff --git a/integration_tests/expected_lcov.dat b/integration_tests/expected_lcov.dat new file mode 100644 index 0000000..18fbe5c --- /dev/null +++ b/integration_tests/expected_lcov.dat @@ -0,0 +1,97 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +# Ground truth for the integration workspace, derived BY HAND from the fixture +# sources and the tests that run against them (validation evidence for the +# coverage pipeline, ISO 26262-8 11.4.9). Function records (FN*, FNF, FNH) are +# not compared; the pipeline gates on lines and branches. +# +# rust/lib.rs classify() called with -5 and 0 by two tests (each test +# binary runs both #[test] fns => entry lines hit 2x), the +# `positive` arm (22) and never_called (28-30) at 0; the test +# module's own lines (37-44) are instrumented and hit once. +# Branches: 17 (value < 0) both ways, 19 (value == 0) true +# only => 3 of 4. +# src/coverable.cpp classify() called with -5 and 0 => line 24 (`positive`) +# at 0, branch 21 false direction never taken => 3 of 4. +# rust/main.rs no test at all => every line 0 via the empty-profile +# baseline; no branches. +# src/uncovered.cpp no test links against it => all lines 0, both directions +# of the branch on line 18 never executed ('-'). +SF:rust/lib.rs +DA:16,2 +DA:17,2 +DA:18,1 +DA:19,1 +DA:20,1 +DA:22,0 +DA:24,2 +DA:28,0 +DA:29,0 +DA:30,0 +DA:37,1 +DA:38,1 +DA:39,1 +DA:42,1 +DA:43,1 +DA:44,1 +BRDA:17,0,0,1 +BRDA:17,0,1,1 +BRDA:19,0,0,1 +BRDA:19,0,1,0 +BRF:4 +BRH:3 +LF:16 +LH:12 +end_of_record +SF:rust/main.rs +DA:17,0 +DA:18,0 +DA:19,0 +BRF:0 +BRH:0 +LF:3 +LH:0 +end_of_record +SF:src/coverable.cpp +DA:17,2 +DA:18,2 +DA:19,1 +DA:20,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:24,0 +DA:25,1 +BRDA:18,0,0,1 +BRDA:18,0,1,1 +BRDA:21,0,0,1 +BRDA:21,0,1,0 +BRF:4 +BRH:3 +LF:9 +LH:8 +end_of_record +SF:src/uncovered.cpp +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +BRDA:18,0,0,- +BRDA:18,0,1,- +BRF:2 +BRH:0 +LF:6 +LH:0 +end_of_record diff --git a/integration_tests/run_integration_test.sh b/integration_tests/run_integration_test.sh new file mode 100755 index 0000000..73e0693 --- /dev/null +++ b/integration_tests/run_integration_test.sh @@ -0,0 +1,225 @@ +#!/usr/bin/env bash +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +# End-to-end test of the score_coverage LLVM coverage pipeline, run against +# this consumer-style workspace. Asserts the properties the pipeline +# guarantees: +# 1. Untested in-scope files (C++ AND Rust) appear at exact 0% in the LCOV. +# 2. The effective-coverage gate fails at threshold 100 and passes at a low +# threshold. +# 3. The justified line raises effective coverage above raw coverage. + +set -euo pipefail +cd "$(dirname "$0")" + +# In GitHub Actions GITHUB_STEP_SUMMARY is set for THIS job; unset it so the +# many generate_coverage_html invocations below don't each append to the real +# run page. The dedicated summary test sets its own target file. +unset GITHUB_STEP_SUMMARY || true + +echo "=== Running coverage build ===" +bazel coverage --config=llvm_cov //... --build_tests_only + +YAML="tools/coverage/coverage_justifications.yaml" + +echo "=== Gate must FAIL at threshold 100 (uncovered fixtures exist) ===" +if COVERAGE_THRESHOLD=100 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml "${YAML}" --archive coverage_artifacts; then + echo "ERROR: coverage gate passed at threshold 100 despite uncovered files" >&2 + exit 1 +fi +echo "OK: gate failed as expected" + +echo "=== Gate must PASS at a low threshold ===" +COVERAGE_THRESHOLD=10 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml "${YAML}" +echo "OK: gate passed as expected" + +echo "=== Without --yaml: HTML still produced, gate applies to RAW coverage ===" +if COVERAGE_THRESHOLD=100 bazel run @score_coverage//:generate_coverage_html; then + echo "ERROR: raw-coverage gate passed at threshold 100" >&2 + exit 1 +fi +COVERAGE_THRESHOLD=10 bazel run @score_coverage//:generate_coverage_html +if [[ ! -f coverage_linux/index.html ]]; then + echo "ERROR: HTML report missing after no-yaml run" >&2 + exit 1 +fi +echo "OK: no-yaml mode works (HTML produced, raw gate enforced)" + +# The following sections all run, in order. Each one deletes summary.md +# before its own generate_coverage_html invocation so a stale file from the +# previous section cannot produce a false pass — in particular, the +# failing-gate section must prove the file was RE-created by THAT run. +echo "=== --summary-md must produce a markdown job summary ===" +rm -f summary.md +COVERAGE_THRESHOLD=10 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml "${YAML}" --summary-md summary.md +for marker in "## Coverage summary" "| Lines |" "Raw vs effective" \ + "Coverage by directory" "Files at exact 0% (2)"; do + if ! grep -qF "${marker}" summary.md; then + echo "ERROR: '${marker}' missing from summary.md" >&2 + exit 1 + fi +done +grep -q "█" summary.md || { echo "ERROR: progress bars missing from summary.md" >&2; exit 1; } +echo "OK: --summary-md works" + +echo "=== Summary must still be written when the gate FAILS ===" +rm -f summary.md +if COVERAGE_THRESHOLD=100 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml "${YAML}" --summary-md summary.md; then + echo "ERROR: gate unexpectedly passed at threshold 100" >&2 + exit 1 +fi +[[ -s summary.md ]] || { echo "ERROR: summary.md missing after failing gate" >&2; exit 1; } +echo "OK: summary survives a failing gate" + +echo "=== GITHUB_STEP_SUMMARY convenience default (no flag) ===" +rm -f step_summary.md +printf '# existing content\n' > step_summary.md +GITHUB_STEP_SUMMARY="$(pwd)/step_summary.md" COVERAGE_THRESHOLD=10 \ + bazel run @score_coverage//:generate_coverage_html -- --yaml "${YAML}" +grep -qF "# existing content" step_summary.md || { echo "ERROR: append mode overwrote the step summary" >&2; exit 1; } +grep -qF "## Coverage summary" step_summary.md || { echo "ERROR: summary not appended to GITHUB_STEP_SUMMARY" >&2; exit 1; } +rm -f summary.md step_summary.md +echo "OK: GITHUB_STEP_SUMMARY convenience works" + +echo "=== --archive-dir must produce an unzipped artifacts tree ===" +COVERAGE_THRESHOLD=10 bazel run @score_coverage//:generate_coverage_html -- \ + --yaml "${YAML}" --archive-dir artifacts_dir +for f in artifacts_dir/coverage_linux/index.html artifacts_dir/coverage_report.dat \ + artifacts_dir/justification_report/summary.txt; do + if [[ ! -f "$f" ]]; then + echo "ERROR: ${f} missing from --archive-dir output" >&2 + exit 1 + fi +done +rm -rf artifacts_dir +echo "OK: --archive-dir works" + +echo "=== Untested files must appear at exact 0% in the LCOV ===" +unzip -p coverage_artifacts.zip artifacts/coverage_report.dat > lcov.dat + +check_zero_coverage() { + local file="$1" + if ! grep -q "SF:.*${file}" lcov.dat; then + echo "ERROR: ${file} missing from LCOV (baseline mechanism broken)" >&2 + exit 1 + fi + # The record for the file must report zero lines hit. + if ! awk -v f="${file}" ' + $0 ~ "^SF:" && $0 ~ f {rec=1} + rec && /^LH:/ {print $0; exit ($0 == "LH:0") ? 0 : 1} + rec && /^end_of_record/ {exit 1}' lcov.dat; then + echo "ERROR: ${file} is present but not at 0% coverage" >&2 + exit 1 + fi + echo "OK: ${file} present at 0%" +} + +check_zero_coverage "src/uncovered.cpp" +check_zero_coverage "rust/main.rs" + +echo "=== LCOV must match the hand-verified ground truth exactly ===" +# Normalise: drop function records, keep one record per file sorted by SF, so +# the comparison is independent of record order and of symbol names. +normalise_lcov() { + grep -v '^FN' "$1" | awk ' + /^SF:/ { key = $0; rec = "" } + { rec = rec $0 "\n" } + /^end_of_record/ { records[key] = rec } + END { n = asorti(records, keys); for (i = 1; i <= n; i++) printf "%s", records[keys[i]] }' +} +normalise_lcov lcov.dat > actual_normalised.dat +grep -v '^#' expected_lcov.dat | normalise_lcov /dev/stdin > expected_normalised.dat +if ! diff -u expected_normalised.dat actual_normalised.dat; then + echo "ERROR: coverage data differs from expected_lcov.dat (see diff above)" >&2 + exit 1 +fi +rm -f actual_normalised.dat expected_normalised.dat +echo "OK: LCOV matches the ground truth" + +echo "=== Covered files must be present with hits ===" +grep -q "SF:.*src/coverable.cpp" lcov.dat || { echo "ERROR: coverable.cpp missing" >&2; exit 1; } +grep -q "SF:.*rust/lib.rs" lcov.dat || { echo "ERROR: lib.rs missing" >&2; exit 1; } +echo "OK" + +echo "=== Justified line must raise effective coverage above raw ===" +SUMMARY="$(unzip -p coverage_artifacts.zip artifacts/justification_report/summary.txt)" +echo "${SUMMARY}" +JUSTIFIED="$(echo "${SUMMARY}" | grep -oP 'Justified lines:\s+\K[0-9]+')" +if [[ "${JUSTIFIED}" -lt 1 ]]; then + echo "ERROR: expected at least one justified line, got ${JUSTIFIED}" >&2 + exit 1 +fi +RAW="$(echo "${SUMMARY}" | grep -oP 'Raw line coverage:\s+\K[0-9.]+')" +EFFECTIVE="$(echo "${SUMMARY}" | grep -oP 'Effective line coverage:\s+\K[0-9.]+')" +if ! awk "BEGIN {exit (${EFFECTIVE} > ${RAW}) ? 0 : 1}"; then + echo "ERROR: effective coverage ${EFFECTIVE}% not above raw ${RAW}%" >&2 + exit 1 +fi +echo "OK: effective ${EFFECTIVE}% > raw ${RAW}%" + +echo "=== Fault injection: a broken report must yield NO verdict (exit 2), never a pass ===" +REPORT="bazel-out/_coverage/_coverage_report.dat" +cp "${REPORT}" report.backup +chmod u+w "${REPORT}" +printf 'this is not a zip archive' > "${REPORT}" +set +e +COVERAGE_THRESHOLD=0 bazel run @score_coverage//:generate_coverage_html > /dev/null 2>&1 +rc=$? +set -e +cp report.backup "${REPORT}" +rm -f report.backup +if [[ "${rc}" -ne 2 ]]; then + echo "ERROR: corrupt report gave exit code ${rc}, expected 2" >&2 + exit 1 +fi +echo "OK: corrupt report is rejected with exit 2" + +echo "=== Fault injection: a non-numeric threshold must be rejected (exit 2) ===" +set +e +COVERAGE_THRESHOLD=lenient bazel run @score_coverage//:generate_coverage_html > /dev/null 2>&1 +rc=$? +set -e +if [[ "${rc}" -ne 2 ]]; then + echo "ERROR: bad threshold gave exit code ${rc}, expected 2" >&2 + exit 1 +fi +echo "OK: invalid threshold is rejected with exit 2" + +echo "=== Fault injection: an unknown justification id must not count as covered ===" +sed -i 's/itest-positive-branch/itest-typo-branch/' src/coverable.cpp +set +e +COVERAGE_THRESHOLD=10 bazel run @score_coverage//:generate_coverage_html -- --yaml "${YAML}" --archive-dir typo_dir > typo.log 2>&1 +rc=$? +set -e +sed -i 's/itest-typo-branch/itest-positive-branch/' src/coverable.cpp +if [[ "${rc}" -ne 0 ]]; then + cat typo.log + echo "ERROR: run with an unknown marker id failed unexpectedly (${rc})" >&2 + exit 1 +fi +grep -q "references unknown ID 'itest-typo-branch'" typo.log || { echo "ERROR: unknown marker id was not reported" >&2; exit 1; } +TYPO_EFFECTIVE="$(grep -oP 'Effective line coverage:\s+\K[0-9.]+' typo_dir/justification_report/summary.txt)" +TYPO_RAW="$(grep -oP 'Raw line coverage:\s+\K[0-9.]+' typo_dir/justification_report/summary.txt)" +if [[ "${TYPO_EFFECTIVE}" != "${TYPO_RAW}" ]]; then + echo "ERROR: unknown marker id still raised effective (${TYPO_EFFECTIVE}) above raw (${TYPO_RAW})" >&2 + exit 1 +fi +rm -rf typo_dir typo.log +echo "OK: unknown justification id is reported and does not count" + +echo "" +echo "=== All integration checks passed ===" diff --git a/integration_tests/rust/BUILD b/integration_tests/rust/BUILD new file mode 100644 index 0000000..6d05d68 --- /dev/null +++ b/integration_tests/rust/BUILD @@ -0,0 +1,37 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test") + +package(default_visibility = ["//visibility:public"]) + +rust_library( + name = "integration_lib", + srcs = ["lib.rs"], + edition = "2021", +) + +rust_test( + name = "integration_lib_test", + crate = ":integration_lib", + edition = "2021", +) + +# No test runs this binary — its main.rs must show up at exact 0% via the +# --empty-profile baseline over the coverage-built executable. +rust_binary( + name = "untested_tool", + srcs = ["main.rs"], + edition = "2021", + deps = [":integration_lib"], +) diff --git a/integration_tests/rust/lib.rs b/integration_tests/rust/lib.rs new file mode 100644 index 0000000..337ba3f --- /dev/null +++ b/integration_tests/rust/lib.rs @@ -0,0 +1,45 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +/// Classifies an integer. Three branches; the unit test exercises only two so +/// the report is guaranteed to contain covered and uncovered Rust branches. +pub fn classify(value: i32) -> &'static str { + if value < 0 { + "negative" + } else if value == 0 { + "zero" + } else { + "positive" + } +} + +/// Never called by any test: must appear as uncovered (0 hits) in the report +/// thanks to -Clink-dead-code keeping it in the coverage map. +pub fn never_called(value: i32) -> i32 { + value * 2 +} + +#[cfg(test)] +mod tests { + use super::classify; + + #[test] + fn classifies_negative() { + assert_eq!(classify(-5), "negative"); + } + + #[test] + fn classifies_zero() { + assert_eq!(classify(0), "zero"); + } +} diff --git a/integration_tests/rust/main.rs b/integration_tests/rust/main.rs new file mode 100644 index 0000000..a36ecb8 --- /dev/null +++ b/integration_tests/rust/main.rs @@ -0,0 +1,19 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +// This binary has no test at all: its source must appear at exactly 0% in the +// coverage report via the --empty-profile baseline over the coverage-built +// executable (rust_binary targets provide no CcInfo archive). +fn main() { + println!("{}", integration_lib::classify(1)); +} diff --git a/integration_tests/src/BUILD b/integration_tests/src/BUILD new file mode 100644 index 0000000..983b6b1 --- /dev/null +++ b/integration_tests/src/BUILD @@ -0,0 +1,37 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_cc//cc:cc_library.bzl", "cc_library") +load("@rules_cc//cc:cc_test.bzl", "cc_test") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "coverable", + srcs = ["coverable.cpp"], + hdrs = ["coverable.h"], +) + +# No test links against this library — it must show up at exact 0% in the +# report via the --empty-profile baseline. +cc_library( + name = "uncovered", + srcs = ["uncovered.cpp"], + hdrs = ["uncovered.h"], +) + +cc_test( + name = "coverable_test", + srcs = ["coverable_test.cpp"], + deps = [":coverable"], +) diff --git a/integration_tests/src/coverable.cpp b/integration_tests/src/coverable.cpp new file mode 100644 index 0000000..f31b997 --- /dev/null +++ b/integration_tests/src/coverable.cpp @@ -0,0 +1,27 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#include "src/coverable.h" + +namespace coverage_integration { + +const char* classify(int value) { + if (value < 0) { + return "negative"; + } + if (value == 0) { + return "zero"; + } + return "positive"; // COV_JUSTIFIED itest-positive-branch +} + +} // namespace coverage_integration diff --git a/integration_tests/src/coverable.h b/integration_tests/src/coverable.h new file mode 100644 index 0000000..bb43b27 --- /dev/null +++ b/integration_tests/src/coverable.h @@ -0,0 +1,24 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef COVERAGE_INTEGRATION_TESTS_SRC_COVERABLE_H +#define COVERAGE_INTEGRATION_TESTS_SRC_COVERABLE_H + +namespace coverage_integration { + +// Classifies an integer. Three branches; the test exercises only two so the +// report is guaranteed to contain both covered and uncovered branches. +const char* classify(int value); + +} // namespace coverage_integration + +#endif // COVERAGE_INTEGRATION_TESTS_SRC_COVERABLE_H diff --git a/integration_tests/src/coverable_test.cpp b/integration_tests/src/coverable_test.cpp new file mode 100644 index 0000000..eb22a5e --- /dev/null +++ b/integration_tests/src/coverable_test.cpp @@ -0,0 +1,28 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#include + +#include "src/coverable.h" + +// Deliberately exercises only the negative and zero branches; the positive +// branch stays uncovered (and justified via the COV_JUSTIFIED marker). +int main() { + using coverage_integration::classify; + if (std::strcmp(classify(-5), "negative") != 0) { + return 1; + } + if (std::strcmp(classify(0), "zero") != 0) { + return 1; + } + return 0; +} diff --git a/integration_tests/src/uncovered.cpp b/integration_tests/src/uncovered.cpp new file mode 100644 index 0000000..6eaf59d --- /dev/null +++ b/integration_tests/src/uncovered.cpp @@ -0,0 +1,24 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#include "src/uncovered.h" + +namespace coverage_integration { + +int never_called(int value) { + if (value > 10) { + return value * 2; + } + return value - 1; +} + +} // namespace coverage_integration diff --git a/integration_tests/src/uncovered.h b/integration_tests/src/uncovered.h new file mode 100644 index 0000000..0c5a4a2 --- /dev/null +++ b/integration_tests/src/uncovered.h @@ -0,0 +1,24 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#ifndef COVERAGE_INTEGRATION_TESTS_SRC_UNCOVERED_H +#define COVERAGE_INTEGRATION_TESTS_SRC_UNCOVERED_H + +namespace coverage_integration { + +// Linked into no test on purpose: this library must still appear in the +// coverage report at exactly 0% via the --empty-profile baseline mechanism. +int never_called(int value); + +} // namespace coverage_integration + +#endif // COVERAGE_INTEGRATION_TESTS_SRC_UNCOVERED_H diff --git a/integration_tests/tools/coverage/BUILD b/integration_tests/tools/coverage/BUILD new file mode 100644 index 0000000..e86d935 --- /dev/null +++ b/integration_tests/tools/coverage/BUILD @@ -0,0 +1,38 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@score_coverage//:defs.bzl", "score_coverage_reporter", "score_coverage_scope") + +# The production targets whose transitive sources define the coverage scope. +# Untested targets listed here (src:uncovered, rust:untested_tool) appear in +# the report at exact 0% via the --empty-profile baseline. +score_coverage_scope( + name = "coverage_scope", + testonly = True, + visibility = ["//visibility:private"], + deps = [ + "//rust:integration_lib", + "//rust:untested_tool", + "//src:coverable", + "//src:uncovered", + ], +) + +score_coverage_reporter( + name = "reporter_wrapper", + testonly = True, + coverage_scope = ":coverage_scope", + llvm_cov = "@llvm_toolchain//:llvm-cov", + llvm_cxxfilt = "@llvm_toolchain_llvm//:bin/llvm-cxxfilt", + llvm_profdata = "@llvm_toolchain//:llvm-profdata", +) diff --git a/integration_tests/tools/coverage/coverage_justifications.yaml b/integration_tests/tools/coverage/coverage_justifications.yaml new file mode 100644 index 0000000..7dadf7c --- /dev/null +++ b/integration_tests/tools/coverage/coverage_justifications.yaml @@ -0,0 +1,25 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +# Coverage justifications for the integration test workspace. +# +# Justified lines count as covered in the EFFECTIVE coverage metric. The line +# is marked in-code with a `COV_JUSTIFIED ` comment (src/coverable.cpp); +# this file provides the id, category and reason. +version: 1 +justifications: + - id: itest-positive-branch + category: other + platforms: [linux] + reason: | + Intentionally uncovered branch: the integration test asserts that a + justified line raises effective coverage above raw coverage. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b684a7d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,86 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +[tool.ruff] +line-length = 120 +target-version = "py312" # the only interpreter the module supports (see MODULE.bazel) +extend-exclude = ["__pycache__", ".*", "bazel-*", "integration_tests"] + +[tool.ruff.lint] +# Rule set of score_tooling's python_basics/pyproject.toml (S-CORE Python guideline). +select = [ + "E", # pycodestyle + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "C90", # mccabe complexity + "UP", # pyupgrade + "SIM", # flake8-simplify + "RET", # flake8-return +] + +[tool.ruff.lint.isort] +known-first-party = ["score_coverage"] + +[tool.ruff.lint.mccabe] +# The S-CORE complexity requirement (gd_req__impl_complexity_analysis) is +# LoC-based: 100 lines per function for safety-related code. McCabe 15 is this +# module's additional ceiling; ruff's default of 10 is the python_basics style +# preference and would force splitting straightforward validation code. +max-complexity = 15 + +[tool.ty.environment] +python-version = "3.12" + +[tool.pylint.format] +max-line-length = 120 +# S-CORE process limit for safety-related code (gd_req__impl_complexity_analysis). +max-module-lines = 2000 + +[tool.pylint."messages control"] +disable = [ + # Size/complexity is governed by ruff's C901 (max 15, see [tool.ruff.lint.mccabe]) + # and the process LoC limits; pylint's design counters would add a second, + # unrelated set of thresholds for the same property. + "too-many-locals", + "too-many-branches", + "too-many-statements", + "too-many-nested-blocks", + "too-many-arguments", + "too-many-positional-arguments", + # Small dataclasses and test fakes legitimately have one or no public method. + "too-few-public-methods", + # aspect_rules_lint's pylint aspect action (see + # @aspect_rules_lint//lint:pylint.bzl) only ever passes a target's own + # `srcs` to pylint -- it never forwards `deps` or sets up PYTHONPATH. + # Pylint's static import resolution therefore can never see ANY + # dependency (first-party or third-party) and reports import-error on + # every non-stdlib import, regardless of whether Bazel actually + # resolves it fine at build/run time. This is a structural limitation + # of the sandboxed lint action, not a real code defect, so it can't be + # fixed in userland code -- disabling is the only option. + "import-error", + + # These duplicate checks ruff already runs (`[tool.ruff.lint] select` + # above): verified repo-wide that every finding below was reported by + # BOTH tools for the exact same file/line. Keeping both just reports the + # same diagnostic twice with no added signal, so pylint defers to ruff + # (faster, and already the formatter for this repo). + "unused-import", # == ruff F401 (unused-import) + "undefined-variable", # == ruff F821 (undefined-name) + "line-too-long", # == ruff E501 (line-too-long) + "multiple-imports", # == ruff E401 (multiple-imports-on-one-line) + "reimported", # == ruff F811 (redefined-while-unused) + "f-string-without-interpolation", # == ruff F541 (f-string-missing-placeholders) +] diff --git a/score_coverage/BUILD b/score_coverage/BUILD new file mode 100644 index 0000000..4af59ae --- /dev/null +++ b/score_coverage/BUILD @@ -0,0 +1,126 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@pip_score_coverage//:requirements.bzl", "requirement") +load("@rules_python//python:defs.bzl", "py_binary", "py_library") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") + +package(default_visibility = ["//visibility:public"]) + +# ============================================================================= +# LLVM source-based coverage pipeline (C++ + Rust) — implementation package. +# Consumers use the root-level labels (//:merger, //:generate_coverage_html, +# //:defs.bzl, //:enable_llvm_coverage_for_death_tests); see //:BUILD. +# ============================================================================= + +# Per-test coverage output generator (--coverage_output_generator). Locates +# llvm-profdata via the LLVM_PROFDATA / RUST_LLVM_PROFDATA environment +# variables exported by the toolchains, so it needs no consumer-supplied labels. +py_binary( + name = "merger", + srcs = ["merger.py"], +) + +# Final report generator. Not referenced directly by consumers: the +# score_coverage_reporter macro wraps it with the consumer's coverage scope, +# workspace root and LLVM tool labels. +py_binary( + name = "reporter", + srcs = ["reporter.py"], + deps = ["@rules_python//python/runfiles"], +) + +py_binary( + name = "justify", + srcs = ["justify.py"], + deps = [requirement("pyyaml")], +) + +py_binary( + name = "effective_coverage", + srcs = ["effective_coverage.py"], +) + +# Markdown job summary (GITHUB_STEP_SUMMARY / --summary-md), invoked by +# generate_coverage_html. Stdlib only. +py_binary( + name = "coverage_summary", + srcs = ["coverage_summary.py"], +) + +# Orchestrator + threshold gate: unpacks the reporter zip, runs justify / +# effective_coverage / coverage_summary in-process and enforces +# COVERAGE_THRESHOLD. Consumers run it as @score_coverage//:generate_coverage_html. +py_binary( + name = "generate_coverage_html", + srcs = ["generate_coverage_html.py"], + deps = [ + ":coverage_summary_lib", + ":effective_coverage_lib", + ":justify_lib", + ], +) + +# Import-only libraries so unit tests can `from score_coverage. import ...`. +py_library( + name = "merger_lib", + srcs = ["merger.py"], + imports = [".."], +) + +py_library( + name = "reporter_lib", + srcs = ["reporter.py"], + imports = [".."], + deps = ["@rules_python//python/runfiles"], +) + +py_library( + name = "justify_lib", + srcs = ["justify.py"], + imports = [".."], + deps = [requirement("pyyaml")], +) + +py_library( + name = "effective_coverage_lib", + srcs = ["effective_coverage.py"], + imports = [".."], +) + +py_library( + name = "coverage_summary_lib", + srcs = ["coverage_summary.py"], + imports = [".."], +) + +py_library( + name = "generate_coverage_html_lib", + srcs = ["generate_coverage_html.py"], + imports = [".."], + deps = [ + ":coverage_summary_lib", + ":effective_coverage_lib", + ":justify_lib", + ], +) + +# In order to update the requirements, change the `requirements.in` file and run: +# `bazel run //score_coverage:requirements_3_12.update`. +compile_pip_requirements( + name = "requirements_3_12", + src = "requirements.in", + python_version = "3.12", + requirements_txt = "requirements_3_12.txt", + tags = ["manual"], +) diff --git a/score_coverage/coverage_scope.bzl b/score_coverage/coverage_scope.bzl new file mode 100644 index 0000000..acb722b --- /dev/null +++ b/score_coverage/coverage_scope.bzl @@ -0,0 +1,202 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +""" +Coverage scope rule for deriving file-level allowlists from implementation targets. + +This rule uses an aspect to traverse the build graph starting from the listed +implementation targets (cc_library, rust_library, rust_binary) through their +transitive deps. At each node it collects the actual source files. + +- cc_library (and rust_library, which also provides CcInfo in rules_rust + 0.68.x): source files come from the srcs/hdrs attributes; static archives + (including the rlib exposed as a .a symlink) are collected for baseline + (zero-coverage) reporting. +- rust_binary (no CcInfo): source files come from CrateInfo.srcs; the + coverage-built executable itself serves as the baseline object. + +The resulting allowlist contains one source file path per line (relative to the +workspace root). The coverage reporter uses this to restrict reports to exactly +the files that are part of the covered implementation. +""" + +load("@rules_rust//rust:rust_common.bzl", "CrateInfo") + +# ============================================================================= +# Provider to carry collected source file paths through the aspect +# ============================================================================= + +_CoverageScopeInfo = provider( + doc = "Carries source file paths and object files collected by the coverage scope aspect.", + fields = { + "source_files": "Depset of source file path strings (workspace-relative).", + "object_files": "Depset of compiled archive/executable File objects for baseline coverage.", + }, +) + +# ============================================================================= +# Aspect: traverses library/binary deps to collect files +# ============================================================================= + +def _coverage_scope_aspect_impl(target, ctx): + """Collects source file paths and archive files from the build graph.""" + direct_files = [] + direct_archives = [] + transitive = [] + transitive_archives = [] + + # At cc_library / rust_library targets (rust_library provides CcInfo with + # its rlib exposed as a .a symlink): collect srcs, hdrs, and static archive + if CcInfo in target: + for attr_name in ["srcs", "hdrs"]: + if hasattr(ctx.rule.attr, attr_name): + for src in getattr(ctx.rule.attr, attr_name): + for f in src.files.to_list(): + if not f.path.startswith("external/") and f.is_source: + direct_files.append(f.short_path) + + # Only collect workspace-internal labels and archives + if not str(target.label).startswith("@@") or str(target.label).startswith("@@//"): + # Collect .a archive files for baseline coverage. + for linker_input in target[CcInfo].linking_context.linker_inputs.to_list(): + for lib in linker_input.libraries: + for archive in [lib.static_library, lib.pic_static_library]: + if archive and "/external/" not in archive.path and not archive.path.startswith("external/"): + direct_archives.append(archive) + break + elif CrateInfo in target: + # rust_binary: no CcInfo, collect .rs sources from CrateInfo and use the + # coverage-built executable as the baseline object. + for f in target[CrateInfo].srcs.to_list(): + if not f.path.startswith("external/") and f.is_source: + direct_files.append(f.short_path) + out = target[CrateInfo].output + if out and "/external/" not in out.path and not out.path.startswith("external/"): + direct_archives.append(out) + + # Propagate from children traversed by the aspect + for attr_name in ["components", "implementation", "deps", "implementation_deps", "exported_deps"]: + if hasattr(ctx.rule.attr, attr_name): + for dep in getattr(ctx.rule.attr, attr_name): + if _CoverageScopeInfo in dep: + transitive.append(dep[_CoverageScopeInfo].source_files) + transitive_archives.append(dep[_CoverageScopeInfo].object_files) + + return [_CoverageScopeInfo( + source_files = depset(direct_files, transitive = transitive), + object_files = depset(direct_archives, transitive = transitive_archives), + )] + +_coverage_scope_aspect = aspect( + implementation = _coverage_scope_aspect_impl, + attr_aspects = ["components", "implementation", "deps", "implementation_deps", "exported_deps"], + doc = "Traverses cc_library/rust_library/rust_binary hierarchy to collect implementation source files.", +) + +# ============================================================================= +# Rule: aggregates aspect results into an allowlist file +# ============================================================================= + +def _coverage_scope_impl(ctx): + """Aggregates source file paths from all deps and writes allowlist + baseline objects.""" + all_files = {} + all_objects = [] + + for dep in ctx.attr.deps: + if _CoverageScopeInfo in dep: + for path in dep[_CoverageScopeInfo].source_files.to_list(): + if path: + all_files[path] = True + all_objects.append(dep[_CoverageScopeInfo].object_files) + + sorted_files = sorted(all_files.keys()) + object_depset = depset(transitive = all_objects) + + # Write the allowlist file + output = ctx.actions.declare_file(ctx.attr.name + "_allowlist.txt") + ctx.actions.write( + output = output, + content = "\n".join(sorted_files) + "\n" if sorted_files else "", + ) + + # Write archive file paths for baseline coverage (reporter uses these as --object args) + archive_paths = sorted(set([f.short_path for f in object_depset.to_list()])) + objects_output = ctx.actions.declare_file(ctx.attr.name + "_objects.txt") + ctx.actions.write( + output = objects_output, + content = "\n".join(archive_paths) + "\n" if archive_paths else "", + ) + + return [ + DefaultInfo(files = depset([output, objects_output], transitive = [object_depset])), + OutputGroupInfo( + allowlist = depset([output]), + objects = depset([objects_output]), + object_files = object_depset, + ), + ] + +def _coverage_transition_impl(settings, attr): + # This dictionary modifies the build configuration + return { + "//command_line_option:collect_code_coverage": True, + } + +# Define the transition +coverage_transition = transition( + implementation = _coverage_transition_impl, + inputs = [], + outputs = ["//command_line_option:collect_code_coverage"], +) + +def _coverage_wrapper_impl(ctx): + # Forward the executable or providers from the underlying target + actual_target = ctx.attr.actual[0] + return [actual_target[DefaultInfo]] + +# Define a rule that applies the transition to its 'actual' dependency +coverage_wrapper = rule( + implementation = _coverage_wrapper_impl, + attrs = { + "actual": attr.label( + mandatory = True, + cfg = coverage_transition, # Applying the transition here + ), + # Mandatory attribute needed when a rule uses a transition + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +coverage_scope = rule( + implementation = _coverage_scope_impl, + doc = """Generates a file-level coverage allowlist from implementation targets. + + Uses an aspect to traverse the listed targets (cc_library, rust_library, + rust_binary) and their transitive deps, collecting all source files + (srcs + hdrs / CrateInfo.srcs). Outputs a text file with one + workspace-relative file path per line. + + This allowlist is consumed by the coverage reporter to restrict coverage + reporting to exactly the source files that are part of the implementation. + """, + attrs = { + "deps": attr.label_list( + mandatory = True, + aspects = [_coverage_scope_aspect], + cfg = coverage_transition, + doc = "Implementation targets whose transitive deps define the coverage scope.", + ), + }, +) diff --git a/score_coverage/coverage_summary.py b/score_coverage/coverage_summary.py new file mode 100644 index 0000000..fc4d435 --- /dev/null +++ b/score_coverage/coverage_summary.py @@ -0,0 +1,352 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Render a markdown coverage summary from the pipeline's LCOV output. + +Invoked by generate_coverage_html to produce a human-readable summary for +GitHub job summary pages (GITHUB_STEP_SUMMARY) or an arbitrary markdown file +(--summary-md). Standard library only. + +Inputs: + --lcov LCOV trace produced by the coverage reporter + (includes exact-0% baseline records). + --justification-report Optional report.json from effective_coverage.py + (raw vs effective metrics, justified counts). + --output Markdown destination. + --append Append to --output instead of overwriting + (GITHUB_STEP_SUMMARY convention). +""" + +import argparse +import json +import sys +from pathlib import Path + +BAR_WIDTH = 10 +LEAST_COVERED_LIMIT = 15 + + +class FileCoverage: + """Line/branch counters for one SF record.""" + + def __init__(self, path: str) -> None: + self.path = path + self.lines_found = 0 + self.lines_hit = 0 + # None means "no branch data in the record" (rendered as an em dash). + self.branches_found: int | None = None + self.branches_hit: int | None = None + + @property + def line_pct(self) -> float | None: + """Line coverage percentage of this file, or None without instrumented lines.""" + return percent(self.lines_hit, self.lines_found) + + +def percent(hit: int, total: int) -> float | None: + """Percentage, or None when the denominator is zero.""" + if total <= 0: + return None + return 100.0 * hit / total + + +def fmt_pct(pct: float | None) -> str: + """Render a percentage for a table cell (n/a for None).""" + return "—" if pct is None else f"{pct:.2f}%" + + +def progress_bar(pct: float | None, width: int = BAR_WIDTH) -> str: + """Render a COVERAGE percentage as an inline-code bar, e.g. `███████░░░`. + + Purely a visual aid next to the numeric cell so table rows can be + compared at a glance on the run page — it shows how much of the code is + covered, nothing else. + """ + if pct is None: + return "—" + filled = int(round(pct / 100.0 * width)) + filled = max(0, min(width, filled)) + return "`" + "█" * filled + "░" * (width - filled) + "`" + + +def escape_cell(text: str) -> str: + """Make a path safe inside a markdown table cell.""" + return text.replace("|", "\\|") + + +class _LcovRecord: + """Accumulates one ``SF:`` record. BRF/BRH sums win over counted BRDA entries.""" + + def __init__(self, path: str) -> None: + self.file = FileCoverage(path) + self.brf = 0 + self.brh = 0 + self.brda_total = 0 + self.brda_hit = 0 + self.saw_brf = False + + def feed(self, line: str) -> None: + """Consume one LCOV line belonging to this record.""" + if line.startswith("LF:"): + self.file.lines_found += _int_suffix(line) + elif line.startswith("LH:"): + self.file.lines_hit += _int_suffix(line) + elif line.startswith("BRF:"): + self.saw_brf = True + self.brf += _int_suffix(line) + elif line.startswith("BRH:"): + self.saw_brf = True + self.brh += _int_suffix(line) + elif line.startswith("BRDA:"): + # BRDA:,,, — "-" means never + # evaluated, any positive count means taken. + self.brda_total += 1 + if line.rsplit(",", 1)[-1] not in ("-", "0"): + self.brda_hit += 1 + + def finish(self) -> FileCoverage: + """Apply the branch counters and return the completed record.""" + if self.saw_brf: + self.file.branches_found = self.brf + self.file.branches_hit = self.brh + elif self.brda_total > 0: + self.file.branches_found = self.brda_total + self.file.branches_hit = self.brda_hit + return self.file + + +def parse_lcov(path: Path) -> list[FileCoverage] | None: + """Parse an LCOV trace into per-file counters. + + Returns None when the file does not exist; an empty list when it exists + but contains no records. Branch data prefers BRF/BRH sums and falls back + to counting BRDA entries (taken > 0 counts as hit). + """ + if not path.is_file(): + return None + + files: list[FileCoverage] = [] + current: _LcovRecord | None = None + # errors="replace" keeps non-UTF8 bytes in paths from crashing the parse. + with open(path, encoding="utf-8", errors="replace") as f: + for raw_line in f: + line = raw_line.strip() + if line.startswith("SF:"): + if current is not None: + files.append(current.finish()) + current = _LcovRecord(line[3:]) + elif current is None: + continue + elif line == "end_of_record": + files.append(current.finish()) + current = None + else: + current.feed(line) + if current is not None: + files.append(current.finish()) + return files + + +def _int_suffix(line: str) -> int: + try: + return int(line.split(":", 1)[1]) + except (IndexError, ValueError): + return 0 + + +def load_justification_summary(path: Path) -> dict | None: + """Load the summary block of effective_coverage.py's report.json.""" + try: + with open(path, encoding="utf-8") as f: + report = json.load(f) + except (OSError, json.JSONDecodeError) as e: + print(f"WARNING: could not read justification report {path}: {e}", file=sys.stderr) + return None + summary = report.get("summary") + if not isinstance(summary, dict): + return None + summary = dict(summary) + applied = report.get("applied_justifications") + summary["applied_justification_count"] = len(applied) if isinstance(applied, list) else 0 + return summary + + +def directory_key(path: str) -> str: + """Group by the first one or two path segments (generic, layout-agnostic).""" + parts = path.split("/") + if len(parts) <= 1: + return "(root)" + if len(parts) == 2: + return parts[0] + return "/".join(parts[:2]) + + +def rollup_by_directory(files: list[FileCoverage]) -> list[dict]: + """Aggregate per-file counters into one row per top-level directory.""" + groups: dict[str, dict] = {} + for fc in files: + g = groups.setdefault( + directory_key(fc.path), + {"lines_found": 0, "lines_hit": 0, "files": 0}, + ) + g["lines_found"] += fc.lines_found + g["lines_hit"] += fc.lines_hit + g["files"] += 1 + rows = [ + { + "directory": name, + "pct": percent(g["lines_hit"], g["lines_found"]), + **g, + } + for name, g in groups.items() + ] + # Worst first; groups without countable lines sink to the end. + rows.sort(key=lambda r: (r["pct"] is None, r["pct"], r["directory"])) + return rows + + +def render_markdown(files: list[FileCoverage], justification: dict | None) -> str: + """Render the full markdown summary (totals, raw vs effective, per-directory rollup, 0% files).""" + out: list[str] = ["## Coverage summary", ""] + + if not files: + out.append("_No coverage records found in the LCOV report._") + out.append("") + return "\n".join(out) + + total_lf = sum(f.lines_found for f in files) + total_lh = sum(f.lines_hit for f in files) + branch_files = [f for f in files if f.branches_found is not None] + total_brf = sum(f.branches_found for f in branch_files) if branch_files else 0 + total_brh = sum(f.branches_hit for f in branch_files) if branch_files else 0 + touched = [f for f in files if f.lines_hit > 0] + zero = [f for f in files if f.lines_found > 0 and f.lines_hit == 0] + + line_pct = percent(total_lh, total_lf) + branch_pct = percent(total_brh, total_brf) if branch_files else None + touched_pct = percent(len(touched), len(files)) + + out.append("| Metric | Covered | Total | % | |") + out.append("|---|---:|---:|---:|---|") + out.append(f"| Lines | {total_lh} | {total_lf} | {fmt_pct(line_pct)} | {progress_bar(line_pct)} |") + out.append( + f"| Branches | {total_brh if branch_files else '—'} | " + f"{total_brf if branch_files else '—'} | {fmt_pct(branch_pct)} | {progress_bar(branch_pct)} |" + ) + out.append( + f"| Files with coverage | {len(touched)} | {len(files)} | " + f"{fmt_pct(touched_pct)} | {progress_bar(touched_pct)} |" + ) + out.append(f"| Files at exact 0% | {len(zero)} | {len(files)} | | |") + out.append("") + + if justification is not None: + out.append("### Raw vs effective (justifications applied)") + out.append("") + out.append("| Metric | Raw | Effective |") + out.append("|---|---:|---:|") + out.append( + f"| Line coverage | {justification.get('raw_line_coverage_pct', 0)}% " + f"| {justification.get('effective_line_coverage_pct', 0)}% |" + ) + out.append( + f"| Branch coverage | {justification.get('raw_branch_coverage_pct', 0)}% " + f"| {justification.get('effective_branch_coverage_pct', 0)}% |" + ) + out.append("") + out.append( + f"Justified: {justification.get('justified_lines', 0)} lines, " + f"{justification.get('justified_branches', 0)} branches " + f"({justification.get('applied_justification_count', 0)} justification entries applied, " + f"{justification.get('stale_justifications', 0)} stale)." + ) + out.append("") + + out.append("### Coverage by directory (worst first)") + out.append("") + out.append("| Directory | Files | Lines hit/total | % | |") + out.append("|---|---:|---:|---:|---|") + for row in rollup_by_directory(files): + out.append( + f"| {escape_cell(row['directory'])} | {row['files']} " + f"| {row['lines_hit']}/{row['lines_found']} " + f"| {fmt_pct(row['pct'])} | {progress_bar(row['pct'])} |" + ) + out.append("") + + least = sorted( + (f for f in touched if f.lines_hit < f.lines_found), + key=lambda f: (f.line_pct is None, f.line_pct, f.path), + )[:LEAST_COVERED_LIMIT] + if least: + out.append("
") + out.append(f"Least-covered files with coverage (top {len(least)})") + out.append("") + out.append("| File | Lines hit/total | % | |") + out.append("|---|---:|---:|---|") + for fc in least: + out.append( + f"| {escape_cell(fc.path)} | {fc.lines_hit}/{fc.lines_found} " + f"| {fmt_pct(fc.line_pct)} | {progress_bar(fc.line_pct)} |" + ) + out.append("") + out.append("
") + out.append("") + + if zero: + out.append("
") + out.append(f"Files at exact 0% ({len(zero)})") + out.append("") + for fc in sorted(zero, key=lambda f: f.path): + out.append(f"- `{fc.path}` ({fc.lines_found} lines)") + out.append("") + out.append("
") + out.append("") + + out.append("_Full per-line HTML report: download the coverage artifact of this run._") + out.append("") + return "\n".join(out) + + +def main(argv: list[str] | None = None) -> None: + """Entry point. ``argv`` defaults to ``sys.argv[1:]``.""" + parser = argparse.ArgumentParser(description="Markdown coverage summary from LCOV") + parser.add_argument("--lcov", type=Path, required=True) + parser.add_argument("--justification-report", type=Path, default=None) + parser.add_argument("--output", type=Path, required=True) + parser.add_argument("--append", action="store_true") + args = parser.parse_args(argv) + + files = parse_lcov(args.lcov) + if files is None: + print(f"WARNING: LCOV file not found: {args.lcov}", file=sys.stderr) + files = [] + + justification = None + if args.justification_report is not None: + justification = load_justification_summary(args.justification_report) + + markdown = render_markdown(files, justification) + + args.output.parent.mkdir(parents=True, exist_ok=True) + mode = "a" if args.append else "w" + with open(args.output, mode, encoding="utf-8") as f: + f.write(markdown) + print( + f"INFO: coverage summary {'appended to' if args.append else 'written to'} {args.output}", + file=sys.stderr, + ) + + +if __name__ == "__main__": + main() diff --git a/score_coverage/effective_coverage.py b/score_coverage/effective_coverage.py new file mode 100644 index 0000000..0871704 --- /dev/null +++ b/score_coverage/effective_coverage.py @@ -0,0 +1,1195 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Effective coverage calculator and HTML post-processor. + +Takes an HTML coverage report (llvm-cov or gcovr) and the resolved justification +manifest. Modifies the HTML to show justified lines in a distinct color (yellow/orange) +and calculates effective coverage metrics. + +Supports two HTML formats: + - llvm-cov: produced by our custom reporter (Linux) + - gcovr: produced by lcov_to_html.py via gcovr (QNX) + +Usage: + python effective_coverage.py --html-dir --manifest --output [--lcov ] +""" + +import argparse +import json +import math +import re +import sys +from pathlib import Path +from typing import Any + +# Pattern to match a table row in llvm-cov HTML source pages +# Format: ......... +LINE_NUMBER_RE = re.compile(r"") +COVERED_LINE_TD_RE = re.compile(r"") + + +def floor_two_decimals(value: float) -> float: + """Floor a percentage value to two decimal places.""" + return math.floor(value * 100.0) / 100.0 + + +def main(argv: list[str] | None = None) -> None: + """Main entry point. ``argv`` defaults to ``sys.argv[1:]``.""" + args = parse_args(argv) + + # Load the justification manifest + manifest = load_manifest(args.manifest) + justified_files = manifest.get("justified_files", {}) + + # Find all source HTML files in the report + html_dir = args.html_dir + if not html_dir.exists(): + print(f"ERROR: HTML report directory not found: {html_dir}", file=sys.stderr) + sys.exit(1) + + # Detect HTML format: llvm-cov uses style.css, gcovr uses index...html naming. + html_format = detect_html_format(html_dir) + + if html_format == "gcovr": + _main_gcovr(args, html_dir, justified_files) + else: + _main_llvm_cov(args, html_dir, justified_files) + + +def _main_llvm_cov(args: argparse.Namespace, html_dir: Path, justified_files: dict) -> None: + """Main logic for llvm-cov HTML format.""" + + # Parse raw coverage totals from the index page (matches llvm-cov exactly). + totals = parse_index_page_totals(html_dir) + raw_covered, raw_total = totals["lines"] + raw_branch_covered, raw_branch_total = totals["branches"] + + # Process each source HTML file (restyle justified lines + count them) + total_justified = 0 + total_stale = 0 + total_justified_branches = 0 + applied_justifications: list[dict[str, Any]] = [] + stale_justifications: list[dict[str, Any]] = [] + # Track per-file justification counts for index page updates + per_file_stats: dict[str, dict[str, int]] = {} + + source_html_files = find_source_html_files(html_dir) + for html_file in source_html_files: + rel_source_path = extract_source_path_from_html(html_file, html_dir) + if not rel_source_path: + continue + + file_justifications = find_matching_justifications(rel_source_path, justified_files) + + file_stats = process_html_file(html_file, file_justifications, applied_justifications, stale_justifications) + + total_justified += file_stats["justified"] + total_stale += file_stats["stale"] + total_justified_branches += file_stats["justified_branches"] + + if file_stats["justified"] > 0 or file_stats["justified_branches"] > 0: + per_file_stats[rel_source_path] = file_stats + + # Calculate stats using llvm-cov's exact numbers + raw_uncovered = raw_total - raw_covered + unjustified_uncovered = raw_uncovered - total_justified + + effective_branch_covered = raw_branch_covered + total_justified_branches + + stats = { + "total_instrumented_lines": raw_total, + "covered_lines": raw_covered, + "justified_lines": total_justified, + "unjustified_uncovered_lines": max(0, unjustified_uncovered), + "stale_justifications": total_stale, + "raw_line_coverage_pct": floor_two_decimals(100.0 * raw_covered / raw_total) if raw_total > 0 else 0.0, + "effective_line_coverage_pct": floor_two_decimals(100.0 * (raw_covered + total_justified) / raw_total) + if raw_total > 0 + else 0.0, + "total_branches": raw_branch_total, + "covered_branches": raw_branch_covered, + "justified_branches": total_justified_branches, + "raw_branch_coverage_pct": floor_two_decimals(100.0 * raw_branch_covered / raw_branch_total) + if raw_branch_total > 0 + else 0.0, + "effective_branch_coverage_pct": floor_two_decimals(100.0 * effective_branch_covered / raw_branch_total) + if raw_branch_total > 0 + else 0.0, + } + + # Inject CSS for justified lines into style.css + inject_justified_css(html_dir) + + # Update the index page with effective coverage info and per-file stats + update_index_page(html_dir, stats, per_file_stats) + + _write_outputs(Path(args.output), stats, applied_justifications, stale_justifications) + + # Print summary + print( + f"INFO: Effective line coverage: {stats['effective_line_coverage_pct']}% " + f"(raw: {stats['raw_line_coverage_pct']}%, " + f"justified: {stats['justified_lines']} lines, " + f"unjustified uncovered: {stats['unjustified_uncovered_lines']} lines)", + file=sys.stderr, + ) + if stats["justified_branches"] > 0: + print( + f"INFO: Effective branch coverage: {stats['effective_branch_coverage_pct']}% " + f"(raw: {stats['raw_branch_coverage_pct']}%, " + f"justified: {stats['justified_branches']} branches)", + file=sys.stderr, + ) + if stale_justifications: + print( + f"WARNING: {len(stale_justifications)} stale justifications " + f"(lines are actually covered, justification can be removed)", + file=sys.stderr, + ) + + +_ROW_STATUS_RE = re.compile( + r"
\d+
" + r"" +) +# Full row, captured for rewriting: +# ...
0
+#
...
... +_FULL_ROW_RE = re.compile( + r"(
\d+
)" + r"(
)\d+(
)" + r"(
)(.*?)(
)" +) +# Branch line in expansion view: +# Branch (195:17): +# [True: 0, ...] +_BRANCH_RE = re.compile( + r"(Branch \(" + r"(\d+:\d+)\):\s*\[)(.*?\])" +) +_DIRECTIONS = ("True", "False") + + +def _line_statuses(content: str) -> dict[int, str]: + """Effective status per line: covered if ANY instantiation covers it.""" + statuses: dict[int, str] = {} + for m in _ROW_STATUS_RE.finditer(content): + line_num = int(m.group(1)) + line_class = m.group(2) + if line_class == "covered-line": + statuses[line_num] = "covered" + elif line_class == "uncovered-line" and line_num not in statuses: + statuses[line_num] = "uncovered" + return statuses + + +def _lines_with_uncovered_branches(content: str) -> set[int]: + """Lines having a branch direction that no instantiation ever covered.""" + covered: dict[str, set] = {} + uncovered: dict[str, set] = {} + branch_line: dict[str, int] = {} + for m in _BRANCH_RE.finditer(content): + branch_id = m.group(3) + branch_line[branch_id] = int(m.group(2)) + covered.setdefault(branch_id, set()) + uncovered.setdefault(branch_id, set()) + for direction in _DIRECTIONS: + if f"class='None'>{direction}" in m.group(4): + covered[branch_id].add(direction) + if f"class='red branch'>{direction}" in m.group(4): + uncovered[branch_id].add(direction) + return {branch_line[bid] for bid, dirs in uncovered.items() if dirs - covered.get(bid, set())} + + +def _classify_justifications( + html_file: Path, + justifications: dict[int, dict[str, str]], + statuses: dict[int, str], + branch_lines: set[int], + applied: list[dict[str, Any]], + stale: list[dict[str, Any]], + file_stats: dict[str, int], +) -> None: + """Sort each justified line into justified / branch-only / stale.""" + for line_num, justification in justifications.items(): + status = statuses.get(line_num) + has_uncovered_branches = line_num in branch_lines + entry = { + "file": html_file.stem, + "line": line_num, + "id": justification.get("id", ""), + "category": justification.get("category", ""), + } + if status == "covered" and not has_uncovered_branches: + file_stats["stale"] += 1 + stale.append( + { + "file": html_file.stem, + "line": line_num, + "id": justification.get("id", ""), + "reason": "Line is already covered and has no uncovered branches — justification is stale", + } + ) + elif status == "uncovered": + file_stats["justified"] += 1 + applied.append(entry) + elif status == "covered" and has_uncovered_branches: + # Covered line with uncovered branches: the justification applies to the branches only. + applied.append(entry) + + +def _restyle_rows(content: str, justifications: dict[int, dict[str, str]]) -> tuple[str, bool]: + """Turn the count cell of justified uncovered rows into 'J' and recolor red regions.""" + modified = False + + def replace_full_row(match: re.Match) -> str: + nonlocal modified + line_num = int(match.group(2)) + if line_num not in justifications: + return match.group(0) + justification = justifications[line_num] + reason = justification.get("reason", "").replace("'", "'").replace('"', """) + tooltip = f"Justified [{justification.get('id', '')}]: {reason}" + modified = True + count_td = f"
J{match.group(4)}"
+        code_content = match.group(6).replace("class='region red'", "class='region justified'")
+        return match.group(1) + count_td + match.group(5) + code_content + match.group(7)
+
+    return _FULL_ROW_RE.sub(replace_full_row, content), modified
+
+
+def _restyle_branches(
+    content: str, justifications: dict[int, dict[str, str]], file_stats: dict[str, int]
+) -> tuple[str, bool]:
+    """Restyle red branches on justified lines and count the truly uncovered directions once."""
+    # A direction is covered if ANY instantiation covers it (llvm-cov's own rule).
+    covered_dirs: set = set()
+    for m in _BRANCH_RE.finditer(content):
+        if int(m.group(2)) not in justifications:
+            continue
+        for direction in _DIRECTIONS:
+            if f"class='None'>{direction}" in m.group(4):
+                covered_dirs.add((m.group(3), direction))
+
+    modified = False
+    counted: set = set()
+
+    def replace_branch(match: re.Match) -> str:
+        nonlocal modified
+        line_num = int(match.group(2))
+        branch_content = match.group(4)
+        if line_num not in justifications or "class='red branch'" not in branch_content:
+            return match.group(0)
+        modified = True
+        for direction in _DIRECTIONS:
+            uid = (match.group(3), direction)
+            is_red = f"class='red branch'>{direction}" in branch_content
+            if is_red and uid not in covered_dirs and uid not in counted:
+                counted.add(uid)
+                file_stats["justified_branches"] += 1
+        branch_content = branch_content.replace("class='red branch'", "class='justified-branch'")
+        branch_content = branch_content.replace("class='uncovered-line'", "class='justified-line'")
+        return match.group(1) + branch_content
+
+    return _BRANCH_RE.sub(replace_branch, content), modified
+
+
+def process_html_file(
+    html_file: Path,
+    justifications: dict[int, dict[str, str]],
+    applied_justifications: list[dict[str, Any]],
+    stale_justifications: list[dict[str, Any]],
+) -> dict[str, int]:
+    """Process a single source HTML file. Modifies it in-place.
+
+    Restyles justified lines: changes the count cell to show "J" with justified-line
+    class, and changes red code regions to justified (orange) background.
+    Also restyles uncovered branches on justified lines.
+    Only counts justified/stale lines for the justification report — raw coverage
+    numbers are taken from the index page to match llvm-cov exactly.
+    """
+    file_stats = {"justified": 0, "stale": 0, "justified_branches": 0}
+
+    with open(html_file, encoding="utf-8") as f:
+        content = f.read()
+
+    if not justifications:
+        return file_stats
+
+    statuses = _line_statuses(content)
+    branch_lines = _lines_with_uncovered_branches(content)
+    _classify_justifications(
+        html_file, justifications, statuses, branch_lines, applied_justifications, stale_justifications, file_stats
+    )
+
+    new_content, rows_modified = _restyle_rows(content, justifications)
+    new_content, branches_modified = _restyle_branches(new_content, justifications, file_stats)
+
+    if rows_modified or branches_modified:
+        with open(html_file, "w", encoding="utf-8") as f:
+            f.write(new_content)
+
+    return file_stats
+
+
+def parse_index_page_totals(html_dir: Path) -> dict[str, tuple[int, int]]:
+    """Parse the TOTALS row from the llvm-cov index.html to get exact coverage numbers.
+
+    Returns dict with 'lines' and 'branches' keys, each (covered, total).
+    The index page TOTALS row format: "93.55% (17565/18777)" — func, line, branch.
+    """
+    index_file = html_dir / "index.html"
+    if not index_file.exists():
+        # Zero totals make every percentage 0.0 and fail the gate; say why.
+        print(f"WARNING: {index_file} not found; coverage totals default to 0/0", file=sys.stderr)
+        return {"lines": (0, 0), "branches": (0, 0)}
+
+    with open(index_file, encoding="utf-8") as f:
+        content = f.read()
+
+    pct_pattern = re.compile(r"(\d+\.\d+)%\s*\((\d+)/(\d+)\)")
+    matches = pct_pattern.findall(content)
+
+    result = {"lines": (0, 0), "branches": (0, 0)}
+
+    if len(matches) >= 3:
+        # Last 3 matches are from TOTALS row: func, line, branch
+        totals_matches = matches[-3:]
+        _, line_covered, line_total = totals_matches[1]
+        result["lines"] = (int(line_covered), int(line_total))
+        _, branch_covered, branch_total = totals_matches[2]
+        result["branches"] = (int(branch_covered), int(branch_total))
+
+    if result["lines"] == (0, 0):
+        print("WARNING: Could not parse coverage totals from index.html", file=sys.stderr)
+
+    return result
+
+
+def inject_justified_css(html_dir: Path) -> None:
+    """Add CSS for justified lines to style.css."""
+    style_file = html_dir / "style.css"
+    if not style_file.exists():
+        return
+
+    justified_css = """
+/* Coverage justification styling */
+.justified-line {
+  text-align: right;
+  color: #a60;
+}
+.region.justified {
+  background-color: #fa04;
+}
+.justified-branch {
+  color: #a60;
+  font-weight: bold;
+}
+tr:has(> td.justified-line) > td.code {
+  background-color: #fff3e0;
+}
+@media (prefers-color-scheme: dark) {
+  .justified-line {
+    color: #fa0;
+  }
+  .justified-branch {
+    color: #fa0;
+  }
+  tr:has(> td.justified-line) > td.code {
+    background-color: #3d2800;
+  }
+  .region.justified {
+    background-color: #fa03;
+  }
+}
+"""
+
+    with open(style_file, "a", encoding="utf-8") as f:
+        f.write(justified_css)
+
+
+def update_index_page(html_dir: Path, stats: dict[str, Any], per_file_stats: dict[str, dict[str, int]]) -> None:
+    """Update the index page with effective coverage info and per-file adjusted percentages."""
+    index_file = html_dir / "index.html"
+    if not index_file.exists():
+        return
+
+    with open(index_file, encoding="utf-8") as f:
+        content = f.read()
+
+    # Banner with overall effective coverage (lines + branches)
+    branch_info = ""
+    if stats.get("justified_branches", 0) > 0:
+        branch_info = (
+            f" | Effective Branch Coverage: {stats['effective_branch_coverage_pct']}%"
+            f" (Raw: {stats['raw_branch_coverage_pct']}%, Justified: {stats['justified_branches']} branches)"
+        )
+
+    banner = (
+        f"
" + f"Effective Line Coverage: {stats['effective_line_coverage_pct']}% " + f"(Raw: {stats['raw_line_coverage_pct']}% | " + f"Justified: {stats['justified_lines']} lines | " + f"Unjustified Uncovered: {stats['unjustified_uncovered_lines']} lines)" + f"{branch_info}" + f"
" + ) + + # Insert after the tag or after the first

+ if "

" in content: + content = content.replace("

", banner + "

", 1) + else: + content = content.replace("", f"{banner}", 1) + + # Update per-file rows in the index table. + # For each file with justifications, find its row and update line% and branch% cells. + # Row format:
displayname
+ #
  XX.XX% (covered/total)
← function + #
  XX.XX% (covered/total)
← line + #
  XX.XX% (covered/total)
← branch + # + pct_cell_pattern = re.compile(r"
\s*(\d+\.\d+)%\s*\((\d+)/(\d+)\)
") + + for file_path, fstats in per_file_stats.items(): + justified_lines = fstats.get("justified", 0) + justified_branches = fstats.get("justified_branches", 0) + if justified_lines == 0 and justified_branches == 0: + continue + + # Find the row for this file in the index page + # The href contains the full path to the HTML file + if file_path not in content: + continue + + # Find the containing this file path + file_idx = content.find(file_path) + if file_idx < 0: + continue + row_start = content.rfind("", file_idx) + if row_start < 0 or row_end < 0: + continue + + row = content[row_start : row_end + 5] + + # Find all percentage cells in this row (func, line, branch) + cells = list(pct_cell_pattern.finditer(row)) + if len(cells) < 2: + continue + + new_row = row + # Update line coverage cell (second cell, index 1) + if justified_lines > 0 and len(cells) >= 2: + line_cell = cells[1] + covered = int(line_cell.group(3)) + total = int(line_cell.group(4)) + eff_covered = covered + justified_lines + eff_pct = floor_two_decimals(100.0 * eff_covered / total) if total > 0 else 0.0 + color = _get_coverage_color(eff_pct) + old_cell = line_cell.group(0) + new_cell = f"
{eff_pct:>7.2f}% ({eff_covered}/{total})
" + new_row = new_row.replace(old_cell, new_cell) + + # Update branch coverage cell (third cell, index 2) + if justified_branches > 0 and len(cells) >= 3: + branch_cell = cells[2] + covered = int(branch_cell.group(3)) + total = int(branch_cell.group(4)) + eff_covered = covered + justified_branches + eff_pct = floor_two_decimals(100.0 * eff_covered / total) if total > 0 else 0.0 + color = _get_coverage_color(eff_pct) + old_cell = branch_cell.group(0) + new_cell = f"
{eff_pct:>7.2f}% ({eff_covered}/{total})
" + new_row = new_row.replace(old_cell, new_cell) + + if new_row != row: + content = content.replace(row, new_row) + + # Update the TOTALS row + content = _update_totals_row(content, stats) + + with open(index_file, "w", encoding="utf-8") as f: + f.write(content) + + +def _get_coverage_color(pct: float) -> str: + """Return the llvm-cov color class for a coverage percentage.""" + if pct >= 100.0: + return "green" + if pct >= 80.0: + return "yellow" + return "red" + + +def _update_totals_row(content: str, stats: dict[str, Any]) -> str: + """Update the TOTALS row in the index page with effective coverage numbers.""" + # Find the TOTALS row — it's the last row before + totals_idx = content.rfind("Totals") + if totals_idx < 0: + return content + + row_start = content.rfind("", totals_idx) + if row_start < 0 or row_end < 0: + return content + + row = content[row_start : row_end + 5] + + pct_cell_pattern = re.compile(r"
\s*(\d+\.\d+)%\s*\((\d+)/(\d+)\)
") + cells = list(pct_cell_pattern.finditer(row)) + + new_row = row + + # Update line coverage in totals (index 1) + if len(cells) >= 2 and stats.get("justified_lines", 0) > 0: + line_cell = cells[1] + eff_covered = stats["covered_lines"] + stats["justified_lines"] + total = stats["total_instrumented_lines"] + eff_pct = stats["effective_line_coverage_pct"] + color = _get_coverage_color(eff_pct) + old_cell = line_cell.group(0) + new_cell = f"
{eff_pct:>7.2f}% ({eff_covered}/{total})
" + new_row = new_row.replace(old_cell, new_cell) + + # Update branch coverage in totals (index 2) + if len(cells) >= 3 and stats.get("justified_branches", 0) > 0: + branch_cell = cells[2] + eff_covered = stats["covered_branches"] + stats["justified_branches"] + total = stats["total_branches"] + eff_pct = stats["effective_branch_coverage_pct"] + color = _get_coverage_color(eff_pct) + old_cell = branch_cell.group(0) + new_cell = f"
{eff_pct:>7.2f}% ({eff_covered}/{total})
" + new_row = new_row.replace(old_cell, new_cell) + + if new_row != row: + content = content.replace(row, new_row) + + return content + + +def find_source_html_files(html_dir: Path) -> list[Path]: + """Find all per-source HTML files (not index.html, style.css, etc.).""" + coverage_dir = html_dir / "coverage" + if not coverage_dir.exists(): + # Some llvm-cov versions put source files directly in html_dir + coverage_dir = html_dir + + files = [] + for html_file in coverage_dir.rglob("*.html"): + if html_file.name in ("index.html",): + continue + files.append(html_file) + return sorted(files) + + +def extract_source_path_from_html(html_file: Path, html_dir: Path) -> str: + """Extract the relative source file path from the HTML file path. + + llvm-cov creates paths like: html_report/coverage/.html + We need to extract the relative path within the project. + """ + rel = str(html_file.relative_to(html_dir)) + # Remove "coverage/" prefix if present + if rel.startswith("coverage/"): + rel = rel[len("coverage/") :] + # Remove .html suffix + if rel.endswith(".html"): + rel = rel[:-5] + return rel + + +def find_matching_justifications( + source_path: str, justified_files: dict[str, dict[str, dict[str, str]]] +) -> dict[int, dict[str, str]]: + """Find justifications that match the given source path. + + The source_path from HTML may be an absolute path or relative. + The justified_files keys are relative to source root. + We match by suffix. + """ + result: dict[int, dict[str, str]] = {} + + for justified_path, line_justifications in justified_files.items(): + if _same_file(source_path, justified_path): + for line_str, justification in line_justifications.items(): + result[int(line_str)] = justification + + return result + + +def _same_file(source_path: str, justified_path: str) -> bool: + """True when one path equals the other or ends with it at a path-component boundary. + + A plain string suffix test would let a justification for ``bar.cpp`` apply + to ``foobar.cpp`` and inflate the effective coverage; the shorter path + must therefore be preceded by ``/`` (or be the whole path). + """ + if source_path == justified_path: + return True + for longer, shorter in ((source_path, justified_path), (justified_path, source_path)): + if shorter and longer.endswith("/" + shorter): + return True + return False + + +def _write_outputs( + output_path: Path, + stats: dict[str, Any], + applied: list[dict[str, Any]], + stale: list[dict[str, Any]], +) -> None: + """Write report.json and the human-readable summary.txt next to it. + + Both HTML backends produce exactly these two files; generate_coverage_html + reads the effective percentage from report.json and displays summary.txt. + """ + report = { + "version": 1, + "summary": stats, + "applied_justifications": applied, + "stale_justifications": stale, + } + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, "w", encoding="utf-8") as f: + json.dump(report, f, indent=2) + write_summary(output_path.parent / "summary.txt", stats, stale) + + +def write_summary(path: Path, stats: dict[str, Any], stale: list[dict[str, Any]]) -> None: + """Write human-readable summary.""" + with open(path, "w", encoding="utf-8") as f: + f.write("Coverage Justification Summary\n") + f.write("=" * 40 + "\n\n") + f.write(f"Total instrumented lines: {stats['total_instrumented_lines']}\n") + f.write(f"Covered lines: {stats['covered_lines']}\n") + f.write(f"Justified lines: {stats['justified_lines']}\n") + f.write(f"Unjustified uncovered: {stats['unjustified_uncovered_lines']}\n") + f.write("\n") + f.write(f"Raw line coverage: {stats['raw_line_coverage_pct']}%\n") + f.write(f"Effective line coverage: {stats['effective_line_coverage_pct']}%\n") + f.write("\n") + if stats.get("total_branches", 0) > 0: + f.write(f"Total branches: {stats['total_branches']}\n") + f.write(f"Covered branches: {stats['covered_branches']}\n") + f.write(f"Justified branches: {stats['justified_branches']}\n") + f.write(f"Raw branch coverage: {stats['raw_branch_coverage_pct']}%\n") + f.write(f"Effective branch coverage: {stats['effective_branch_coverage_pct']}%\n") + f.write("\n") + if stale: + f.write(f"Stale justifications ({len(stale)}):\n") + for s in stale: + f.write(f" - {s['file']}:{s['line']} [{s['id']}]\n") + f.write("\n") + + +def load_manifest(path: Path) -> dict[str, Any]: + """Load the justification manifest JSON.""" + if not path.exists(): + print(f"ERROR: Manifest not found: {path}", file=sys.stderr) + sys.exit(1) + with open(path, encoding="utf-8") as f: + return json.load(f) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + """Parse command-line arguments (``argv`` defaults to ``sys.argv[1:]``).""" + parser = argparse.ArgumentParser(description="Effective coverage calculator and HTML post-processor") + parser.add_argument( + "--html-dir", + type=Path, + required=True, + help="Path to llvm-cov HTML report directory", + ) + parser.add_argument( + "--manifest", + type=Path, + required=True, + help="Path to resolved justification manifest (from justify.py)", + ) + parser.add_argument( + "--output", + type=Path, + required=True, + help="Output path for justification report (JSON)", + ) + parser.add_argument( + "--lcov", + type=Path, + default=None, + help="Optional path to LCOV data file (used for gcovr format totals)", + ) + return parser.parse_args(argv) + + +# ============================================================================= +# Format detection +# ============================================================================= + + +def detect_html_format(html_dir: Path) -> str: + """Detect whether the HTML report was generated by llvm-cov or gcovr. + + Returns 'llvm_cov' or 'gcovr'. + """ + # gcovr produces files named based on --html-details argument. + # We use index.html, so per-source files are index...html + if any(html_dir.glob("index.*.*.html")): + return "gcovr" + if (html_dir / "coverage_details.html").exists(): + return "gcovr" + return "llvm_cov" + + +def _parse_lcov_totals(lcov_path: Path) -> dict[str, tuple[int, int]]: + """Parse coverage totals from an LCOV data file. + + Sums LH/LF (line hit/found) and BRH/BRF (branch hit/found) across all records. + """ + total_lines = 0 + hit_lines = 0 + total_branches = 0 + hit_branches = 0 + + with open(lcov_path, encoding="utf-8", errors="replace") as f: + for line in f: + line = line.strip() + if line.startswith("LF:"): + total_lines += int(line[3:]) + elif line.startswith("LH:"): + hit_lines += int(line[3:]) + elif line.startswith("BRF:"): + total_branches += int(line[4:]) + elif line.startswith("BRH:"): + hit_branches += int(line[4:]) + + return { + "lines": (hit_lines, total_lines), + "branches": (hit_branches, total_branches), + } + + +# ============================================================================= +# gcovr support +# ============================================================================= + + +def _main_gcovr(args: argparse.Namespace, html_dir: Path, justified_files: dict) -> None: + """Main logic for gcovr HTML format (produced by lcov_to_html.py via gcovr).""" + + # Parse coverage totals from LCOV file or gcovr index page. + totals = _parse_lcov_totals(args.lcov) if args.lcov and args.lcov.exists() else _parse_gcovr_index_totals(html_dir) + + raw_covered, raw_total = totals["lines"] + raw_branch_covered, raw_branch_total = totals["branches"] + + # Process each source HTML file + total_justified = 0 + total_stale = 0 + total_justified_branches = 0 + applied_justifications: list[dict[str, Any]] = [] + stale_justifications: list[dict[str, Any]] = [] + per_file_stats: dict[str, dict[str, int]] = {} + + source_html_files = _find_gcovr_source_files(html_dir) + for html_file in source_html_files: + rel_source_path = _extract_gcovr_source_path(html_file) + if not rel_source_path: + continue + + file_justifications = find_matching_justifications(rel_source_path, justified_files) + + file_stats = _process_gcovr_file(html_file, file_justifications, applied_justifications, stale_justifications) + + total_justified += file_stats["justified"] + total_stale += file_stats["stale"] + total_justified_branches += file_stats["justified_branches"] + + if file_stats["justified"] > 0 or file_stats["justified_branches"] > 0: + per_file_stats[rel_source_path] = file_stats + + # Calculate stats + raw_uncovered = raw_total - raw_covered + unjustified_uncovered = raw_uncovered - total_justified + effective_branch_covered = raw_branch_covered + total_justified_branches + + stats = { + "total_instrumented_lines": raw_total, + "covered_lines": raw_covered, + "justified_lines": total_justified, + "unjustified_uncovered_lines": max(0, unjustified_uncovered), + "stale_justifications": total_stale, + "raw_line_coverage_pct": floor_two_decimals(100.0 * raw_covered / raw_total) if raw_total > 0 else 0.0, + "effective_line_coverage_pct": floor_two_decimals(100.0 * (raw_covered + total_justified) / raw_total) + if raw_total > 0 + else 0.0, + "total_branches": raw_branch_total, + "covered_branches": raw_branch_covered, + "justified_branches": total_justified_branches, + "raw_branch_coverage_pct": floor_two_decimals(100.0 * raw_branch_covered / raw_branch_total) + if raw_branch_total > 0 + else 0.0, + "effective_branch_coverage_pct": floor_two_decimals(100.0 * effective_branch_covered / raw_branch_total) + if raw_branch_total > 0 + else 0.0, + } + + # Inject CSS for justified lines + _inject_gcovr_justified_css(html_dir) + + # Update the gcovr index page with effective coverage banner + _update_gcovr_index_page(html_dir, stats) + + _write_outputs(Path(args.output), stats, applied_justifications, stale_justifications) + print( + f"INFO: Effective line coverage: {stats['effective_line_coverage_pct']}% " + f"(raw: {stats['raw_line_coverage_pct']}%, " + f"justified: {stats['justified_lines']} lines, " + f"unjustified uncovered: {stats['unjustified_uncovered_lines']} lines)", + file=sys.stderr, + ) + if stale_justifications: + print( + f"WARNING: {len(stale_justifications)} stale justifications " + f"(lines are actually covered, justification can be removed)", + file=sys.stderr, + ) + + +def _parse_gcovr_index_totals(html_dir: Path) -> dict[str, tuple[int, int]]: + """Parse coverage totals from gcovr's index page. + + gcovr format shows coverage in the summary header with patterns like: + 75.0% + 30 / 40 + """ + index_file = html_dir / "index.html" + if not index_file.exists(): + # Fallback for older naming + index_file = html_dir / "coverage_details.html" + if not index_file.exists(): + return {"lines": (0, 0), "branches": (0, 0)} + + content = index_file.read_text(encoding="utf-8", errors="replace") + + # gcovr >= 6 renders the summary as rows "Lines: | 58.8% | 20 / 0 / 34" + # (Exec / Excl / Total). Read those rows first; the older two-number + # heuristics below stay as a fallback for other gcovr versions. + row_totals = _parse_gcovr_summary_rows(content) + if row_totals is not None: + return row_totals + + # gcovr summary table has rows with line/branch stats. + # Look for the summary div with class "summary" containing coverage percentages. + # Pattern: "N / M" in table cells for covered/total + lines_covered, lines_total = 0, 0 + branches_covered, branches_total = 0, 0 + + # gcovr index uses meter elements with data attributes or text like "N / M" + # The summary section shows: Line Coverage: XX.X% (covered / total) + ratio_pattern = re.compile(r"(\d+)\s*/\s*(\d+)") + + # Find the summary section — gcovr puts line/branch/function stats in order. + # Look for the summary-coverage section + summary_match = re.search(r'class="[^"]*summary[^"]*".*?', content, re.DOTALL) + if summary_match: + summary_text = summary_match.group(0) + ratios = ratio_pattern.findall(summary_text) + # gcovr order: lines, functions, branches (if branches enabled) + if len(ratios) >= 1: + lines_covered, lines_total = int(ratios[0][0]), int(ratios[0][1]) + if len(ratios) >= 3: + branches_covered, branches_total = int(ratios[2][0]), int(ratios[2][1]) + elif len(ratios) >= 2: + # Might be lines then branches (no functions section) + branches_covered, branches_total = int(ratios[1][0]), int(ratios[1][1]) + + if lines_total == 0: + # Fallback: scan the whole page for ratio patterns + all_ratios = ratio_pattern.findall(content) + if len(all_ratios) >= 1: + lines_covered, lines_total = int(all_ratios[0][0]), int(all_ratios[0][1]) + if len(all_ratios) >= 3: + branches_covered, branches_total = int(all_ratios[2][0]), int(all_ratios[2][1]) + + return { + "lines": (lines_covered, lines_total), + "branches": (branches_covered, branches_total), + } + + +_GCOVR_SUMMARY_ROW_RE = ( + r'{label}:\s*]*>[^<]*\s*]*>\s*(\d+)\s*/\s*(\d+)\s*/\s*(\d+)\s*' +) + + +def _parse_gcovr_summary_rows(content: str) -> dict[str, tuple[int, int]] | None: + """Parse gcovr's "Exec / Excl / Total" summary rows; None when absent.""" + lines = re.search(_GCOVR_SUMMARY_ROW_RE.format(label="Lines"), content) + if not lines: + return None + branches = re.search(_GCOVR_SUMMARY_ROW_RE.format(label="Branches"), content) + return { + "lines": (int(lines.group(1)), int(lines.group(3))), + "branches": (int(branches.group(1)), int(branches.group(3))) if branches else (0, 0), + } + + +def _find_gcovr_source_files(html_dir: Path) -> list[Path]: + """Find all per-source HTML files in a gcovr report. + + gcovr --html-details creates files named: + index...html + The index is index.html (no dot-separated parts after "index"). + """ + files = [] + for html_file in sorted(html_dir.glob("index.*.html")): + # Skip function pages (contain ".functions." in name) + if ".functions." in html_file.name: + continue + files.append(html_file) + return files + + +def _extract_gcovr_source_path(html_file: Path) -> str: + """Extract the source file path from a gcovr per-source HTML file. + + gcovr embeds the directory in a "Directory:" table row and the filename + in the Box-header. Combining these gives the full relative source path. + """ + try: + content = html_file.read_text(encoding="utf-8", errors="replace")[:8000] + except OSError: + return "" + + # Extract directory from: Directory:\npath/ + directory = "" + dir_match = re.search(r"Directory:\s*([^<]*)", content) + if dir_match: + directory = dir_match.group(1).strip() + + # Extract filename from the Box-header + filename = "" + name_match = re.search( + r'class="Box-header[^"]*d-flex flex-space-between[^"]*"[^>]*>\s*\n?\s*([^\n<]+)', + content, + ) + if name_match: + filename = name_match.group(1).strip() + + if not filename: + # Fallback: look in + title_match = re.search(r"<title>([^<]+?)(?:\s*-\s*GCC[^<]*)?", content) + if title_match: + filename = title_match.group(1).strip() + + if directory and filename: + return directory + filename + return filename + + +def _process_gcovr_file( + html_file: Path, + justifications: dict[int, dict[str, str]], + applied_justifications: list[dict[str, Any]], + stale_justifications: list[dict[str, Any]], +) -> dict[str, int]: + """Process a single gcovr source HTML file. Modifies it in-place. + + gcovr line format: + + {num} + ... + 5 + source code + + + Coverage classes: + - coveredLine: line is covered (count > 0) + - uncoveredLine: line is not covered (count == 0) + - partialCoveredLine: some branches not taken + - excludedLine: excluded from coverage + """ + file_stats = {"justified": 0, "stale": 0, "justified_branches": 0} + + if not justifications: + return file_stats + + with open(html_file, encoding="utf-8") as f: + content = f.read() + + # Parse line coverage status from gcovr HTML. + # Each source line: + # followed by + line_pattern = re.compile( + r']*>.*?' + r' on lines with branch issues + branch_pattern = re.compile( + r']*>.*?(.*?)', + re.DOTALL, + ) + + line_effective_status: dict[int, str] = {} + lines_with_uncovered_branches: set = set() + + for m in line_pattern.finditer(content): + line_num = int(m.group(1)) + cov_class = m.group(2) + if cov_class == "coveredLine": + line_effective_status[line_num] = "covered" + elif cov_class == "uncoveredLine": + line_effective_status[line_num] = "uncovered" + elif cov_class == "partialCoveredLine": + line_effective_status[line_num] = "covered" + lines_with_uncovered_branches.add(line_num) + + # Also check branch details for not-taken branches + for m in branch_pattern.finditer(content): + line_num = int(m.group(1)) + branch_content = m.group(2) + if "notTakenBranch" in branch_content: + lines_with_uncovered_branches.add(line_num) + + # Determine stale vs applicable justifications + for line_num, justification in justifications.items(): + status = line_effective_status.get(line_num) + has_uncovered_branches = line_num in lines_with_uncovered_branches + if status == "covered" and not has_uncovered_branches: + file_stats["stale"] += 1 + stale_justifications.append( + { + "file": _extract_gcovr_source_path(html_file), + "line": line_num, + "id": justification.get("id", ""), + "reason": "Line is already covered and has no uncovered branches — justification is stale", + } + ) + elif status == "uncovered": + file_stats["justified"] += 1 + applied_justifications.append( + { + "file": _extract_gcovr_source_path(html_file), + "line": line_num, + "id": justification.get("id", ""), + "category": justification.get("category", ""), + } + ) + # Mark the line as justified in the HTML + content = _mark_gcovr_line_justified(content, line_num) + elif status == "covered" and has_uncovered_branches: + file_stats["justified_branches"] += 1 + applied_justifications.append( + { + "file": _extract_gcovr_source_path(html_file), + "line": line_num, + "id": justification.get("id", ""), + "category": justification.get("category", ""), + } + ) + + # Write modified content back + if file_stats["justified"] > 0: + with open(html_file, "w", encoding="utf-8") as f: + f.write(content) + + return file_stats + + +def _mark_gcovr_line_justified(content: str, line_num: int) -> str: + """Replace 'uncoveredLine' with 'justifiedLine' for a specific line in gcovr HTML.""" + # Find the line anchor and replace the coverage class in that row + # Pattern: ...uncoveredLine... (within the same ) + pattern = re.compile( + rf'(]*>.*?)', + re.DOTALL, + ) + match = pattern.search(content) + if match: + original = match.group(0) + modified = original.replace("uncoveredLine", "justifiedLine") + modified = modified.replace("show_uncoveredLine", "show_justifiedLine") + content = content[: match.start()] + modified + content[match.end() :] + return content + + +def _inject_gcovr_justified_css(html_dir: Path) -> None: + """Inject CSS for justified lines into gcovr's stylesheet.""" + # gcovr names its CSS file based on the output filename (coverage_details.css) + css_files = list(html_dir.glob("*.css")) + if not css_files: + return + + justified_css = """ +/* Justified line styling (injected by effective_coverage.py) */ +.justifiedLine { background-color: #ffe4b5 !important; } +.show_justifiedLine { display: table-cell; } +.button_toggle_justifiedLine { background-color: #ffe4b5; border: 1px solid #daa520; } +""" + # Inject into the first CSS file found + with open(css_files[0], "a", encoding="utf-8") as f: + f.write(justified_css) + + +def _update_gcovr_index_page(html_dir: Path, stats: dict[str, Any]) -> None: + """Update the gcovr index page with an effective coverage banner.""" + index_file = html_dir / "index.html" + if not index_file.exists(): + index_file = html_dir / "coverage_details.html" + if not index_file.exists(): + return + + with open(index_file, encoding="utf-8") as f: + content = f.read() + + branch_info = "" + if stats.get("justified_branches", 0) > 0: + branch_info = ( + f" | Effective Branch Coverage: {stats['effective_branch_coverage_pct']}%" + f" (Raw: {stats['raw_branch_coverage_pct']}%, Justified: {stats['justified_branches']} branches)" + ) + + banner = ( + f'
' + f"Effective Line Coverage: {stats['effective_line_coverage_pct']}% " + f"(Raw: {stats['raw_line_coverage_pct']}% | " + f"Justified: {stats['justified_lines']} lines | " + f"Unjustified Uncovered: {stats['unjustified_uncovered_lines']} lines)" + f"{branch_info}" + f"
" + ) + + # Insert before the file listing + if '
" in content: + content = content.replace("", f"{banner}", 1) + + with open(index_file, "w", encoding="utf-8") as f: + f.write(content) + + +if __name__ == "__main__": + main() diff --git a/score_coverage/generate_coverage_html.py b/score_coverage/generate_coverage_html.py new file mode 100644 index 0000000..5704233 --- /dev/null +++ b/score_coverage/generate_coverage_html.py @@ -0,0 +1,404 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Generate the HTML coverage report from `bazel coverage` output and gate it. + +The LLVM pipeline's reporter leaves a zip at bazel-out/_coverage/_coverage_report.dat +containing html_report/, lcov_report/ and text_report/. This tool + +1. extracts the HTML report into the output directory, +2. optionally applies coverage justifications (--yaml) and computes the + effective-coverage metric, +3. writes an optional markdown summary (--summary-md or GITHUB_STEP_SUMMARY), +4. optionally assembles an artifacts tree / zip (--archive-dir / --archive), +5. enforces COVERAGE_THRESHOLD on the gated metric: effective line coverage + when --yaml is given, raw line coverage from the LCOV data otherwise. + +Usage (from the CONSUMER workspace, after `bazel coverage --config=llvm_cov`): + + bazel run @score_coverage//:generate_coverage_html -- \\ + [--yaml ] \\ + [--archive ] [--archive-dir ] \\ + [--platform ] [--testlogs-subdir ] \\ + [--summary-md ] [output-dir] + +Exit codes: + 0 gate passed + 1 gate failed (gated coverage below COVERAGE_THRESHOLD) + 2 the run could not be evaluated (missing/invalid inputs, bad threshold, + justification errors). This is deliberately distinct from 0: a report + that cannot be produced must never look like a passing gate. + +Design note: the threshold gate is the one decision downstream safety +arguments rely on, which is why it lives in small pure functions here +(``parse_threshold``, ``raw_line_coverage_from_lcov``, +``effective_line_coverage_from_report``, ``gate_passes``) that are unit tested +independently of Bazel. The comparison uses the UNROUNDED percentage: a +value printed as "100.00" but actually 99.995 must not pass a threshold of +100. +""" + +from __future__ import annotations + +import argparse +import json +import math +import os +import shutil +import sys +import tempfile +import zipfile +from collections.abc import Sequence +from dataclasses import dataclass +from pathlib import Path + +from score_coverage import coverage_summary, effective_coverage, justify + +EXIT_OK = 0 +EXIT_GATE_FAILED = 1 +EXIT_ERROR = 2 + +DEFAULT_THRESHOLD = 100.0 +COVERAGE_REPORT_REL = Path("bazel-out/_coverage/_coverage_report.dat") + + +class GenerateError(Exception): + """A condition under which no verdict can be produced (exit code 2).""" + + +@dataclass +class Options: + """Parsed command line.""" + + yaml: str | None + archive: str | None + archive_dir: str | None + platform: str + testlogs_subdir: str + summary_md: str | None + output_dir: str | None + + +def parse_args(argv: Sequence[str] | None = None) -> Options: + """Parse the command line (``argv`` defaults to ``sys.argv[1:]``).""" + parser = argparse.ArgumentParser( + prog="generate_coverage_html", + description="Extract the LLVM coverage HTML report, apply justifications and gate on the threshold.", + ) + parser.add_argument("--yaml", metavar="PATH", help="Justification YAML, relative to the workspace root.") + parser.add_argument("--archive", metavar="NAME", help="Write an artifacts zip named NAME.zip.") + parser.add_argument("--archive-dir", metavar="DIR", help="Assemble the artifacts tree into DIR (not zipped).") + parser.add_argument( + "--platform", + default="linux", + choices=sorted(justify.VALID_PLATFORMS), + help="Target platform for justification filtering (default: linux).", + ) + parser.add_argument( + "--testlogs-subdir", + default="", + metavar="SUBDIR", + help="Subdirectory of bazel-testlogs to collect JUnit XMLs from when archiving.", + ) + parser.add_argument("--summary-md", metavar="PATH", help="Write the markdown coverage summary to PATH.") + parser.add_argument( + "output_dir", + nargs="?", + help="Directory for the HTML report (default: coverage_).", + ) + ns = parser.parse_args(argv) + return Options( + yaml=ns.yaml, + archive=ns.archive, + archive_dir=ns.archive_dir, + platform=ns.platform, + testlogs_subdir=ns.testlogs_subdir, + summary_md=ns.summary_md, + output_dir=ns.output_dir, + ) + + +# ----------------------------------------------------------------------------- +# Gate primitives (pure, unit tested) +# ----------------------------------------------------------------------------- + + +def parse_threshold(value: str | None) -> float: + """Return the coverage threshold in percent. + + ``None`` or an empty string means the default (100). Anything that is not + a number in [0, 100] is an error: a misspelt threshold must never turn + into a permissive gate. + """ + if value is None or value.strip() == "": + return DEFAULT_THRESHOLD + try: + threshold = float(value) + except ValueError as exc: + raise GenerateError(f"COVERAGE_THRESHOLD must be a number, got {value!r}") from exc + if math.isnan(threshold) or not 0.0 <= threshold <= 100.0: + raise GenerateError(f"COVERAGE_THRESHOLD must be within [0, 100], got {value!r}") + return threshold + + +def raw_line_coverage_from_lcov(lcov_path: Path) -> float: + """Sum LF/LH over all records of an LCOV file and return the percentage. + + The LCOV file (not llvm-cov's text summary) is used on purpose: it + includes the baseline-only records of in-scope files no test links + against, which the text summary omits. A file with no instrumented + lines at all (LF total 0) yields no verdict and is an error. + """ + if not lcov_path.is_file(): + raise GenerateError(f"lcov_report/lcov.dat not found at {lcov_path}") + lines_found = 0 + lines_hit = 0 + with open(lcov_path, encoding="utf-8") as f: + for line in f: + line = line.rstrip("\n") + if line.startswith("LF:"): + lines_found += _lcov_int(line) + elif line.startswith("LH:"): + lines_hit += _lcov_int(line) + if lines_found <= 0: + raise GenerateError(f"could not compute raw line coverage from {lcov_path}: no instrumented lines") + if lines_hit > lines_found: + raise GenerateError(f"corrupt LCOV data in {lcov_path}: LH total {lines_hit} exceeds LF total {lines_found}") + return 100.0 * lines_hit / lines_found + + +def _lcov_int(record: str) -> int: + key, _, value = record.partition(":") + try: + number = int(value) + except ValueError as exc: + raise GenerateError(f"malformed LCOV record {record!r}") from exc + if number < 0: + raise GenerateError(f"malformed LCOV record {record!r}: negative {key}") + return number + + +def effective_line_coverage_from_report(report_path: Path) -> float: + """Read the effective line coverage percentage from effective_coverage's report.json.""" + if not report_path.is_file(): + raise GenerateError(f"effective coverage report was not produced: {report_path}") + try: + with open(report_path, encoding="utf-8") as f: + report = json.load(f) + value = report["summary"]["effective_line_coverage_pct"] + except (json.JSONDecodeError, KeyError, TypeError) as exc: + raise GenerateError( + f"effective coverage report {report_path} is missing summary.effective_line_coverage_pct" + ) from exc + if not isinstance(value, (int, float)) or isinstance(value, bool): + raise GenerateError(f"effective_line_coverage_pct in {report_path} is not a number: {value!r}") + return float(value) + + +def gate_passes(coverage_pct: float, threshold_pct: float) -> bool: + """The gate passes when the (unrounded) coverage reaches the threshold.""" + return coverage_pct >= threshold_pct + + +# ----------------------------------------------------------------------------- +# Steps +# ----------------------------------------------------------------------------- + + +def extract_report(report_zip: Path, extract_dir: Path) -> None: + """Unpack the reporter's zip; it must contain html_report/.""" + if not report_zip.is_file(): + raise GenerateError( + f"Coverage report not found at {report_zip}\n" + " Run 'bazel coverage --config=llvm_cov //... --build_tests_only' first." + ) + if not zipfile.is_zipfile(report_zip): + raise GenerateError( + f"{report_zip} is not the LLVM pipeline zip report.\n" + " Run 'bazel coverage --config=llvm_cov //... --build_tests_only' first." + ) + with zipfile.ZipFile(report_zip) as zf: + zf.extractall(extract_dir) + if not (extract_dir / "html_report").is_dir(): + raise GenerateError(f"html_report/ not found in {report_zip}") + + +def run_justifications( + workspace: Path, yaml_rel: str, platform: str, output_dir: Path, justification_dir: Path +) -> float: + """Resolve justifications, post-process the HTML and return the effective line coverage.""" + yaml_path = workspace / yaml_rel + if not yaml_path.is_file(): + raise GenerateError(f"{yaml_path} not found.") + print("\nRunning coverage justification processing...") + justification_dir.mkdir(parents=True, exist_ok=True) + manifest = justification_dir / "manifest.json" + report = justification_dir / "report.json" + # In-process calls. Both tools call sys.exit(1) on their own errors; that + # is turned into a GenerateError so it exits with EXIT_ERROR (2) and can + # never be mistaken for the gate verdict (0/1). + _call_tool( + "justify", + justify.main, + ["--yaml", str(yaml_path), "--source-root", str(workspace), "--platform", platform, "--output", str(manifest)], + ) + _call_tool( + "effective_coverage", + effective_coverage.main, + ["--html-dir", str(output_dir), "--manifest", str(manifest), "--output", str(report)], + ) + summary_txt = justification_dir / "summary.txt" + if not summary_txt.is_file(): + raise GenerateError("Effective coverage summary was not produced.") + print() + print(summary_txt.read_text(encoding="utf-8"), end="") + return effective_line_coverage_from_report(report) + + +def _call_tool(name: str, entry, argv: list[str]) -> None: + try: + entry(argv) + except SystemExit as exc: + if exc.code not in (None, 0): + raise GenerateError(f"{name} failed with exit code {exc.code}") from exc + + +def write_summary( + workspace: Path, + lcov: Path, + justification_dir: Path | None, + summary_md: str | None, + step_summary: str | None, +) -> None: + """Emit the markdown summary to --summary-md or, failing that, GITHUB_STEP_SUMMARY.""" + args: list[str] = ["--lcov", str(lcov)] + if justification_dir is not None and (justification_dir / "report.json").is_file(): + args += ["--justification-report", str(justification_dir / "report.json")] + if summary_md: + target = Path(summary_md) + if not target.is_absolute(): + target = workspace / target + coverage_summary.main(args + ["--output", str(target)]) + print(f"Coverage summary written to: {target}") + elif step_summary: + coverage_summary.main(args + ["--output", step_summary, "--append"]) + print("Coverage summary appended to GITHUB_STEP_SUMMARY") + + +def assemble_artifacts( + dest: Path, + workspace: Path, + testlogs_subdir: str, + output_dir: Path, + lcov: Path, + justification_dir: Path | None, +) -> None: + """Copy JUnit XMLs (tree preserved), the HTML report, the LCOV and the justification report.""" + dest.mkdir(parents=True, exist_ok=True) + testlogs = workspace / "bazel-testlogs" / testlogs_subdir if testlogs_subdir else workspace / "bazel-testlogs" + if not testlogs.is_dir(): + raise GenerateError(f"test logs directory not found: {testlogs}") + for xml in sorted(testlogs.rglob("test.xml")): + rel = xml.relative_to(workspace) + target = dest / rel + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(xml, target) + shutil.copytree(output_dir, dest / output_dir.name, dirs_exist_ok=True) + if lcov.is_file(): + shutil.copy2(lcov, dest / "coverage_report.dat") + if justification_dir is not None and justification_dir.is_dir(): + shutil.copytree(justification_dir, dest / justification_dir.name, dirs_exist_ok=True) + + +# ----------------------------------------------------------------------------- +# Orchestration +# ----------------------------------------------------------------------------- + + +def run(opts: Options, workspace: Path, environ: dict | None = None) -> int: + """Execute the full flow from ``workspace`` and return the exit code.""" + env = os.environ if environ is None else environ + threshold = parse_threshold(env.get("COVERAGE_THRESHOLD")) + + output_dir = workspace / (opts.output_dir or f"coverage_{opts.platform}") + report_zip = workspace / COVERAGE_REPORT_REL + + with tempfile.TemporaryDirectory(prefix="coverage_extract_") as tmp: + extract_dir = Path(tmp) + extract_report(report_zip, extract_dir) + if output_dir.exists(): + shutil.rmtree(output_dir) + shutil.copytree(extract_dir / "html_report", output_dir) + print(f"Coverage report written to: {output_dir}") + + lcov = extract_dir / "lcov_report" / "lcov.dat" + justification_dir: Path | None = None + if opts.yaml: + justification_dir = extract_dir / "justification_report" + gate_pct = run_justifications(workspace, opts.yaml, opts.platform, output_dir, justification_dir) + gate_kind = "Effective" + else: + print("\nINFO: no --yaml given; justification processing skipped, gating on raw line coverage.") + gate_pct = raw_line_coverage_from_lcov(lcov) + print(f"Raw line coverage: {gate_pct:.2f}%") + gate_kind = "Raw" + + # The summary is emitted BEFORE the gate decides, so a failing gate + # still leaves it on the workflow run page. + write_summary(workspace, lcov, justification_dir, opts.summary_md, env.get("GITHUB_STEP_SUMMARY")) + + if gate_passes(gate_pct, threshold): + rc = EXIT_OK + else: + print( + f"ERROR: {gate_kind} coverage {gate_pct:.2f}% is below threshold {threshold:g}%", + file=sys.stderr, + ) + rc = EXIT_GATE_FAILED + + if opts.archive_dir: + archive_dir = workspace / opts.archive_dir + if archive_dir.exists(): + shutil.rmtree(archive_dir) + assemble_artifacts(archive_dir, workspace, opts.testlogs_subdir, output_dir, lcov, justification_dir) + print(f"Coverage artifacts written to: {opts.archive_dir}/") + + if opts.archive: + tree = workspace / "artifacts" + if tree.exists(): + shutil.rmtree(tree) + assemble_artifacts(tree, workspace, opts.testlogs_subdir, output_dir, lcov, justification_dir) + shutil.make_archive(str(workspace / opts.archive), "zip", root_dir=workspace, base_dir="artifacts") + shutil.rmtree(tree) + print(f"Coverage archive written to: {opts.archive}.zip") + + return rc + + +def main(argv: Sequence[str] | None = None) -> int: + """CLI entry point; returns the process exit code.""" + opts = parse_args(argv) + workspace_env = os.environ.get("BUILD_WORKSPACE_DIRECTORY") + if not workspace_env: + print("ERROR: BUILD_WORKSPACE_DIRECTORY is not set; run this tool via `bazel run`.", file=sys.stderr) + return EXIT_ERROR + workspace = Path(workspace_env) + os.chdir(workspace) + try: + return run(opts, workspace) + except GenerateError as exc: + print(f"ERROR: {exc}", file=sys.stderr) + return EXIT_ERROR + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/score_coverage/justify.py b/score_coverage/justify.py new file mode 100644 index 0000000..39f9014 --- /dev/null +++ b/score_coverage/justify.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Coverage justification processor. + +Parses the YAML justification database and source files for COV_JUSTIFIED markers. +Resolves all justified lines and produces a manifest mapping file:line → justification. + +Usage: + python justify.py --yaml --source-root --output + +Supports two ways to specify justified lines: +1. YAML locations: directly specify file + line ranges in the YAML +2. In-code markers: COV_JUSTIFIED , COV_JUSTIFIED_START / COV_JUSTIFIED_STOP +""" + +import argparse +import json +import re +import sys +from pathlib import Path +from typing import Any, cast + +import yaml + +# Marker patterns +COV_JUSTIFIED_LINE_RE = re.compile(r"COV_JUSTIFIED\s+([\w-]+)") +COV_JUSTIFIED_START_RE = re.compile(r"COV_JUSTIFIED_START\s+([\w-]+)") +COV_JUSTIFIED_STOP_RE = re.compile(r"COV_JUSTIFIED_STOP") + +VALID_CATEGORIES = { + "defensive_programming", + "tool_false_positive", + "platform_specific", + "other", +} + +VALID_PLATFORMS = { + "linux", + "qnx", +} + + +def main(argv: list[str] | None = None) -> None: + """Main entry point. ``argv`` defaults to ``sys.argv[1:]``.""" + args = parse_args(argv) + + justifications_data = load_yaml(args.yaml) + validate_yaml(justifications_data) + justifications_by_id = _justifications_by_id(justifications_data, args.platform) + + resolved, errors = _resolve_yaml_locations(justifications_by_id, Path(args.source_root)) + warnings = _scan_sources(Path(args.source_root), args.file_filter, justifications_by_id, resolved) + _write_manifest(Path(args.output), Path(args.source_root), resolved, warnings, errors) + + # Print diagnostics + total_justified_lines = sum(len(lines) for lines in resolved.values()) + print( + f"INFO: Resolved {total_justified_lines} justified lines across {len(resolved)} files.", + file=sys.stderr, + ) + for w in warnings: + print(f"WARNING: {w}", file=sys.stderr) + if errors: + for e in errors: + print(f"ERROR: {e}", file=sys.stderr) + sys.exit(1) + + +def _justifications_by_id(data: dict[str, Any], platform: str | None) -> dict[str, dict[str, Any]]: + """Index the entries by id, keeping only those that apply to ``platform`` (if given).""" + by_id: dict[str, dict[str, Any]] = {entry["id"]: entry for entry in data.get("justifications", [])} + if platform: + by_id = {jid: entry for jid, entry in by_id.items() if _matches_platform(entry, platform)} + return by_id + + +def _resolve_yaml_locations( + justifications_by_id: dict[str, dict[str, Any]], source_root: Path +) -> tuple[dict[str, dict[int, dict[str, str]]], list[str]]: + """Resolve the explicit ``locations`` of the YAML entries to file -> line -> justification.""" + resolved: dict[str, dict[int, dict[str, str]]] = {} + errors: list[str] = [] + for entry in justifications_by_id.values(): + for location in entry.get("locations", []): + file_path = location["file"] + if not (source_root / file_path).exists(): + errors.append(f"File not found for justification '{entry['id']}': {file_path}") + continue + lines = resolved.setdefault(file_path, {}) + for line in resolve_location_lines(location): + lines[line] = { + "id": entry["id"], + "category": entry["category"], + "reason": entry["reason"].strip(), + } + return resolved, errors + + +def _scan_sources( + source_root: Path, + file_filter: str, + justifications_by_id: dict[str, dict[str, Any]], + resolved: dict[str, dict[int, dict[str, str]]], +) -> list[str]: + """Scan the source tree for COV_JUSTIFIED markers, merging results into ``resolved``.""" + warnings: list[str] = [] + for source_file in collect_source_files(source_root, file_filter): + rel_path = str(source_file.relative_to(source_root)) + scan_warnings, scan_lines = scan_file_for_markers(source_file, rel_path, justifications_by_id) + warnings.extend(scan_warnings) + if scan_lines: + resolved.setdefault(rel_path, {}).update(scan_lines) + return warnings + + +def _write_manifest( + output_path: Path, + source_root: Path, + resolved: dict[str, dict[int, dict[str, str]]], + warnings: list[str], + errors: list[str], +) -> None: + """Write the manifest consumed by effective_coverage (line keys as strings, files sorted).""" + manifest = { + "version": 1, + "source_root": str(source_root), + "justified_files": { + filepath: {str(k): v for k, v in lines.items()} for filepath, lines in sorted(resolved.items()) + }, + "warnings": warnings, + "errors": errors, + } + output_path.parent.mkdir(parents=True, exist_ok=True) + with open(output_path, "w", encoding="utf-8") as f: + json.dump(manifest, f, indent=2) + + +def resolve_location_lines(location: dict[str, Any]) -> list[int]: + """Resolve line numbers from a YAML location entry.""" + if "lines" in location: + return location["lines"] + if "line_start" in location and "line_end" in location: + return list(range(location["line_start"], location["line_end"] + 1)) + if "line" in location: + return [location["line"]] + return [] + + +def _matches_platform(entry: dict[str, Any], platform: str) -> bool: + """Check if a justification entry applies to the given platform. + + The ``platforms`` field is mandatory and validated by ``validate_yaml``. + """ + platforms = entry.get("platforms", []) + return platform in platforms + + +def scan_file_for_markers( + file_path: Path, + rel_path: str, + justifications_by_id: dict[str, dict[str, Any]], +) -> tuple[list[str], dict[int, dict[str, str]]]: + """Scan a source file for COV_JUSTIFIED markers.""" + warnings = [] + justified_lines: dict[int, dict[str, str]] = {} + + try: + with open(file_path, encoding="utf-8", errors="replace") as f: + lines = f.readlines() + except OSError: + return warnings, justified_lines + + region_stack: list[tuple[int, str]] = [] # (start_line, justification_id) + + for line_num, line in enumerate(lines, start=1): + # Check for COV_JUSTIFIED_START + start_match = COV_JUSTIFIED_START_RE.search(line) + if start_match: + jid = start_match.group(1) + if jid not in justifications_by_id: + warnings.append(f"{rel_path}:{line_num}: COV_JUSTIFIED_START references unknown ID '{jid}'") + else: + region_stack.append((line_num, jid)) + continue + + # Check for COV_JUSTIFIED_STOP + stop_match = COV_JUSTIFIED_STOP_RE.search(line) + if stop_match: + if not region_stack: + warnings.append(f"{rel_path}:{line_num}: COV_JUSTIFIED_STOP without matching START") + else: + start_line, jid = region_stack.pop() + if jid in justifications_by_id: + entry = justifications_by_id[jid] + for ln in range(start_line + 1, line_num): + justified_lines[ln] = { + "id": jid, + "category": entry["category"], + "reason": entry["reason"].strip(), + } + continue + + # Check for single-line COV_JUSTIFIED (but not START/STOP) + if "COV_JUSTIFIED_START" not in line and "COV_JUSTIFIED_STOP" not in line: + line_match = COV_JUSTIFIED_LINE_RE.search(line) + if line_match: + jid = line_match.group(1) + if jid not in justifications_by_id: + warnings.append(f"{rel_path}:{line_num}: COV_JUSTIFIED references unknown ID '{jid}'") + else: + entry = justifications_by_id[jid] + justified_lines[line_num] = { + "id": jid, + "category": entry["category"], + "reason": entry["reason"].strip(), + } + + # Check for unclosed regions + for start_line, jid in region_stack: + warnings.append(f"{rel_path}:{start_line}: COV_JUSTIFIED_START '{jid}' without matching STOP") + + return warnings, justified_lines + + +def collect_source_files(source_root: Path, file_filter: str) -> list[Path]: + """Collect source files to scan for markers.""" + extensions = file_filter.split(",") if file_filter else ["cpp", "h", "hpp", "cc", "rs"] + files = [] + for ext in extensions: + for path in source_root.rglob(f"*.{ext.strip()}"): + # Skip Bazel convenience symlinks (bazel-bin, bazel-out, bazel-, ...) + # so the marker scan does not descend into build outputs. + rel_parts = path.relative_to(source_root).parts + if rel_parts and rel_parts[0].startswith("bazel-"): + continue + files.append(path) + return sorted(files) + + +def load_yaml(yaml_path: Path) -> dict[str, Any]: + """Load YAML justification database.""" + if not yaml_path.exists(): + print(f"ERROR: Justification YAML not found: {yaml_path}", file=sys.stderr) + sys.exit(1) + + with open(yaml_path, encoding="utf-8") as f: + content = f.read() + + return yaml.safe_load(content) + + +def validate_yaml(data: Any) -> None: + """Validate the justification YAML structure and types; exit(1) with all findings on failure.""" + try: + errors = _validate_document(data) + except Exception as error: # pylint: disable=broad-exception-caught + # Any malformed shape must end in a validation failure, never in a traceback. + print(f"ERROR: YAML validation: {error}", file=sys.stderr) + sys.exit(1) + if errors: + for e in errors: + print(f"ERROR: YAML validation: {e}", file=sys.stderr) + sys.exit(1) + + +def _validate_document(data: Any) -> list[str]: + """Return all validation errors of the document (empty when valid).""" + if not isinstance(data, dict): + return ["root must be a mapping"] + errors: list[str] = [] + if "version" not in data: + errors.append("Missing 'version' field") + elif not isinstance(data["version"], int): + errors.append(f"'version' must be an integer, got {type(data['version']).__name__}") + if "justifications" not in data: + errors.append("Missing 'justifications' field") + return errors + justifications = data["justifications"] + if not isinstance(justifications, list): + errors.append(f"'justifications' must be a list, got {type(justifications).__name__}") + return errors + seen_ids: set[str] = set() + for i, entry in enumerate(justifications): + errors.extend(_validate_entry(f"justifications[{i}]", entry, seen_ids)) + return errors + + +def _validate_entry(prefix: str, entry: Any, seen_ids: set[str]) -> list[str]: + """Validate one justification entry.""" + if not isinstance(entry, dict): + return [f"{prefix}: must be a mapping, got {type(entry).__name__}"] + if "id" not in entry: + return [f"{prefix}: missing 'id'"] + jid = entry["id"] + if not isinstance(jid, str): + return [f"{prefix}: 'id' must be a string, got {type(jid).__name__}"] + errors: list[str] = [] + if jid in seen_ids: + errors.append(f"{prefix}: duplicate ID '{jid}'") + seen_ids.add(jid) + if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", jid): + errors.append(f"{prefix}: ID '{jid}' must be kebab-case") + errors.extend(_validate_choice(prefix, entry, "category", VALID_CATEGORIES)) + errors.extend(_validate_platforms(prefix, entry)) + errors.extend(_validate_reason(prefix, entry)) + if "locations" in entry: + errors.extend(_validate_locations(prefix, entry["locations"])) + return errors + + +def _validate_choice(prefix: str, entry: dict[str, Any], field: str, valid: set[str]) -> list[str]: + """A mandatory string field restricted to ``valid`` values.""" + if field not in entry: + return [f"{prefix}: missing '{field}'"] + value = entry[field] + if not isinstance(value, str): + return [f"{prefix}: '{field}' must be a string, got {type(value).__name__}"] + if value not in valid: + return [f"{prefix}: invalid {field} '{value}'. Must be one of: {sorted(valid)}"] + return [] + + +def _validate_platforms(prefix: str, entry: dict[str, Any]) -> list[str]: + """``platforms``: a non-empty list of known platform names.""" + if "platforms" not in entry: + return [f"{prefix}: missing 'platforms'"] + platforms = entry["platforms"] + if not isinstance(platforms, list): + return [f"{prefix}: 'platforms' must be a list, got {type(platforms).__name__}"] + if not platforms: + return [f"{prefix}: 'platforms' must not be empty"] + errors: list[str] = [] + for p in platforms: + if not isinstance(p, str): + errors.append(f"{prefix}: 'platforms' entries must be strings, got {type(p).__name__}") + elif p not in VALID_PLATFORMS: + errors.append(f"{prefix}: invalid platform '{p}'. Must be one of: {sorted(VALID_PLATFORMS)}") + return errors + + +def _validate_reason(prefix: str, entry: dict[str, Any]) -> list[str]: + """``reason``: a non-blank string.""" + if "reason" not in entry: + return [f"{prefix}: missing 'reason'"] + reason = entry["reason"] + if not isinstance(reason, str): + return [f"{prefix}: 'reason' must be a string, got {type(reason).__name__}"] + if not reason.strip(): + return [f"{prefix}: 'reason' must not be empty"] + return [] + + +def _validate_locations(prefix: str, locations: Any) -> list[str]: + """``locations``: a list of mappings with a ``file`` and integer line selectors.""" + if not isinstance(locations, list): + return [f"{prefix}: 'locations' must be a list, got {type(locations).__name__}"] + errors: list[str] = [] + for j, loc in enumerate(locations): + loc_prefix = f"{prefix}.locations[{j}]" + if not isinstance(loc, dict): + errors.append(f"{loc_prefix}: must be a mapping, got {type(loc).__name__}") + continue + loc_map = cast(dict[str, Any], loc) # ty cannot narrow Any through isinstance + if "file" not in loc_map: + errors.append(f"{loc_prefix}: missing 'file'") + elif not isinstance(loc_map["file"], str): + errors.append(f"{loc_prefix}: 'file' must be a string, got {type(loc_map['file']).__name__}") + for int_field in ("line", "line_start", "line_end"): + if int_field in loc and not isinstance(loc_map[int_field], int): + errors.append( + f"{loc_prefix}: '{int_field}' must be an integer, got {type(loc_map[int_field]).__name__}" + ) + if "lines" in loc: + if not isinstance(loc_map["lines"], list): + errors.append(f"{loc_prefix}: 'lines' must be a list, got {type(loc_map['lines']).__name__}") + elif not all(isinstance(ln, int) for ln in loc_map["lines"]): + errors.append(f"{loc_prefix}: 'lines' must contain only integers") + return errors + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + """Parse command-line arguments (``argv`` defaults to ``sys.argv[1:]``).""" + parser = argparse.ArgumentParser(description="Coverage justification processor") + parser.add_argument( + "--yaml", + type=Path, + required=True, + help="Path to coverage_justifications.yaml", + ) + parser.add_argument( + "--source-root", + type=Path, + required=True, + help="Root directory of source files", + ) + parser.add_argument( + "--output", + type=Path, + required=True, + help="Output path for resolved justification manifest (JSON)", + ) + parser.add_argument( + "--file-filter", + type=str, + default="cpp,h,hpp,cc,rs", + help="Comma-separated file extensions to scan (default: cpp,h,hpp,cc,rs)", + ) + parser.add_argument( + "--platform", + type=str, + default=None, + choices=sorted(VALID_PLATFORMS), + help="Target platform for filtering justifications (default: all platforms apply)", + ) + return parser.parse_args(argv) + + +if __name__ == "__main__": + main() diff --git a/score_coverage/merger.py b/score_coverage/merger.py new file mode 100644 index 0000000..def16b8 --- /dev/null +++ b/score_coverage/merger.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Per-test coverage output generator using llvm-cov. + +This script is invoked by Bazel as the --coverage_output_generator for each test. +It receives profraw files from test execution, merges them into profdata, generates +an HTML coverage report using llvm-cov show, and packages everything into a zip file +that the reporter can later aggregate. + +Expected Bazel interface (from collect_coverage.sh): + --coverage_dir= Directory containing *.profraw files + --output_file= Where to write the output (zip) + --source_file_manifest= File listing instrumented sources and object files + --filter_sources= Source path regexes to exclude (repeatable) + [--sources_to_replace_file=] Optional source mapping file +""" + +import argparse +import json +import os +import subprocess +import sys +import zipfile +from pathlib import Path + + +def main(argv: list[str] | None = None) -> None: + """Entry point. ``argv`` defaults to ``sys.argv[1:]``.""" + args = parse_args(argv) + + # Get object files from the manifest. + object_files = get_object_files_from_manifest(args.source_file_manifest) + if not object_files: + print("INFO: No instrumented object files found, skipping coverage.", file=sys.stderr) + cleanup_dangling_symlinks(args.coverage_dir) + sys.exit(0) + + # Find profraw files. + profraw_files = sorted(args.coverage_dir.glob("*.profraw")) + if not profraw_files: + print("INFO: No *.profraw files found, skipping coverage.", file=sys.stderr) + cleanup_dangling_symlinks(args.coverage_dir) + sys.exit(0) + + llvm_profdata = find_llvm_profdata() + if not llvm_profdata: + print( + "ERROR: llvm-profdata not found (neither LLVM_PROFDATA nor " + "RUST_LLVM_PROFDATA resolved to an existing binary).", + file=sys.stderr, + ) + sys.exit(1) + + # Merge profraw → profdata. + profdata_dir = args.coverage_dir / "profdata" + profdata_dir.mkdir(exist_ok=True) + profdata_file = profdata_dir / "target.profdata" + + run_command( + [ + llvm_profdata, + "merge", + "--sparse", + "--output", + str(profdata_file), + ] + + [str(f) for f in profraw_files] + ) + + # Create meta.json with object files for the reporter. + meta_dir = args.coverage_dir / "meta" + meta_dir.mkdir(exist_ok=True) + meta = { + "object_files": [os.path.realpath(f) for f in sorted(object_files)], + } + with open(meta_dir / "meta.json", "w", encoding="utf-8") as f: + json.dump(meta, f) + + # Package into zip at output_file. + create_zip( + root=args.coverage_dir, + directories=[profdata_dir, meta_dir], + output_file=args.output_file, + ) + + # Clean up dangling symlinks in coverage_dir that would cause Bazel tree + # artifact validation to fail (e.g. the 'gcov' symlink created by + # collect_cc_coverage.sh's init_gcov() pointing into the destroyed sandbox). + cleanup_dangling_symlinks(args.coverage_dir) + + target = os.environ.get("TEST_TARGET", "unknown") + print(f"INFO: Coverage merger completed for '{target}'", file=sys.stderr) + + +def find_llvm_profdata() -> str: + """Locate the llvm-profdata binary. + + C++ tests: Bazel exports LLVM_PROFDATA from the cc toolchain. + Rust tests: rules_rust exports RUST_LLVM_PROFDATA (an execroot-relative + path to the rust_toolchain's llvm_profdata) instead; resolve it against + the current directory, ROOT and the runfiles dir. + """ + direct = os.environ.get("LLVM_PROFDATA") + if direct and Path(direct).exists(): + return direct + + rust = os.environ.get("RUST_LLVM_PROFDATA") + if rust: + exec_root = Path(os.environ.get("ROOT", ".")) + runfiles_dir = Path(os.environ.get("RUNFILES_DIR", "")) / os.environ.get("TEST_WORKSPACE", "_main") + for candidate in [Path(rust), exec_root / rust, runfiles_dir / rust]: + if candidate.exists(): + return str(candidate) + + return "" + + +def cleanup_dangling_symlinks(directory: Path) -> None: + """Remove symlinks in the coverage directory that would become dangling. + + Bazel's tree artifact validation rejects directories containing dangling + symlinks. The 'gcov' symlink created by collect_cc_coverage.sh's init_gcov() + points into the sandbox which is torn down before validation runs. Since we + use llvm-cov directly, this symlink is not needed. + """ + gcov_link = directory / "gcov" + if gcov_link.is_symlink(): + gcov_link.unlink() + + # Also remove any other symlinks pointing into sandbox paths. + for entry in directory.iterdir(): + if entry.is_symlink(): + target = os.readlink(entry) + if "sandbox" in target: + entry.unlink() + + +def get_object_files_from_manifest(source_file_manifest: Path) -> set[str]: + """Parse the coverage manifest to find instrumented object files.""" + runfiles_dir = Path(os.environ.get("RUNFILES_DIR", "")) / os.environ.get("TEST_WORKSPACE", "_main") + root = os.environ.get("ROOT") + if not root: + # Bazel's coverage collection exports ROOT (the exec root) to the + # LCOV merger action; without it manifest paths cannot be resolved. + print( + "ERROR: ROOT environment variable is not set; the merger must be " + "invoked by Bazel's coverage collection (--coverage_output_generator).", + file=sys.stderr, + ) + sys.exit(1) + exec_root = Path(root) + + object_files = set() + with open(source_file_manifest, encoding="utf-8") as f: + manifests = [line.strip() for line in f.readlines()] + + for manifest in manifests: + if "objects_list.txt" in manifest: + with open(manifest, encoding="utf-8") as f: + for line in f: + obj_path = line.strip() + if not obj_path: + continue + # Try runfiles first, then exec_root. + candidate = runfiles_dir / obj_path + if candidate.exists(): + object_files.add(str(candidate)) + else: + object_files.add(str(exec_root / obj_path)) + else: + # Rust tests: rules_rust lists the instrumented test executable + # itself in the manifest (via coverage metadata_files) instead of + # an objects_list.txt. Pick up manifest entries that are ELF + # binaries directly. Skip external/ entries: the rust_toolchain + # also lists its llvm-cov/llvm-profdata binaries as metadata + # files, and those are not instrumented objects. + if manifest.startswith("external/") or "/external/" in manifest: + continue + for candidate in [runfiles_dir / manifest, exec_root / manifest, Path(manifest)]: + if candidate.is_file() and is_elf(candidate): + object_files.add(str(candidate)) + break + + return object_files + + +def is_elf(path: Path) -> bool: + """Return True if the file at path is an ELF binary.""" + try: + with open(path, "rb") as f: + return f.read(4) == b"\x7fELF" + except OSError: + return False + + +def run_command(cmd: list[str]) -> subprocess.CompletedProcess: + """Run a command and exit on failure.""" + try: + return subprocess.run( + cmd, + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + except subprocess.CalledProcessError as e: + print(f"ERROR: Command failed with code {e.returncode}:", file=sys.stderr) + print(f" {' '.join(cmd)}", file=sys.stderr) + if e.stdout: + print(e.stdout, file=sys.stderr) + sys.exit(1) + + +def create_zip(root: Path, directories: list[Path], output_file: Path) -> None: + """Create a zip file from the given directories relative to root.""" + with zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED) as zf: + for directory in directories: + if not directory.exists(): + continue + for dirpath, _, files in os.walk(directory): + for filename in files: + file_path = Path(dirpath) / filename + arcname = file_path.relative_to(root) + zf.write(file_path, arcname) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + """Parse command-line arguments matching the Bazel LCOV_MERGER interface.""" + parser = argparse.ArgumentParser(description="LLVM coverage merger for Bazel") + parser.add_argument("--coverage_dir", type=Path, required=True) + parser.add_argument("--output_file", type=Path, required=True) + parser.add_argument("--source_file_manifest", type=Path, required=True) + parser.add_argument("--filter_sources", action="append", default=[]) + parser.add_argument("--sources_to_replace_file", type=str, default=None) + return parser.parse_args(argv) + + +if __name__ == "__main__": + main() diff --git a/score_coverage/reporter.py b/score_coverage/reporter.py new file mode 100644 index 0000000..7e9eb29 --- /dev/null +++ b/score_coverage/reporter.py @@ -0,0 +1,765 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Final coverage report generator using llvm-cov. + +This script is invoked by Bazel as the --coverage_report_generator after all tests +complete. It reads the per-test zip files produced by the merger, merges all profdata +into one, and generates the final combined HTML report. + +Expected Bazel interface: + --reports_file= Text file listing paths to all per-test coverage outputs + --output_file= Where to write the final report (zip) +""" + +import argparse +import json +import os +import re +import subprocess +import sys +import zipfile +from pathlib import Path +from typing import Protocol + +from python.runfiles import Runfiles + + +class RunfilesLike(Protocol): + """The part of ``python.runfiles.Runfiles`` this module uses; tests provide fakes.""" + + def Rlocation(self, path: str) -> str | None: # noqa: N802 # pylint: disable=invalid-name + """Resolve a runfiles path to an absolute path, or None.""" + + +def main(argv: list[str] | None = None) -> None: + """Main entry point. ``argv`` defaults to ``sys.argv[1:]``.""" + args = parse_args(argv) + r = Runfiles.Create() + if r is None: + print("ERROR: runfiles are unavailable; the reporter must run as a Bazel coverage action.", file=sys.stderr) + sys.exit(1) + + # Read the list of per-test report files. + reports = read_reports_file(args.reports_file) + if not reports: + print("INFO: No coverage reports listed; writing empty output.", file=sys.stderr) + write_empty_output(args.output_file) + return + + # Extract profdata and object files from each per-test zip. + valid_profdata_files, valid_object_files = extract_reports(reports) + + if not valid_profdata_files or not valid_object_files: + print("INFO: No valid profdata or object files found; writing empty output.", file=sys.stderr) + write_empty_output(args.output_file) + return + + sorted_objects = sorted(valid_object_files) + + # Resolve the llvm tools. The reporter_wrapper passes explicit rlocation + # paths for the consumer-supplied toolchain labels; the bare + # "llvm_toolchain/..." forms remain as a fallback for in-repo setups. + llvm_bin_path = resolve_tool(r, args.llvm_cov, "llvm_toolchain/llvm-cov") + llvm_profdata_path = resolve_tool(r, args.llvm_profdata, "llvm_toolchain/llvm-profdata") + if not llvm_bin_path or not llvm_profdata_path: + print( + "ERROR: llvm-cov/llvm-profdata not found in runfiles. Pass --llvm_cov " + "and --llvm_profdata (the score_coverage_reporter macro does this).", + file=sys.stderr, + ) + sys.exit(1) + + # Merge all per-test profdata files. + merged_profdata = Path.cwd() / "merged_coverage.profdata" + merge_inputs = sorted(set(valid_profdata_files)) + run_command( + [ + str(llvm_profdata_path), + "merge", + "--output", + str(merged_profdata), + ] + + merge_inputs + ) + + # Load baseline objects (production library archives) for zero-coverage baseline. + baseline_objects = load_baseline_objects(r, args.baseline_objects) + + # Rust rlib archives (exposed as .a symlinks by rules_rust) start with a + # lib.rmeta member, which makes llvm-cov reject the whole archive with + # "no coverage data found" even though the .o members carry the covmap. + # Expand such archives into their object members. + baseline_objects = expand_rlib_archives(baseline_objects, Path.cwd() / "rlib_baseline_objects") + + # Determine filter regexes: prefer allowlist-based filtering, fall back to manual regexes. + workspace_root = args.workspace_root + allowlist_files = [] + filter_regexes = [] + baseline_only_archives = [] + baseline_only_files = set() + + if args.coverage_allowlist: + allowlist_files = load_coverage_allowlist(r, args.coverage_allowlist) + if allowlist_files: + print(f"INFO: Using coverage allowlist with {len(allowlist_files)} source files.", file=sys.stderr) + allowlist_set = set(allowlist_files) + + # Get files covered by test binaries. + test_covered_files = get_covered_files(llvm_bin_path, sorted_objects, str(merged_profdata), workspace_root) + print(f"INFO: Test binaries cover {len(test_covered_files)} files.", file=sys.stderr) + + # Get files from baseline archives via a SEPARATE llvm-cov run. + # Combining archives with test binaries in a single llvm-cov invocation + # causes some files to vanish (suspected llvm-cov deduplication issue). + # Some archives may have oversized coverage mappings ("malformed coverage + # data"), so we iteratively remove bad ones. + baseline_files = set() + if baseline_objects: + baseline_files = get_covered_files(llvm_bin_path, baseline_objects, None, workspace_root) + print(f"INFO: Baseline archives contain {len(baseline_files)} files.", file=sys.stderr) + + # Files only in baseline archives (not in any test binary). + baseline_only_files = (baseline_files & allowlist_set) - test_covered_files + baseline_only_archives = [] + if baseline_only_files: + print( + f"INFO: {len(baseline_only_files)} allowlisted files only in baseline " + f"(e.g., {sorted(baseline_only_files)[:5]})", + file=sys.stderr, + ) + # Use all valid baseline archives for LCOV generation. + # The _filter_lcov function will filter to only baseline-only files. + baseline_only_archives = list(baseline_objects) + + # Union of test + baseline for exclude-set calculation. + all_covered_files = test_covered_files | baseline_files + files_to_exclude = all_covered_files - allowlist_set + filter_regexes = [re.escape(f) + "$" for f in sorted(files_to_exclude)] + print(f"INFO: Excluding {len(filter_regexes)} files not in allowlist.", file=sys.stderr) + else: + print("ERROR: Coverage allowlist is empty, falling back to filter_regexes.txt.", file=sys.stderr) + sys.exit(-1) + cxxfilt = find_cxxfilt(llvm_bin_path, r, args.llvm_cxxfilt) + profile = str(merged_profdata) + regexes = sorted(filter_regexes) + + def show_html(objects: list[str]) -> None: + run_llvm_cov_show( + llvm_bin_path, + objects, + profile, + regexes, + workspace_root, + output_format="html", + html_report_dir=html_report_dir, + cxxfilt=cxxfilt, + ) + + # Generate HTML report including baseline-only files when valid archives are available. + html_report_dir = Path.cwd() / "html_report" + if baseline_only_archives: + try: + show_html(sorted_objects + baseline_only_archives) + except SystemExit: + # Some baseline archives caused llvm-cov show to fail; retry with test binaries only. + print( + "WARNING: HTML generation with baseline archives failed; falling back to test-only HTML.", + file=sys.stderr, + ) + show_html(sorted_objects) + else: + show_html(sorted_objects) + + # Rewrite absolute workspace paths in the HTML pages so unpacked report + # archives remain browsable outside the machine that produced them. + _make_html_paths_relative(html_report_dir, workspace_root) + + # Generate LCOV report from test binaries. + lcov_report_dir = Path.cwd() / "lcov_report" + lcov_report_dir.mkdir(exist_ok=True) + lcov_content = run_llvm_cov_export(llvm_bin_path, sorted_objects, profile, regexes, workspace_root).stdout + + # If there are baseline-only files, generate a separate baseline LCOV and merge. + if baseline_only_archives: + # No filtering: only the needed archives are passed. + baseline_lcov = run_llvm_cov_export(llvm_bin_path, baseline_only_archives, None, [], workspace_root) + if baseline_lcov.stdout: + # Filter baseline LCOV to only include baseline-only files. + filtered_baseline = _filter_lcov(baseline_lcov.stdout, baseline_only_files) + if filtered_baseline: + lcov_content += filtered_baseline + print(f"INFO: Merged baseline LCOV for {len(baseline_only_files)} files.", file=sys.stderr) + + # Strip the absolute workspace root from SF: records so the LCOV file is + # portable (IDE gutters, SonarQube, reports produced inside containers). + lcov_content = _make_lcov_paths_relative(lcov_content, workspace_root) + + with open(lcov_report_dir / "lcov.dat", "w", encoding="utf-8") as f: + f.write(lcov_content) + + # Generate text summary. + text_report_dir = Path.cwd() / "text_report" + text_report_dir.mkdir(exist_ok=True) + summary = run_llvm_cov_report(llvm_bin_path, sorted_objects, profile, regexes, workspace_root) + with open(text_report_dir / "summary.txt", "w", encoding="utf-8") as f: + f.write(summary.stdout) + print(summary.stdout, file=sys.stderr) + + # Package everything into the output zip. + directories = [html_report_dir, lcov_report_dir, text_report_dir] + create_zip( + root=Path.cwd(), + directories=directories, + output_file=args.output_file, + ) + + print(f"INFO: Coverage reporter completed. Output: {args.output_file}", file=sys.stderr) + + +def _make_lcov_paths_relative(lcov_content: str, workspace_root: str) -> str: + """Rewrite absolute SF: paths under workspace_root to workspace-relative ones. + + Paths outside the workspace (external deps that survived filtering) are + left unchanged. + """ + prefix = workspace_root if workspace_root.endswith("/") else workspace_root + "/" + sf_prefix = "SF:" + prefix + lines = [] + for line in lcov_content.splitlines(keepends=True): + if line.startswith(sf_prefix): + lines.append("SF:" + line[len(sf_prefix) :]) + else: + lines.append(line) + return "".join(lines) + + +_SOURCE_TITLE_RE = re.compile(r"(
)([^<]*)(
)") + + +def _make_html_paths_relative(html_dir: Path, workspace_root: str) -> None: + """Rewrite absolute workspace paths in llvm-cov HTML page titles. + + Only the source-name-title header text is touched — hrefs and the on-disk + page layout embed the same path components without a leading slash, and a + blanket text replacement would corrupt them. + """ + if not html_dir.exists(): + return + prefix = workspace_root if workspace_root.endswith("/") else workspace_root + "/" + + def _repl(match: "re.Match") -> str: + title = match.group(2) + if title.startswith(prefix): + title = title[len(prefix) :] + return match.group(1) + title + match.group(3) + + for page in html_dir.rglob("*.html"): + text = page.read_text(encoding="utf-8", errors="replace") + new_text = _SOURCE_TITLE_RE.sub(_repl, text) + if new_text != text: + page.write_text(new_text, encoding="utf-8") + + +def _filter_lcov(lcov_content: str, target_files: set) -> str: + """Filter LCOV content to only include records for target files. + + LCOV format: SF: starts a record, end_of_record ends it. + """ + result = [] + current_record = [] + include = False + + for line in lcov_content.splitlines(keepends=True): + if line.startswith("SF:"): + current_record = [line] + filepath = line[3:].strip() + # Check if the file path (or its suffix) matches any target file. + include = any(filepath.endswith(f) for f in target_files) + elif line.strip() == "end_of_record": + current_record.append(line) + if include: + result.extend(current_record) + current_record = [] + include = False + else: + current_record.append(line) + + return "".join(result) + + +def get_covered_files( + llvm_bin_path: Path, + objects: list[str], + instr_profile: str | None, + workspace_root: str, +) -> set: + """Run a quick llvm-cov report to discover all files with coverage data. + + Returns a set of workspace-relative file paths. + """ + cmd = [ + str(llvm_bin_path), + "report", + f"--path-equivalence=/proc/self/cwd/,{workspace_root}", + ] + if instr_profile is None: + cmd.append("--empty-profile") + else: + cmd.extend(["--instr-profile", instr_profile]) + cmd.append(objects[0]) + for obj in objects[1:]: + cmd.extend(["--object", obj]) + + result = run_command(cmd) + if result.returncode != 0: + return set() + + files = set() + in_files = False + for line in result.stdout.splitlines(): + if line.startswith("---"): + in_files = True + continue + if line.startswith("TOTAL"): + break + if not in_files: + continue + # Extract filename (everything before first multi-space + digit sequence) + match = re.match(r"^(.+?)\s{2,}\d+", line) + if match: + filename = match.group(1).strip() + # Normalize to workspace-relative form. llvm-cov report prints the + # raw covmap path: for C++ that is the recorded compilation dir + # /proc/self/cwd/, --path-equivalence does not rewrite the + # DISPLAYED path. Rust covmap paths are already exec-root relative. + for prefix in (workspace_root, "/proc/self/cwd/"): + if filename.startswith(prefix): + filename = filename[len(prefix) :] + break + files.add(filename) + + return files + + +def run_llvm_cov_show( + llvm_bin_path: Path, + objects: list[str], + instr_profile: str | None, + filter_regexes: list[str], + workspace_root: str, + output_format: str, + html_report_dir: Path | None = None, + cxxfilt: str = "", +) -> subprocess.CompletedProcess: + """Run llvm-cov show.""" + cmd = [ + str(llvm_bin_path), + "show", + f"--format={output_format}", + f"--path-equivalence=/proc/self/cwd/,{workspace_root}", + f"--compilation-dir={workspace_root}", + "--show-branches=count", + "--show-region-summary=0", + ] + + if cxxfilt: + cmd.append(f"--Xdemangler={cxxfilt}") + + for regex in filter_regexes: + cmd.append(f"--ignore-filename-regex={regex}") + + if html_report_dir: + cmd.append(f"--output-dir={html_report_dir}") + cmd.append("--coverage-watermark=100,50") + cmd.append("--show-expansions") + + if instr_profile is None: + cmd.append("--empty-profile") + else: + cmd.extend(["--instr-profile", instr_profile]) + cmd.append(objects[0]) + for obj in objects[1:]: + cmd.extend(["--object", obj]) + + return run_command(cmd) + + +def run_llvm_cov_export( + llvm_bin_path: Path, + objects: list[str], + instr_profile: str | None, + filter_regexes: list[str], + workspace_root: str, +) -> subprocess.CompletedProcess: + """Run llvm-cov export to produce LCOV format.""" + cmd = [ + str(llvm_bin_path), + "export", + "--format=lcov", + f"--path-equivalence=/proc/self/cwd/,{workspace_root}", + f"--compilation-dir={workspace_root}", + ] + + for regex in filter_regexes: + cmd.append(f"--ignore-filename-regex={regex}") + + if instr_profile is None: + cmd.append("--empty-profile") + else: + cmd.extend(["--instr-profile", instr_profile]) + cmd.append(objects[0]) + for obj in objects[1:]: + cmd.extend(["--object", obj]) + + # Keep stderr separate: llvm-cov warnings must not end up in the LCOV data. + return run_command(cmd, separate_stderr=True) + + +def run_llvm_cov_report( + llvm_bin_path: Path, + objects: list[str], + instr_profile: str | None, + filter_regexes: list[str], + workspace_root: str, +) -> subprocess.CompletedProcess: + """Run llvm-cov report for a text summary.""" + cmd = [ + str(llvm_bin_path), + "report", + f"--path-equivalence=/proc/self/cwd/,{workspace_root}", + "--show-region-summary=0", + "--show-branch-summary=1", + ] + + for regex in filter_regexes: + cmd.append(f"--ignore-filename-regex={regex}") + + if instr_profile is None: + cmd.append("--empty-profile") + else: + cmd.extend(["--instr-profile", instr_profile]) + cmd.append(objects[0]) + for obj in objects[1:]: + cmd.extend(["--object", obj]) + + return run_command(cmd) + + +def extract_reports(reports: list[str]) -> tuple[set[str], set[str]]: + """Extract profdata and object files from per-test zip files.""" + valid_profdata_files = set() + valid_object_files = set() + + for i, report_path in enumerate(reports): + # Skip baseline_coverage files (LCOV format, not our zip). + if "baseline_coverage" in report_path: + continue + + report = Path(report_path) + if not report.exists() or report.stat().st_size == 0: + continue + + # Check if it's a valid zip. + if not zipfile.is_zipfile(report): + continue + + profdata_name = f"coverage_report_{i:08d}.profdata" + + try: + with zipfile.ZipFile(report, "r") as archive: + # Extract meta. + meta_json = archive.read("meta/meta.json") + target_meta = json.loads(meta_json) + + # Extract profdata. + profdata_content = archive.read("profdata/target.profdata") + profdata_path = Path.cwd() / profdata_name + with open(profdata_path, "wb") as f: + f.write(profdata_content) + + valid_profdata_files.add(str(profdata_path)) + + # Collect object files. + for obj in target_meta.get("object_files", []): + if obj and Path(obj).exists(): + valid_object_files.add(os.path.realpath(obj)) + + except (zipfile.BadZipFile, KeyError, json.JSONDecodeError) as e: + print(f"WARNING: Skipping invalid report {report_path}: {e}", file=sys.stderr) + continue + + return valid_profdata_files, valid_object_files + + +def read_reports_file(reports_file: Path) -> list[str]: + """Read the reports file listing all per-test coverage outputs.""" + with open(reports_file, encoding="utf-8") as f: + return [line.strip() for line in f if line.strip()] + + +def _read_ar_members(path: str) -> list[tuple]: + """Parse a Unix ar archive, returning (name, data_offset, size) tuples. + + Handles the GNU long-name table ("//" member with "/" references). + Returns an empty list when the file is not an ar archive. + """ + members = [] + longnames = b"" + with open(path, "rb") as f: + if f.read(8) != b"!\n": + return [] + while True: + header = f.read(60) + if len(header) < 60: + break + name = header[0:16].decode(errors="replace").rstrip() + try: + size = int(header[48:58].decode().strip() or "0") + except ValueError: + break + data_offset = f.tell() + if name == "//": + longnames = f.read(size) + else: + if name.startswith("/") and name[1:].isdigit(): + start = int(name[1:]) + end = longnames.find(b"\n", start) + name = longnames[start:end].decode(errors="replace").rstrip("/") + elif name.endswith("/"): + name = name[:-1] + members.append((name, data_offset, size)) + f.seek(size, 1) + if size % 2 == 1: + f.seek(1, 1) + return members + + +def expand_rlib_archives(objects: list[str], workdir: Path) -> list[str]: + """Replace Rust rlib archives with their extracted object members. + + llvm-cov rejects rlib archives ("no coverage data found") because of the + leading lib.rmeta member, even though the .o members carry the coverage + mapping. Non-rlib entries (C++ .a archives, executables) pass through + unchanged. + """ + result = [] + extracted = 0 + for obj in objects: + members = _read_ar_members(obj) if obj.endswith((".a", ".rlib")) else [] + if not any(name == "lib.rmeta" for name, _, _ in members): + result.append(obj) + continue + workdir.mkdir(parents=True, exist_ok=True) + with open(obj, "rb") as f: + for index, (name, offset, size) in enumerate(members): + if not name.endswith(".o"): + continue + f.seek(offset) + out_path = workdir / f"{Path(obj).stem}.{index}.o" + out_path.write_bytes(f.read(size)) + result.append(str(out_path)) + extracted += 1 + if extracted: + print(f"INFO: Expanded {extracted} object(s) from Rust rlib baseline archives.", file=sys.stderr) + return result + + +def resolve_tool( + runfiles: RunfilesLike | None, + flag_value: str | None, + fallback_rlocation: str, +) -> Path | None: + """Resolve an llvm tool path. + + Preference order: the explicit rlocation path passed by the + reporter_wrapper (consumer-supplied toolchain label), then the legacy + "llvm_toolchain/..." runfiles location, then the raw value as a plain path. + """ + for candidate in (flag_value, fallback_rlocation): + if not candidate: + continue + if runfiles: + location = runfiles.Rlocation(candidate) + if location and Path(location).exists(): + return Path(location) + if Path(candidate).exists(): + return Path(candidate) + return None + + +def find_cxxfilt( + llvm_bin_path: Path, + runfiles: RunfilesLike | None = None, + explicit: str | None = None, +) -> str: + """Locate llvm-cxxfilt for demangling (C++ Itanium and Rust v0/legacy symbols). + + Tries the explicit rlocation path from the reporter_wrapper first, then the + directory of llvm-cov, then the @llvm_toolchain_llvm distribution via + runfiles (toolchains_llvm declares no alias for llvm-cxxfilt). + Returns an empty string when unavailable (demangling is cosmetic). + """ + if explicit: + resolved = resolve_tool(runfiles, explicit, "") + if resolved: + return str(resolved) + sibling = llvm_bin_path.parent / "llvm-cxxfilt" + if sibling.exists(): + return str(sibling) + r = runfiles or Runfiles.Create() + if r: + location = r.Rlocation("llvm_toolchain_llvm/bin/llvm-cxxfilt") + if location and Path(location).exists(): + return location + return "" + + +def load_coverage_allowlist(runfiles: RunfilesLike, rlocation_path: str) -> list[str]: + """Load coverage allowlist (package paths) from a file via Bazel runfiles.""" + path = runfiles.Rlocation(rlocation_path) + if not path or not Path(path).exists(): + return [] + + lines = Path(path).read_text(encoding="utf-8").splitlines() + return [line.strip() for line in lines if line.strip() and not line.strip().startswith("#")] + + +def load_baseline_objects( + runfiles: RunfilesLike, + rlocation_path: str | None, +) -> list[str]: + """Load baseline object archive paths and resolve them to absolute paths. + + The objects manifest lists relative paths to .a files. When the reporter runs + in the exec config, the manifest paths use the exec config dir + (e.g., k8-opt-exec-*). + """ + if not rlocation_path: + return [] + + path = runfiles.Rlocation(rlocation_path) + if not path or not Path(path).exists(): + print(f"WARNING: Baseline objects manifest not found: {rlocation_path}", file=sys.stderr) + return [] + + lines = Path(path).read_text(encoding="utf-8").splitlines() + resolved = [] + for line in lines: + line = line.strip() + if not line or line.startswith("#"): + continue + # The manifest lists short_paths of files built by the CONSUMER + # repository, which is always the root module ("_main") in a coverage + # run. Do NOT use runfiles.CurrentRepository() here: this script lives + # in score_coverage, so that would resolve against the wrong repo. + path = runfiles.Rlocation(os.path.join("_main", line)) + if path and os.path.exists(path): + resolved.append(path) + else: + print(f"ERROR: Baseline object not found: {line}", file=sys.stderr) + sys.exit(-1) + return sorted(resolved) + + +def run_command(cmd: list[str], separate_stderr: bool = False) -> subprocess.CompletedProcess: + """Run a command and exit on failure. + + With separate_stderr the child's stderr is captured separately and + forwarded to our stderr — required when stdout is machine-consumed data + (LCOV) that llvm-cov warnings must not corrupt. + """ + try: + result = subprocess.run( + cmd, + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE if separate_stderr else subprocess.STDOUT, + text=True, + ) + if separate_stderr and result.stderr: + print(result.stderr, file=sys.stderr) + return result + except subprocess.CalledProcessError as e: + print(f"ERROR: Command failed with code {e.returncode}:", file=sys.stderr) + print(f" {' '.join(cmd[:10])}{'...' if len(cmd) > 10 else ''}", file=sys.stderr) + if e.stdout: + print(e.stdout, file=sys.stderr) + if e.stderr: + print(e.stderr, file=sys.stderr) + sys.exit(1) + + +def write_empty_output(output_file: Path) -> None: + """Write an empty (but valid) zip so Bazel's coverage action still succeeds. + + Matches Bazel's own behaviour for runs that produce no coverage data + (e.g. a coverage invocation whose tests were all filtered out). + """ + with zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED): + pass + + +def create_zip(root: Path, directories: list[Path], output_file: Path) -> None: + """Create a zip file from the given directories relative to root.""" + with zipfile.ZipFile(output_file, "w", zipfile.ZIP_DEFLATED) as zf: + for directory in directories: + if not directory.exists(): + continue + for dirpath, _, files in os.walk(directory): + for filename in files: + file_path = Path(dirpath) / filename + arcname = file_path.relative_to(root) + zf.write(file_path, arcname) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + """Parse command-line arguments matching the Bazel coverage_report_generator interface.""" + parser = argparse.ArgumentParser(description="LLVM coverage reporter for Bazel") + parser.add_argument("--output_file", type=Path, required=True) + parser.add_argument("--reports_file", type=Path, required=True) + parser.add_argument( + "--coverage_allowlist", + type=str, + default=None, + help="Rlocation path to the coverage allowlist file (preferred over filter_regexes)", + ) + parser.add_argument( + "--baseline_objects", + type=str, + default=None, + help="Rlocation path to the baseline objects manifest (archive .a files)", + ) + parser.add_argument( + "--workspace_root", type=str, required=True, help="Real workspace root path for source path mapping" + ) + parser.add_argument( + "--llvm_cov", type=str, default=None, help="Rlocation path to llvm-cov (supplied by score_coverage_reporter)" + ) + parser.add_argument( + "--llvm_profdata", + type=str, + default=None, + help="Rlocation path to llvm-profdata (supplied by score_coverage_reporter)", + ) + parser.add_argument( + "--llvm_cxxfilt", + type=str, + default=None, + help="Rlocation path to llvm-cxxfilt (supplied by score_coverage_reporter)", + ) + return parser.parse_args(argv) + + +if __name__ == "__main__": + main() diff --git a/score_coverage/reporter_wrapper.bzl b/score_coverage/reporter_wrapper.bzl new file mode 100644 index 0000000..204bf2a --- /dev/null +++ b/score_coverage/reporter_wrapper.bzl @@ -0,0 +1,155 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Executable wrapper rule for the coverage reporter. + +Instantiated in the CONSUMER repository (via the score_coverage_reporter +macro) so that the consumer's coverage_scope, MODULE.bazel and LLVM tool +labels can be wired into the reporter, which itself lives in score_coverage. +""" + +def _rlocation_path(ctx, file): + """Return the Runfiles.Rlocation()-compatible path for a Bazel File. + + External-repo files have short_path = "..//" — strip the + "../". Main-workspace files have short_path = "/" — prepend + the workspace name. Required because this rule mixes files from the + consumer repo (_main) and from score_coverage / toolchain repos. + """ + if file.short_path.startswith("../"): + return file.short_path[3:] + return ctx.workspace_name + "/" + file.short_path + +def _reporter_wrapper_impl(ctx): + launcher = ctx.actions.declare_file(ctx.label.name + ".sh") + + reporter = ctx.executable.reporter + module_bazel = ctx.file.module_bazel + coverage_scope = ctx.attr.coverage_scope + allowlist_group = coverage_scope[OutputGroupInfo].allowlist.to_list() + objects_group = coverage_scope[OutputGroupInfo].objects.to_list() + object_files = coverage_scope[OutputGroupInfo].object_files + + if len(allowlist_group) != 1: + fail("coverage_scope must provide exactly one allowlist file") + if len(objects_group) != 1: + fail("coverage_scope must provide exactly one objects manifest file") + + allowlist = allowlist_group[0] + baseline_objects = objects_group[0] + + cxxfilt_line = "" + if ctx.file.llvm_cxxfilt: + cxxfilt_line = ' --llvm_cxxfilt="{}" \\\n'.format( + _rlocation_path(ctx, ctx.file.llvm_cxxfilt), + ) + + # Bazel invokes the coverage report generator from within its coverage + # machinery, where an inherited RUNFILES_DIR may point at ANOTHER tool's + # runfiles tree. Derive our own runfiles directory from $0 first and only + # fall back to the inherited value. + script = """#!/usr/bin/env bash +set -euo pipefail +SELF_RUNFILES_DIR="$(cd "$(dirname "$0")" && pwd)/$(basename "$0").runfiles" +if [[ -d "${{SELF_RUNFILES_DIR}}" ]]; then + RUNFILES_DIR="${{SELF_RUNFILES_DIR}}" +elif [[ -z "${{RUNFILES_DIR:-}}" || ! -d "${{RUNFILES_DIR}}" ]]; then + echo "ERROR: could not locate the reporter_wrapper runfiles directory" >&2 + exit 1 +fi +export RUNFILES_DIR +WORKSPACE_ROOT="$(cd "$(dirname "$(readlink -f "${{RUNFILES_DIR}}/{module_bazel}")")" && pwd)/" +exec "${{RUNFILES_DIR}}/{reporter}" \\ + --coverage_allowlist="{allowlist}" \\ + --baseline_objects="{baseline_objects}" \\ + --workspace_root="${{WORKSPACE_ROOT}}" \\ + --llvm_cov="{llvm_cov}" \\ + --llvm_profdata="{llvm_profdata}" \\ +{cxxfilt_line} "$@" +""".format( + module_bazel = _rlocation_path(ctx, module_bazel), + reporter = _rlocation_path(ctx, reporter), + allowlist = _rlocation_path(ctx, allowlist), + baseline_objects = _rlocation_path(ctx, baseline_objects), + llvm_cov = _rlocation_path(ctx, ctx.file.llvm_cov), + llvm_profdata = _rlocation_path(ctx, ctx.file.llvm_profdata), + cxxfilt_line = cxxfilt_line, + ) + + ctx.actions.write( + output = launcher, + content = script, + is_executable = True, + ) + + direct_files = [ + reporter, + allowlist, + baseline_objects, + module_bazel, + ctx.file.llvm_cov, + ctx.file.llvm_profdata, + ] + if ctx.file.llvm_cxxfilt: + direct_files.append(ctx.file.llvm_cxxfilt) + + runfiles = ctx.runfiles( + files = direct_files, + transitive_files = object_files, + ).merge(ctx.attr.reporter[DefaultInfo].default_runfiles) + for tool in (ctx.attr.llvm_cov, ctx.attr.llvm_profdata, ctx.attr.llvm_cxxfilt): + if tool: + runfiles = runfiles.merge(tool[DefaultInfo].default_runfiles) + + return [DefaultInfo( + executable = launcher, + runfiles = runfiles, + )] + +reporter_wrapper = rule( + implementation = _reporter_wrapper_impl, + executable = True, + attrs = { + "reporter": attr.label( + executable = True, + cfg = "exec", + default = Label("//score_coverage:reporter"), + doc = "The coverage reporter binary (defaults to score_coverage's).", + ), + "coverage_scope": attr.label( + cfg = "target", + mandatory = True, + doc = "A score_coverage_scope target defining the in-scope sources/archives.", + ), + "module_bazel": attr.label( + allow_single_file = True, + mandatory = True, + doc = "The consumer's root MODULE.bazel; used to locate the real workspace root.", + ), + "llvm_cov": attr.label( + allow_single_file = True, + mandatory = True, + doc = "llvm-cov binary, e.g. @llvm_toolchain//:llvm-cov.", + ), + "llvm_profdata": attr.label( + allow_single_file = True, + mandatory = True, + doc = "llvm-profdata binary, e.g. @llvm_toolchain//:llvm-profdata.", + ), + "llvm_cxxfilt": attr.label( + allow_single_file = True, + doc = "Optional llvm-cxxfilt for demangling, e.g. " + + "@llvm_toolchain_llvm//:bin/llvm-cxxfilt.", + ), + }, +) diff --git a/score_coverage/requirements.in b/score_coverage/requirements.in new file mode 100644 index 0000000..c3726e8 --- /dev/null +++ b/score_coverage/requirements.in @@ -0,0 +1 @@ +pyyaml diff --git a/score_coverage/requirements_3_12.txt b/score_coverage/requirements_3_12.txt new file mode 100644 index 0000000..1e80040 --- /dev/null +++ b/score_coverage/requirements_3_12.txt @@ -0,0 +1,81 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# bazel run //coverage:requirements_3_12.update +# +pyyaml==6.0.3 \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ + --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ + --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ + --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ + --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ + --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ + --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ + --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ + --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ + --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ + --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ + --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ + --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ + --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ + --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ + --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ + --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via -r coverage/requirements.in diff --git a/score_coverage/tests/BUILD b/score_coverage/tests/BUILD new file mode 100644 index 0000000..8fe2220 --- /dev/null +++ b/score_coverage/tests/BUILD @@ -0,0 +1,80 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_python//python:defs.bzl", "py_library") +load("@score_tooling//:defs.bzl", "score_py_pytest") + +# Requirement-to-test links: the unittest classes carry @verifies(...) which +# writes PartiallyVerifies/TestType/DerivationTechnique into the JUnit XML that +# docs-as-code turns into testcase needs (gd_req__verification_link_tests_python). +# score_py_pytest runs the unittest classes under pytest with score_tooling's +# attribute plugin and --junitxml=$XML_OUTPUT_FILE. +py_library( + name = "traceability", + srcs = ["traceability.py"], + imports = ["../.."], +) + +score_py_pytest( + name = "merger_test", + srcs = ["merger_test.py"], + deps = [ + ":traceability", + "//score_coverage:merger_lib", + ], +) + +score_py_pytest( + name = "reporter_test", + srcs = ["reporter_test.py"], + deps = [ + ":traceability", + "//score_coverage:reporter_lib", + ], +) + +score_py_pytest( + name = "coverage_summary_test", + srcs = ["coverage_summary_test.py"], + deps = [ + ":traceability", + "//score_coverage:coverage_summary_lib", + ], +) + +score_py_pytest( + name = "generate_coverage_html_test", + srcs = ["generate_coverage_html_test.py"], + deps = [ + ":traceability", + "//score_coverage:generate_coverage_html_lib", + ], +) + +score_py_pytest( + name = "justify_test", + srcs = ["justify_test.py"], + deps = [ + ":traceability", + "//score_coverage:justify_lib", + ], +) + +score_py_pytest( + name = "effective_coverage_test", + srcs = ["effective_coverage_test.py"], + deps = [ + ":traceability", + "//score_coverage:effective_coverage_lib", + ], +) diff --git a/score_coverage/tests/coverage_summary_test.py b/score_coverage/tests/coverage_summary_test.py new file mode 100644 index 0000000..bba82f7 --- /dev/null +++ b/score_coverage/tests/coverage_summary_test.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Unit tests for the markdown coverage summary.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import json +import tempfile +import unittest +from pathlib import Path + +from score_coverage.coverage_summary import ( + directory_key, + load_justification_summary, + parse_lcov, + percent, + progress_bar, + render_markdown, + rollup_by_directory, +) +from score_coverage.tests.traceability import verifies + +LCOV_TWO_FILES = ( + "SF:src/foo/a.cpp\n" + "DA:1,1\nDA:2,0\n" + "BRF:4\nBRH:3\n" + "LF:2\nLH:1\n" + "end_of_record\n" + "SF:rust/main.rs\n" + "DA:1,0\n" + "LF:3\nLH:0\n" + "end_of_record\n" +) + + +def _write(tmp: str, name: str, content: str) -> Path: + p = Path(tmp) / name + p.write_text(content, encoding="utf-8") + return p + + +@verifies("tool_req__coverage_summary_first") +class ParseLcovTest(unittest.TestCase): + def test_missing_file_returns_none(self): + self.assertIsNone(parse_lcov(Path("/nonexistent/lcov.dat"))) + + def test_empty_file_returns_empty_list(self): + with tempfile.TemporaryDirectory() as tmp: + self.assertEqual(parse_lcov(_write(tmp, "e.dat", "")), []) + + def test_line_and_branch_counters(self): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", LCOV_TWO_FILES)) + assert files is not None + self.assertEqual(len(files), 2) + a, main_rs = files + self.assertEqual((a.lines_hit, a.lines_found), (1, 2)) + self.assertEqual((a.branches_hit, a.branches_found), (3, 4)) + self.assertEqual((main_rs.lines_hit, main_rs.lines_found), (0, 3)) + + def test_lf_without_brf_yields_no_branch_data(self): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", "SF:a.cpp\nLF:5\nLH:2\nend_of_record\n")) + assert files is not None + self.assertIsNone(files[0].branches_found) + + def test_brda_fallback_when_no_brf(self): + lcov = "SF:a.cpp\nBRDA:1,0,0,3\nBRDA:1,0,1,-\nBRDA:2,0,0,0\nLF:2\nLH:2\nend_of_record\n" + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", lcov)) + assert files is not None + self.assertEqual((files[0].branches_hit, files[0].branches_found), (1, 3)) + + def test_record_without_end_of_record_is_flushed(self): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", "SF:a.cpp\nLF:1\nLH:1\n")) + assert files is not None + self.assertEqual(len(files), 1) + + def test_non_utf8_bytes_do_not_crash(self): + with tempfile.TemporaryDirectory() as tmp: + p = Path(tmp) / "l.dat" + p.write_bytes(b"SF:src/\xff\xfe.cpp\nLF:1\nLH:0\nend_of_record\n") + files = parse_lcov(p) + assert files is not None + self.assertEqual(len(files), 1) + self.assertEqual(files[0].lines_found, 1) + + +@verifies("tool_req__coverage_summary_first", derivation="boundary-values") +class MathHelpersTest(unittest.TestCase): + def test_percent_zero_denominator_is_none(self): + self.assertIsNone(percent(0, 0)) + self.assertIsNone(percent(5, 0)) + + def test_progress_bar_bounds(self): + self.assertEqual(progress_bar(0.0), "`" + "░" * 10 + "`") + self.assertEqual(progress_bar(100.0), "`" + "█" * 10 + "`") + self.assertEqual(progress_bar(None), "—") + + def test_directory_key_grouping(self): + self.assertEqual(directory_key("a.cpp"), "(root)") + self.assertEqual(directory_key("src/a.cpp"), "src") + self.assertEqual(directory_key("src/foo/a.cpp"), "src/foo") + self.assertEqual(directory_key("src/foo/bar/a.cpp"), "src/foo") + + +@verifies("tool_req__coverage_summary_first") +class RollupTest(unittest.TestCase): + def test_worst_directory_first(self): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", LCOV_TWO_FILES)) + assert files is not None + rows = rollup_by_directory(files) + self.assertEqual(rows[0]["directory"], "rust") + self.assertEqual(rows[0]["pct"], 0.0) + self.assertEqual(rows[1]["directory"], "src/foo") + + +@verifies("tool_req__coverage_summary_first") +class RenderTest(unittest.TestCase): + def _render(self, justification=None): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", LCOV_TWO_FILES)) + assert files is not None + return render_markdown(files, justification) + + def test_empty_input_renders_note(self): + md = render_markdown([], None) + self.assertIn("No coverage records", md) + + def test_overall_table_and_zero_section(self): + md = self._render() + self.assertIn("| Lines | 1 | 5 | 20.00% |", md) + self.assertIn("| Branches | 3 | 4 | 75.00% |", md) + self.assertIn("Files at exact 0% (1)", md) + self.assertIn("`rust/main.rs` (3 lines)", md) + self.assertIn("█", md) # progress bars present + self.assertIn("
", md) + + def test_justification_section(self): + justification = { + "raw_line_coverage_pct": 20.0, + "effective_line_coverage_pct": 40.0, + "raw_branch_coverage_pct": 75.0, + "effective_branch_coverage_pct": 75.0, + "justified_lines": 1, + "justified_branches": 0, + "stale_justifications": 0, + "applied_justification_count": 1, + } + md = self._render(justification) + self.assertIn("Raw vs effective", md) + self.assertIn("| Line coverage | 20.0% | 40.0% |", md) + self.assertIn("1 justification entries applied", md) + + def test_branch_dash_when_no_branch_data(self): + with tempfile.TemporaryDirectory() as tmp: + files = parse_lcov(_write(tmp, "l.dat", "SF:a.cpp\nLF:2\nLH:1\nend_of_record\n")) + assert files is not None + md = render_markdown(files, None) + self.assertIn("| Branches | — | — | — | — |", md) + + +@verifies("tool_req__coverage_summary_first") +class JustificationReportTest(unittest.TestCase): + def test_loads_summary_and_counts_applied(self): + report = { + "version": 1, + "summary": {"raw_line_coverage_pct": 50.0, "justified_lines": 2}, + "applied_justifications": [{"id": "a"}, {"id": "b"}], + } + with tempfile.TemporaryDirectory() as tmp: + p = _write(tmp, "report.json", json.dumps(report)) + summary = load_justification_summary(p) + assert summary is not None + self.assertEqual(summary["applied_justification_count"], 2) + self.assertEqual(summary["justified_lines"], 2) + + def test_malformed_json_returns_none(self): + with tempfile.TemporaryDirectory() as tmp: + p = _write(tmp, "report.json", "{not json") + self.assertIsNone(load_justification_summary(p)) + + +if __name__ == "__main__": + unittest.main() diff --git a/score_coverage/tests/effective_coverage_test.py b/score_coverage/tests/effective_coverage_test.py new file mode 100644 index 0000000..0486971 --- /dev/null +++ b/score_coverage/tests/effective_coverage_test.py @@ -0,0 +1,793 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Unit tests for effective_coverage: arithmetic, llvm-cov HTML post-processing and the report.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import io +import json +import tempfile +import unittest +from contextlib import redirect_stderr, redirect_stdout +from pathlib import Path + +from score_coverage import effective_coverage as ec +from score_coverage.tests.traceability import verifies + + +def _row(line: int, status: str, count: str, code: str) -> str: + """One llvm-cov source table row in the exact shape the module parses.""" + return ( + f"
{line}
" + f"
{count}
" + f"
{code}
\n" + ) + + +def _branch(line: int, col: int, true_covered: bool, false_covered: bool) -> str: + def side(name, covered): + if covered: + return f"{name}: 3" + return f"{name}: 0" + + return ( + f"Branch ({line}:{col}): " + f"[{side('True', true_covered)}, {side('False', false_covered)}]\n" + ) + + +def _pct_cell(covered: int, total: int, color: str = "red") -> str: + pct = 100.0 * covered / total if total else 0.0 + return f"
{pct:>7.2f}% ({covered}/{total})
" + + +def _index_page(files, totals) -> str: + """Minimal llvm-cov index.html: one row per (path, (fc, ft), (lc, lt), (bc, bt)) plus Totals.""" + rows = [] + for path, func, line, branch in files: + rows.append( + f"
{path}
" + f"{_pct_cell(*func)}{_pct_cell(*line)}{_pct_cell(*branch)}\n" + ) + func, line, branch = totals + rows.append( + "
Totals
" + f"{_pct_cell(*func)}{_pct_cell(*line)}{_pct_cell(*branch)}\n" + ) + return "

Coverage Report

" + "".join(rows) + "
" + + +@verifies("tool_req__coverage_eff_metric", derivation="boundary-values") +class FloorTwoDecimalsTest(unittest.TestCase): + def test_never_rounds_up(self): + self.assertEqual(ec.floor_two_decimals(61.7647), 61.76) + self.assertEqual(ec.floor_two_decimals(99.999), 99.99) + self.assertEqual(ec.floor_two_decimals(100.0), 100.0) + self.assertEqual(ec.floor_two_decimals(0.0), 0.0) + + +@verifies("tool_req__coverage_eff_metric") +class ParseIndexPageTotalsTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.html = Path(self.tmp.name) + + def tearDown(self): + self.tmp.cleanup() + + def test_reads_totals_row(self): + (self.html / "index.html").write_text( + _index_page([("src/a.cpp", (1, 2), (10, 20), (2, 4))], ((5, 6), (17, 34), (6, 10))), encoding="utf-8" + ) + totals = ec.parse_index_page_totals(self.html) + self.assertEqual(totals["lines"], (17, 34)) + self.assertEqual(totals["branches"], (6, 10)) + + def test_missing_index_yields_zero_totals_and_warns(self): + err = io.StringIO() + with redirect_stderr(err): + totals = ec.parse_index_page_totals(self.html) + self.assertEqual(totals, {"lines": (0, 0), "branches": (0, 0)}) + self.assertIn("WARNING", err.getvalue()) + + def test_unparseable_index_yields_zero_totals(self): + (self.html / "index.html").write_text("nothing here", encoding="utf-8") + with redirect_stderr(io.StringIO()): + totals = ec.parse_index_page_totals(self.html) + self.assertEqual(totals["lines"], (0, 0)) + + +@verifies("tool_req__coverage_eff_path_match") +class PathHelpersTest(unittest.TestCase): + def test_extract_source_path(self): + html_dir = Path("/r/html") + self.assertEqual( + ec.extract_source_path_from_html(Path("/r/html/coverage/src/a.cpp.html"), html_dir), "src/a.cpp" + ) + self.assertEqual(ec.extract_source_path_from_html(Path("/r/html/src/a.cpp.html"), html_dir), "src/a.cpp") + self.assertEqual( + ec.extract_source_path_from_html(Path("/r/html/coverage/home/u/ws/src/a.cpp.html"), html_dir), + "home/u/ws/src/a.cpp", + ) + + def test_find_source_html_files(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + for rel in [ + "index.html", + "style.css", + "coverage/src/a.cpp.html", + "coverage/src/index.html", + "coverage/rust/lib.rs.html", + ]: + p = root / rel + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text("", encoding="utf-8") + found = [str(f.relative_to(root)) for f in ec.find_source_html_files(root)] + self.assertEqual(found, ["coverage/rust/lib.rs.html", "coverage/src/a.cpp.html"]) + + +@verifies("tool_req__coverage_eff_path_match", derivation="equivalence-classes") +class FindMatchingJustificationsTest(unittest.TestCase): + JUSTIFIED = { + "src/bar.cpp": {"5": {"id": "bar-five"}}, + "lib.rs": {"1": {"id": "lib-one"}}, + } + + def test_exact_and_component_suffix_match(self): + self.assertEqual(ec.find_matching_justifications("src/bar.cpp", self.JUSTIFIED), {5: {"id": "bar-five"}}) + self.assertEqual( + ec.find_matching_justifications("home/u/ws/src/bar.cpp", self.JUSTIFIED), {5: {"id": "bar-five"}} + ) + self.assertEqual(ec.find_matching_justifications("rust/lib.rs", self.JUSTIFIED), {1: {"id": "lib-one"}}) + + def test_shorter_html_path_matches_at_component_boundary(self): + self.assertEqual(ec.find_matching_justifications("bar.cpp", self.JUSTIFIED), {5: {"id": "bar-five"}}) + + def test_partial_basename_does_not_match(self): + # A justification for bar.cpp must never leak into foobar.cpp (would inflate effective coverage). + self.assertEqual(ec.find_matching_justifications("src/foobar.cpp", self.JUSTIFIED), {}) + self.assertEqual(ec.find_matching_justifications("mylib.rs", self.JUSTIFIED), {}) + self.assertEqual(ec.find_matching_justifications("other/xsrc/bar.cpp", self.JUSTIFIED), {}) + + def test_line_keys_become_integers(self): + result = ec.find_matching_justifications("src/bar.cpp", self.JUSTIFIED) + self.assertEqual(list(result), [5]) + + +@verifies("tool_req__coverage_eff_stale", "tool_req__coverage_eff_branch_only", "tool_req__coverage_eff_html") +class ProcessHtmlFileTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.html = Path(self.tmp.name) / "a.cpp.html" + self.applied = [] + self.stale = [] + self.j = {"id": "j-1", "category": "other", "reason": 'it\'s "fine"'} + + def tearDown(self): + self.tmp.cleanup() + + def _process(self, content, justifications): + self.html.write_text(content, encoding="utf-8") + stats = ec.process_html_file(self.html, justifications, self.applied, self.stale) + return stats, self.html.read_text(encoding="utf-8") + + def test_no_justifications_leaves_file_untouched(self): + content = _row(1, "uncovered-line", "0", "x") + stats, after = self._process(content, {}) + self.assertEqual(stats, {"justified": 0, "stale": 0, "justified_branches": 0}) + self.assertEqual(after, content) + + def test_uncovered_justified_line_is_counted_and_restyled(self): + content = _row(1, "covered-line", "3", "a") + _row( + 2, "uncovered-line", "0", "b" + ) + stats, after = self._process(content, {2: self.j}) + self.assertEqual(stats["justified"], 1) + self.assertEqual(stats["stale"], 0) + self.assertIn( + "
J
", after + ) + self.assertIn("class='region justified'", after) + self.assertNotIn("class='region red'", after) + self.assertEqual(self.applied, [{"file": "a.cpp", "line": 2, "id": "j-1", "category": "other"}]) + # Line 1 is untouched. + self.assertIn(_row(1, "covered-line", "3", "a"), after) + + def test_covered_justified_line_is_stale(self): + content = _row(4, "covered-line", "2", "a") + stats, after = self._process(content, {4: self.j}) + self.assertEqual(stats["stale"], 1) + self.assertEqual(stats["justified"], 0) + self.assertEqual(after, content) + self.assertEqual(self.stale[0]["line"], 4) + self.assertEqual(self.stale[0]["id"], "j-1") + + def test_justified_line_not_in_file_is_ignored(self): + content = _row(1, "uncovered-line", "0", "x") + stats, _ = self._process(content, {99: self.j}) + self.assertEqual(stats, {"justified": 0, "stale": 0, "justified_branches": 0}) + self.assertEqual(self.applied, []) + self.assertEqual(self.stale, []) + + def test_covered_in_any_instantiation_counts_as_covered(self): + content = _row(3, "uncovered-line", "0", "t") + _row(3, "covered-line", "1", "t") + stats, _ = self._process(content, {3: self.j}) + self.assertEqual(stats["stale"], 1) + self.assertEqual(stats["justified"], 0) + + def test_uncovered_branch_on_justified_line(self): + content = _row(5, "covered-line", "3", "if (x)") + _branch(5, 9, True, False) + stats, after = self._process(content, {5: self.j}) + self.assertEqual(stats["justified_branches"], 1) + self.assertEqual(stats["stale"], 0) + self.assertEqual(stats["justified"], 0) # the line itself is covered + self.assertIn("class='justified-branch'>False: 0", after) + self.assertEqual(len(self.applied), 1) + + def test_branch_covered_in_one_instantiation_is_not_justified(self): + content = _row(5, "covered-line", "3", "if (x)") + _branch(5, 9, True, False) + _branch(5, 9, True, True) + stats, _ = self._process(content, {5: self.j}) + self.assertEqual(stats["justified_branches"], 0) + self.assertEqual(stats["stale"], 1) # covered line, no truly uncovered branch: nothing left to justify + + def test_both_directions_uncovered_count_two_branches(self): + content = _row(5, "uncovered-line", "0", "if (x)") + _branch(5, 9, False, False) + stats, _ = self._process(content, {5: self.j}) + self.assertEqual(stats["justified"], 1) + self.assertEqual(stats["justified_branches"], 2) + + def test_branches_on_unjustified_lines_untouched(self): + content = _row(5, "covered-line", "3", "if (x)") + _branch(5, 9, True, False) + stats, after = self._process(content, {7: self.j}) + self.assertEqual(stats["justified_branches"], 0) + self.assertIn("class='red branch'>False", after) + + +@verifies("tool_req__coverage_eff_html") +class UpdateIndexPageTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.html = Path(self.tmp.name) + (self.html / "index.html").write_text( + _index_page( + [("src/a.cpp", (1, 2), (5, 10), (1, 4)), ("src/b.cpp", (2, 2), (10, 10), (4, 4))], + ((3, 4), (15, 20), (5, 8)), + ), + encoding="utf-8", + ) + (self.html / "style.css").write_text("body {}\n", encoding="utf-8") + + def tearDown(self): + self.tmp.cleanup() + + def test_banner_per_file_and_totals_updated(self): + stats = { + "total_instrumented_lines": 20, + "covered_lines": 15, + "justified_lines": 3, + "unjustified_uncovered_lines": 2, + "raw_line_coverage_pct": 75.0, + "effective_line_coverage_pct": 90.0, + "total_branches": 8, + "covered_branches": 5, + "justified_branches": 1, + "raw_branch_coverage_pct": 62.5, + "effective_branch_coverage_pct": 75.0, + } + ec.update_index_page(self.html, stats, {"src/a.cpp": {"justified": 3, "stale": 0, "justified_branches": 1}}) + content = (self.html / "index.html").read_text(encoding="utf-8") + self.assertIn("Effective Line Coverage: 90.0%", content) + self.assertIn("Effective Branch Coverage: 75.0%", content) + # per-file row: 5+3 of 10 lines, 1+1 of 4 branches + self.assertIn("
  80.00% (8/10)
", content) + self.assertIn("
  50.00% (2/4)
", content) + # totals row uses the stats' effective numbers + self.assertIn("
  90.00% (18/20)
", content) + self.assertIn("
  75.00% (6/8)
", content) + # untouched file keeps its cell + self.assertIn(_pct_cell(10, 10), content) + + def test_css_injection(self): + ec.inject_justified_css(self.html) + css = (self.html / "style.css").read_text(encoding="utf-8") + self.assertTrue(css.startswith("body {}\n")) + self.assertIn(".justified-line", css) + self.assertIn(".justified-branch", css) + + def test_color_thresholds(self): + self.assertEqual(ec._get_coverage_color(100.0), "green") + self.assertEqual(ec._get_coverage_color(99.99), "yellow") + self.assertEqual(ec._get_coverage_color(80.0), "yellow") + self.assertEqual(ec._get_coverage_color(79.99), "red") + + +@verifies("tool_req__coverage_eff_metric", "tool_req__coverage_eff_stale", "tool_req__coverage_eff_html") +class MainLlvmCovTest(unittest.TestCase): + """End-to-end on a synthetic llvm-cov report: report.json, summary.txt and HTML edits.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + root = Path(self.tmp.name) + self.html = root / "html_report" + (self.html / "coverage" / "src").mkdir(parents=True) + (self.html / "index.html").write_text( + _index_page([("src/a.cpp", (1, 1), (3, 5), (1, 2))], ((1, 1), (3, 5), (1, 2))), encoding="utf-8" + ) + (self.html / "style.css").write_text("body {}\n", encoding="utf-8") + (self.html / "coverage" / "src" / "a.cpp.html").write_text( + _row(1, "covered-line", "1", "a") + + _row(2, "covered-line", "1", "b") + + _row(3, "covered-line", "1", "c") + + _row(4, "uncovered-line", "0", "d") + + _row(5, "uncovered-line", "0", "e"), + encoding="utf-8", + ) + self.manifest = root / "manifest.json" + self.report = root / "just" / "report.json" + + def tearDown(self): + self.tmp.cleanup() + + def _run(self, justified_files): + self.manifest.write_text(json.dumps({"version": 1, "justified_files": justified_files}), encoding="utf-8") + with redirect_stderr(io.StringIO()), redirect_stdout(io.StringIO()): + ec.main(["--html-dir", str(self.html), "--manifest", str(self.manifest), "--output", str(self.report)]) + return json.loads(self.report.read_text(encoding="utf-8")) + + def test_one_justified_line(self): + report = self._run({"src/a.cpp": {"4": {"id": "j-4", "category": "other", "reason": "r"}}}) + s = report["summary"] + self.assertEqual((s["total_instrumented_lines"], s["covered_lines"], s["justified_lines"]), (5, 3, 1)) + self.assertEqual(s["unjustified_uncovered_lines"], 1) + self.assertEqual(s["raw_line_coverage_pct"], 60.0) + self.assertEqual(s["effective_line_coverage_pct"], 80.0) + self.assertEqual(s["total_branches"], 2) + self.assertEqual(report["applied_justifications"][0]["line"], 4) + self.assertEqual(report["stale_justifications"], []) + summary = (self.report.parent / "summary.txt").read_text(encoding="utf-8") + self.assertIn("Justified lines: 1", summary) + self.assertIn("Raw line coverage: 60.0%", summary) + self.assertIn("Effective line coverage: 80.0%", summary) + index = (self.html / "index.html").read_text(encoding="utf-8") + self.assertIn("Effective Line Coverage: 80.0%", index) + self.assertIn("(4/5)", index) + self.assertIn(".justified-line", (self.html / "style.css").read_text(encoding="utf-8")) + page = (self.html / "coverage" / "src" / "a.cpp.html").read_text(encoding="utf-8") + self.assertIn("
J
", page) + + def test_no_justifications_effective_equals_raw(self): + report = self._run({}) + s = report["summary"] + self.assertEqual(s["justified_lines"], 0) + self.assertEqual(s["effective_line_coverage_pct"], s["raw_line_coverage_pct"]) + + def test_stale_justification_is_reported_not_counted(self): + report = self._run({"src/a.cpp": {"1": {"id": "stale-1", "category": "other", "reason": "r"}}}) + s = report["summary"] + self.assertEqual(s["justified_lines"], 0) + self.assertEqual(s["stale_justifications"], 1) + self.assertEqual(s["effective_line_coverage_pct"], 60.0) + self.assertEqual(report["stale_justifications"][0]["id"], "stale-1") + summary = (self.report.parent / "summary.txt").read_text(encoding="utf-8") + self.assertIn("Stale justifications (1):", summary) + + def test_justification_for_other_file_does_not_apply(self): + report = self._run({"src/foo_a.cpp": {"4": {"id": "x", "category": "other", "reason": "r"}}}) + self.assertEqual(report["summary"]["justified_lines"], 0) + + def test_effective_coverage_is_floored(self): + # 3 covered + 1 justified of 5 = 80.0 exactly; use 4/5 -> 3 covered of 5 = 60.0; craft 2/3 case instead + (self.html / "index.html").write_text( + _index_page([("src/a.cpp", (1, 1), (1, 3), (0, 0))], ((1, 1), (1, 3), (0, 0))), encoding="utf-8" + ) + report = self._run({"src/a.cpp": {"4": {"id": "j", "category": "other", "reason": "r"}}}) + s = report["summary"] + self.assertEqual(s["raw_line_coverage_pct"], 33.33) + self.assertEqual(s["effective_line_coverage_pct"], 66.66) # 66.666.. floored, never 66.67 + + def test_missing_manifest_exits(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + ec.main( + [ + "--html-dir", + str(self.html), + "--manifest", + str(self.manifest / "nope"), + "--output", + str(self.report), + ] + ) + + def test_missing_html_dir_exits(self): + self.manifest.write_text(json.dumps({"justified_files": {}}), encoding="utf-8") + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + ec.main( + [ + "--html-dir", + str(self.html / "missing"), + "--manifest", + str(self.manifest), + "--output", + str(self.report), + ] + ) + + +@verifies("tool_req__coverage_eff_gcovr") +class FormatDetectionAndLcovTest(unittest.TestCase): + def test_detect_html_format(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + (root / "index.html").write_text("", encoding="utf-8") + self.assertEqual(ec.detect_html_format(root), "llvm_cov") + (root / "index.a_cpp.0123abcd.html").write_text("", encoding="utf-8") + self.assertEqual(ec.detect_html_format(root), "gcovr") + + def test_parse_lcov_totals(self): + with tempfile.TemporaryDirectory() as tmp: + lcov = Path(tmp) / "lcov.dat" + lcov.write_text( + "SF:a\nLF:10\nLH:4\nBRF:6\nBRH:2\nend_of_record\nSF:b\nLF:5\nLH:5\nend_of_record\n", encoding="utf-8" + ) + totals = ec._parse_lcov_totals(lcov) + self.assertEqual(totals, {"lines": (9, 15), "branches": (2, 6)}) + + +# --------------------------------------------------------------------------- +# gcovr backend (QNX path). The fixtures reproduce the markup gcovr 8.6 emits +# for lcov_to_html.py's --html-details output, taken from a real report of the +# integration workspace. +# --------------------------------------------------------------------------- + + +def _gcovr_index(lines=(20, 0, 34), functions=(4, 0, 7), branches=(6, 0, 10), with_summary=True) -> str: + def row(label, triple): + e, x, t = triple + pct = f"{100.0 * e / t:.1f}%" if t else "-%" + return ( + f' \n {label}:\n' + f' {pct}\n' + f' {e} / {x} / {t}\n \n' + ) + + summary = "" + if with_summary: + summary = ( + '
\n
\n \n' + ' \n
Directory:./
\n
\n
\n' + ' \n \n \n \n' + ' \n \n' + + row("Lines", lines) + + row("Functions", functions) + + row("Branches", branches) + + "
CoverageExec / Excl / Total
\n
\n
\n" + ) + return ( + "\n\n\n
\n" + summary + "
\n" + '
\n
\n' + '
\n' + ' 75.0%\n 12 / 0 / 16\n' + "
\n
\n
\n" + "\n\n" + ) + + +def _gcovr_row(line: int, status: str, count: str, code: str, branches=None) -> str: + """One gcovr source row. ``branches`` is a list of (taken: bool) per branch direction.""" + if branches: + taken = sum(1 for b in branches if b) + details = ( + '
\n' + f' {taken}/{len(branches)}\n' + '
\n' + ) + for i, ok in enumerate(branches): + if ok: + details += ( + f'
✓ Branch 0 → {i} taken 1 time.
\n' + ) + else: + details += ( + f'
✗ Branch 0 → {i} not taken.
\n' + ) + details += "
\n
\n" + else: + details = "" + return ( + ' \n' + f' {line}\n' + f' \n{details} \n' + f' {count}\n' + f' {code}\n' + " \n" + ) + + +def _gcovr_source_page(path: str, rows: str, directory: str = "./") -> str: + return ( + "\n\nGCC Code Coverage Report\n\n" + '\n \n \n' + f" \n \n
Directory:{directory}
\n" + '
\n
\n' + '
Function (File:Line)
\n' + "
\n
\n" + '
\n
\n' + f" {path}\n" + '
\n
\n' + ' \n' + rows + "
\n
\n\n\n" + ) + + +COVERABLE_ROWS = ( + _gcovr_row(17, "coveredLine", "2", "const char* classify(int value) {") + + _gcovr_row(18, "coveredLine", "2", "if (value < 0) {", branches=[True, True]) + + _gcovr_row(19, "coveredLine", "1", 'return "negative";') + + _gcovr_row(20, "coveredLine", "1", "}") + + _gcovr_row(21, "coveredLine", "1", "if (value == 0) {", branches=[True, False]) + + _gcovr_row(22, "coveredLine", "1", 'return "zero";') + + _gcovr_row(23, "coveredLine", "1", "}") + + _gcovr_row(24, "uncoveredLine", "✗", 'return "positive"; // COV_JUSTIFIED itest-positive-branch') + + _gcovr_row(25, "coveredLine", "1", "}") +) + + +class GcovrFixtureMixin: + def _make_gcovr_report(self, with_summary=True): + self.tmp = tempfile.TemporaryDirectory() + self.html = Path(self.tmp.name) / "cpp_coverage_qnx" + self.html.mkdir() + (self.html / "index.html").write_text(_gcovr_index(with_summary=with_summary), encoding="utf-8") + (self.html / "index.css").write_text("body { color: black; }\n", encoding="utf-8") + (self.html / "index.js").write_text("// js\n", encoding="utf-8") + (self.html / "index.functions.html").write_text("functions", encoding="utf-8") + self.page = self.html / "index.coverable.cpp.adc3e3ccca5ac003a7efea58a6f0e095.html" + self.page.write_text(_gcovr_source_page("src/coverable.cpp", COVERABLE_ROWS), encoding="utf-8") + self.uncovered = self.html / "index.uncovered.cpp.e4ac329bbb251afd99e0ac248d5dd32f.html" + self.uncovered.write_text( + _gcovr_source_page( + "src/uncovered.cpp", + _gcovr_row(17, "uncoveredLine", "✗", "int never_called(int value) {") + + _gcovr_row(18, "uncoveredLine", "✗", "if (value > 10) {", branches=[False, False]), + ), + encoding="utf-8", + ) + + +@verifies("tool_req__coverage_eff_gcovr") +class GcovrDetectionAndParsingTest(GcovrFixtureMixin, unittest.TestCase): + def setUp(self): + self._make_gcovr_report() + + def tearDown(self): + self.tmp.cleanup() + + def test_format_detected_by_per_source_naming(self): + self.assertEqual(ec.detect_html_format(self.html), "gcovr") + + def test_source_files_skip_index_and_functions_pages(self): + names = [p.name for p in ec._find_gcovr_source_files(self.html)] + self.assertEqual(names, [self.page.name, self.uncovered.name]) + + def test_source_path_from_directory_and_header(self): + self.assertEqual(ec._extract_gcovr_source_path(self.page), "./src/coverable.cpp") + + def test_source_path_falls_back_to_title(self): + page = self.html / "index.x.cpp.0123.html" + page.write_text( + "x.cpp - GCC Code Coverage Report", encoding="utf-8" + ) + self.assertEqual(ec._extract_gcovr_source_path(page), "x.cpp") + self.assertEqual(ec._extract_gcovr_source_path(self.html / "missing.html"), "") + + def test_index_totals_from_exec_excl_total_rows(self): + totals = ec._parse_gcovr_index_totals(self.html) + self.assertEqual(totals, {"lines": (20, 34), "branches": (6, 10)}) + + def test_index_totals_without_summary_block(self): + (self.html / "index.html").write_text(_gcovr_index(with_summary=False), encoding="utf-8") + totals = ec._parse_gcovr_index_totals(self.html) + # Fallback heuristics see the "12 / 0 / 16" file row: whatever they yield must not be + # a plausible-looking wrong total; the LCOV route (--lcov) is authoritative. + self.assertIn(totals["lines"][1], (0, 16)) + + def test_index_totals_missing_index(self): + (self.html / "index.html").unlink() + self.assertEqual(ec._parse_gcovr_index_totals(self.html), {"lines": (0, 0), "branches": (0, 0)}) + + def test_matching_ignores_leading_dot_slash(self): + result = ec.find_matching_justifications("./src/coverable.cpp", {"src/coverable.cpp": {"24": {"id": "j"}}}) + self.assertEqual(list(result), [24]) + + +@verifies("tool_req__coverage_eff_gcovr", "tool_req__coverage_eff_stale", "tool_req__coverage_eff_branch_only") +class ProcessGcovrFileTest(GcovrFixtureMixin, unittest.TestCase): + def setUp(self): + self._make_gcovr_report() + self.applied = [] + self.stale = [] + + def tearDown(self): + self.tmp.cleanup() + + def _j(self, jid): + return {"id": jid, "category": "other", "reason": "r"} + + def test_uncovered_line_is_justified_and_restyled(self): + before = self.page.read_text(encoding="utf-8") + stats = ec._process_gcovr_file(self.page, {24: self._j("pos")}, self.applied, self.stale) + self.assertEqual(stats, {"justified": 1, "stale": 0, "justified_branches": 0}) + after = self.page.read_text(encoding="utf-8") + self.assertNotEqual(before, after) + self.assertIn('✗', after) + self.assertIn('', after) + self.assertEqual(after.count("uncoveredLine"), 0) + self.assertEqual(self.applied, [{"file": "./src/coverable.cpp", "line": 24, "id": "pos", "category": "other"}]) + + def test_covered_line_without_branch_gap_is_stale(self): + stats = ec._process_gcovr_file(self.page, {19: self._j("stale")}, self.applied, self.stale) + self.assertEqual(stats["stale"], 1) + self.assertEqual(self.stale[0]["line"], 19) + self.assertEqual(self.stale[0]["file"], "./src/coverable.cpp") + + def test_not_taken_branch_makes_justification_branch_only(self): + stats = ec._process_gcovr_file(self.page, {21: self._j("br")}, self.applied, self.stale) + self.assertEqual(stats, {"justified": 0, "stale": 0, "justified_branches": 1}) + self.assertEqual(self.applied[0]["line"], 21) + + def test_fully_taken_branch_line_is_stale(self): + stats = ec._process_gcovr_file(self.page, {18: self._j("x")}, self.applied, self.stale) + self.assertEqual(stats["stale"], 1) + + def test_partial_covered_line_class(self): + page = self.html / "index.p.cpp.0000.html" + page.write_text( + _gcovr_source_page("p.cpp", _gcovr_row(5, "partialCoveredLine", "1", "if (a || b)")), encoding="utf-8" + ) + stats = ec._process_gcovr_file(page, {5: self._j("p")}, self.applied, self.stale) + self.assertEqual(stats["justified_branches"], 1) + + def test_no_justifications_leaves_page_untouched(self): + before = self.page.read_text(encoding="utf-8") + stats = ec._process_gcovr_file(self.page, {}, self.applied, self.stale) + self.assertEqual(stats, {"justified": 0, "stale": 0, "justified_branches": 0}) + self.assertEqual(self.page.read_text(encoding="utf-8"), before) + + def test_unknown_line_is_ignored(self): + stats = ec._process_gcovr_file(self.page, {99: self._j("nope")}, self.applied, self.stale) + self.assertEqual(stats, {"justified": 0, "stale": 0, "justified_branches": 0}) + self.assertEqual((self.applied, self.stale), ([], [])) + + def test_only_the_named_line_is_marked(self): + ec._process_gcovr_file(self.uncovered, {18: self._j("u")}, self.applied, self.stale) + after = self.uncovered.read_text(encoding="utf-8") + self.assertIn('id="l17"', after) + # line 17 stays uncovered, line 18 is justified + row17 = after[after.index('id="l17"') : after.index('id="l18"')] + row18 = after[after.index('id="l18"') :] + self.assertIn("uncoveredLine", row17) + self.assertNotIn("justifiedLine", row17) + self.assertIn("justifiedLine", row18) + + +@verifies("tool_req__coverage_eff_gcovr", "tool_req__coverage_eff_html") +class GcovrIndexAndCssTest(GcovrFixtureMixin, unittest.TestCase): + def setUp(self): + self._make_gcovr_report() + + def tearDown(self): + self.tmp.cleanup() + + def test_css_injected_into_first_stylesheet(self): + ec._inject_gcovr_justified_css(self.html) + css = (self.html / "index.css").read_text(encoding="utf-8") + self.assertTrue(css.startswith("body { color: black; }\n")) + self.assertIn(".justifiedLine", css) + (self.html / "index.css").unlink() + ec._inject_gcovr_justified_css(self.html) # no stylesheet: no-op + + def test_banner_inserted_before_file_list(self): + stats = { + "effective_line_coverage_pct": 64.7, + "raw_line_coverage_pct": 58.82, + "justified_lines": 2, + "unjustified_uncovered_lines": 12, + "justified_branches": 1, + "effective_branch_coverage_pct": 70.0, + "raw_branch_coverage_pct": 60.0, + } + ec._update_gcovr_index_page(self.html, stats) + content = (self.html / "index.html").read_text(encoding="utf-8") + banner_at = content.index("Effective Line Coverage: 64.7%") + self.assertLess(banner_at, content.index('
Path: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content, encoding="utf-8") + return path + + +def _make_workspace( + root: Path, lcov: str = LCOV_25_PERCENT, with_html: bool = True, with_testlogs: bool = True +) -> Path: + """Create a fake consumer workspace with a reporter zip and test logs.""" + report = root / gch.COVERAGE_REPORT_REL + report.parent.mkdir(parents=True, exist_ok=True) + with zipfile.ZipFile(report, "w") as zf: + if with_html: + zf.writestr("html_report/index.html", "report") + zf.writestr("html_report/style.css", "body {}") + zf.writestr("lcov_report/lcov.dat", lcov) + zf.writestr("text_report/summary.txt", "TOTAL 50%") + if with_testlogs: + _write(root / "bazel-testlogs" / "pkg" / "some_test" / "test.xml", "") + _write(root / "bazel-testlogs" / "pkg" / "some_test" / "test.log", "log") + return root + + +def _run(root: Path, argv, environ) -> tuple: + """Run the tool quietly, returning (rc, stdout, stderr).""" + out, err = io.StringIO(), io.StringIO() + with redirect_stdout(out), redirect_stderr(err): + rc = gch.run(gch.parse_args(argv), root, environ) + return rc, out.getvalue(), err.getvalue() + + +@verifies("tool_req__coverage_gate_threshold", derivation="boundary-values") +class ParseThresholdTest(unittest.TestCase): + def test_default_is_100(self): + self.assertEqual(gch.parse_threshold(None), 100.0) + self.assertEqual(gch.parse_threshold(""), 100.0) + self.assertEqual(gch.parse_threshold(" "), 100.0) + + def test_numbers(self): + self.assertEqual(gch.parse_threshold("85"), 85.0) + self.assertEqual(gch.parse_threshold("99.5"), 99.5) + self.assertEqual(gch.parse_threshold("0"), 0.0) + self.assertEqual(gch.parse_threshold("100"), 100.0) + + def test_garbage_is_an_error_not_a_permissive_gate(self): + for bad in ["abc", "85%", "1e999", "nan", "-1", "100.01", "inf"]: + with self.subTest(bad=bad), self.assertRaises(gch.GenerateError): + gch.parse_threshold(bad) + + +@verifies("tool_req__coverage_gate_metric", "tool_req__coverage_gate_no_verdict") +class RawLineCoverageTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + + def tearDown(self): + self.tmp.cleanup() + + def test_sums_all_records(self): + lcov = _write(self.root / "lcov.dat", LCOV_25_PERCENT) + self.assertAlmostEqual(gch.raw_line_coverage_from_lcov(lcov), 25.0) + + def test_baseline_only_records_count_towards_the_denominator(self): + lcov = _write(self.root / "lcov.dat", "SF:a\nLF:1\nLH:1\nend_of_record\nSF:b\nLF:1\nLH:0\nend_of_record\n") + self.assertAlmostEqual(gch.raw_line_coverage_from_lcov(lcov), 50.0) + + def test_result_is_not_rounded(self): + lcov = _write(self.root / "lcov.dat", "SF:a\nLF:200000\nLH:199999\nend_of_record\n") + pct = gch.raw_line_coverage_from_lcov(lcov) + self.assertLess(pct, 100.0) + self.assertEqual(f"{pct:.2f}", "100.00") # the printed value rounds up, the gate value must not + + def test_missing_file(self): + with self.assertRaises(gch.GenerateError): + gch.raw_line_coverage_from_lcov(self.root / "nope.dat") + + def test_no_instrumented_lines_is_an_error(self): + lcov = _write(self.root / "lcov.dat", "SF:a\nLF:0\nLH:0\nend_of_record\n") + with self.assertRaises(gch.GenerateError): + gch.raw_line_coverage_from_lcov(lcov) + empty = _write(self.root / "empty.dat", "") + with self.assertRaises(gch.GenerateError): + gch.raw_line_coverage_from_lcov(empty) + + def test_corrupt_records_are_errors(self): + for content in ["SF:a\nLF:1\nLH:2\nend_of_record\n", "SF:a\nLF:x\nLH:0\n", "SF:a\nLF:5\nLH:-1\n"]: + with self.subTest(content=content): + lcov = _write(self.root / "lcov.dat", content) + with self.assertRaises(gch.GenerateError): + gch.raw_line_coverage_from_lcov(lcov) + + +@verifies("tool_req__coverage_gate_metric", "tool_req__coverage_gate_no_verdict") +class EffectiveLineCoverageTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + + def tearDown(self): + self.tmp.cleanup() + + def _report(self, payload) -> Path: + return _write(self.root / "report.json", json.dumps(payload)) + + def test_reads_summary_value(self): + path = self._report({"summary": {"effective_line_coverage_pct": 61.76}}) + self.assertEqual(gch.effective_line_coverage_from_report(path), 61.76) + + def test_integer_is_accepted(self): + path = self._report({"summary": {"effective_line_coverage_pct": 100}}) + self.assertEqual(gch.effective_line_coverage_from_report(path), 100.0) + + def test_missing_report(self): + with self.assertRaises(gch.GenerateError): + gch.effective_line_coverage_from_report(self.root / "missing.json") + + def test_malformed_reports(self): + for payload in [ + {}, + {"summary": {}}, + {"summary": {"effective_line_coverage_pct": "95"}}, + {"summary": {"effective_line_coverage_pct": None}}, + {"summary": {"effective_line_coverage_pct": True}}, + ]: + with self.subTest(payload=payload), self.assertRaises(gch.GenerateError): + gch.effective_line_coverage_from_report(self._report(payload)) + bad_json = _write(self.root / "report.json", "{not json") + with self.assertRaises(gch.GenerateError): + gch.effective_line_coverage_from_report(bad_json) + + +@verifies("tool_req__coverage_gate_unrounded", derivation="boundary-values") +class GateTest(unittest.TestCase): + def test_boundaries(self): + self.assertTrue(gch.gate_passes(100.0, 100.0)) + self.assertTrue(gch.gate_passes(85.0, 85.0)) + self.assertTrue(gch.gate_passes(0.0, 0.0)) + self.assertFalse(gch.gate_passes(99.995, 100.0)) + self.assertFalse(gch.gate_passes(84.999, 85.0)) + + +@verifies("tool_req__coverage_summary_first", "tool_req__coverage_artifacts") +class ParseArgsTest(unittest.TestCase): + def test_defaults(self): + opts = gch.parse_args([]) + self.assertIsNone(opts.yaml) + self.assertIsNone(opts.archive) + self.assertIsNone(opts.archive_dir) + self.assertEqual(opts.platform, "linux") + self.assertEqual(opts.testlogs_subdir, "") + self.assertIsNone(opts.summary_md) + self.assertIsNone(opts.output_dir) + + def test_all_flags(self): + opts = gch.parse_args( + [ + "--yaml", + "j.yaml", + "--archive", + "cov", + "--archive-dir", + "d", + "--platform", + "qnx", + "--testlogs-subdir", + "score", + "--summary-md", + "s.md", + "out", + ] + ) + self.assertEqual((opts.yaml, opts.archive, opts.archive_dir), ("j.yaml", "cov", "d")) + self.assertEqual( + (opts.platform, opts.testlogs_subdir, opts.summary_md, opts.output_dir), ("qnx", "score", "s.md", "out") + ) + + def test_unknown_platform_rejected(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + gch.parse_args(["--platform", "windows"]) + + +@verifies( + "tool_req__coverage_gate_metric", + "tool_req__coverage_gate_exit_codes", + "tool_req__coverage_summary_first", + "tool_req__coverage_artifacts", +) +class RunWithoutYamlTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = _make_workspace(Path(self.tmp.name)) + + def tearDown(self): + self.tmp.cleanup() + + def test_gate_passes_at_low_threshold_and_writes_html(self): + rc, out, _ = _run(self.root, [], {"COVERAGE_THRESHOLD": "10"}) + self.assertEqual(rc, gch.EXIT_OK) + self.assertTrue((self.root / "coverage_linux" / "index.html").is_file()) + self.assertIn("Raw line coverage: 25.00%", out) + + def test_gate_fails_at_default_threshold(self): + rc, _, err = _run(self.root, [], {}) + self.assertEqual(rc, gch.EXIT_GATE_FAILED) + self.assertIn("Raw coverage 25.00% is below threshold 100%", err) + + def test_gate_fails_exactly_below_threshold(self): + rc, _, _ = _run(self.root, [], {"COVERAGE_THRESHOLD": "25.01"}) + self.assertEqual(rc, gch.EXIT_GATE_FAILED) + rc, _, _ = _run(self.root, [], {"COVERAGE_THRESHOLD": "25"}) + self.assertEqual(rc, gch.EXIT_OK) + + def test_invalid_threshold_is_an_error_before_any_output(self): + with self.assertRaises(gch.GenerateError): + _run(self.root, [], {"COVERAGE_THRESHOLD": "high"}) + self.assertFalse((self.root / "coverage_linux").exists()) + + def test_custom_output_dir_and_platform_default(self): + rc, _, _ = _run(self.root, ["--platform", "qnx"], {"COVERAGE_THRESHOLD": "0"}) + self.assertEqual(rc, gch.EXIT_OK) + self.assertTrue((self.root / "coverage_qnx" / "index.html").is_file()) + rc, _, _ = _run(self.root, ["custom_out"], {"COVERAGE_THRESHOLD": "0"}) + self.assertEqual(rc, gch.EXIT_OK) + self.assertTrue((self.root / "custom_out" / "index.html").is_file()) + + def test_stale_output_dir_is_replaced(self): + _write(self.root / "coverage_linux" / "stale.html", "old") + _run(self.root, [], {"COVERAGE_THRESHOLD": "0"}) + self.assertFalse((self.root / "coverage_linux" / "stale.html").exists()) + + def test_summary_md_is_written_even_when_gate_fails(self): + rc, out, _ = _run(self.root, ["--summary-md", "summary.md"], {}) + self.assertEqual(rc, gch.EXIT_GATE_FAILED) + summary = (self.root / "summary.md").read_text(encoding="utf-8") + self.assertIn("## Coverage summary", summary) + self.assertIn("Coverage summary written to:", out) + + def test_github_step_summary_is_appended_not_overwritten(self): + step = _write(self.root / "step.md", "# existing content\n") + rc, out, _ = _run(self.root, [], {"COVERAGE_THRESHOLD": "0", "GITHUB_STEP_SUMMARY": str(step)}) + self.assertEqual(rc, gch.EXIT_OK) + text = step.read_text(encoding="utf-8") + self.assertTrue(text.startswith("# existing content\n")) + self.assertIn("## Coverage summary", text) + self.assertIn("appended to GITHUB_STEP_SUMMARY", out) + + def test_explicit_summary_md_wins_over_step_summary(self): + step = _write(self.root / "step.md", "# existing content\n") + _run(self.root, ["--summary-md", "s.md"], {"COVERAGE_THRESHOLD": "0", "GITHUB_STEP_SUMMARY": str(step)}) + self.assertEqual(step.read_text(encoding="utf-8"), "# existing content\n") + self.assertTrue((self.root / "s.md").is_file()) + + def test_archive_dir_layout(self): + rc, out, _ = _run( + self.root, ["--archive-dir", "artifacts_dir", "--testlogs-subdir", "pkg"], {"COVERAGE_THRESHOLD": "0"} + ) + self.assertEqual(rc, gch.EXIT_OK) + base = self.root / "artifacts_dir" + for rel in ["coverage_linux/index.html", "coverage_report.dat", "bazel-testlogs/pkg/some_test/test.xml"]: + with self.subTest(rel=rel): + self.assertTrue((base / rel).is_file()) + self.assertFalse((base / "bazel-testlogs/pkg/some_test/test.log").exists()) + self.assertEqual((base / "coverage_report.dat").read_text(encoding="utf-8"), LCOV_25_PERCENT) + self.assertIn("Coverage artifacts written to: artifacts_dir/", out) + + def test_archive_zip_layout(self): + rc, _, _ = _run(self.root, ["--archive", "coverage_artifacts"], {"COVERAGE_THRESHOLD": "0"}) + self.assertEqual(rc, gch.EXIT_OK) + with zipfile.ZipFile(self.root / "coverage_artifacts.zip") as zf: + names = set(zf.namelist()) + self.assertIn("artifacts/coverage_report.dat", names) + self.assertIn("artifacts/coverage_linux/index.html", names) + self.assertIn("artifacts/bazel-testlogs/pkg/some_test/test.xml", names) + self.assertFalse((self.root / "artifacts").exists()) + + def test_archive_is_still_produced_when_gate_fails(self): + rc, _, _ = _run(self.root, ["--archive-dir", "out"], {}) + self.assertEqual(rc, gch.EXIT_GATE_FAILED) + self.assertTrue((self.root / "out" / "coverage_report.dat").is_file()) + + def test_missing_testlogs_when_archiving_is_an_error(self): + with self.assertRaises(gch.GenerateError): + _run( + self.root, ["--archive-dir", "out", "--testlogs-subdir", "does_not_exist"], {"COVERAGE_THRESHOLD": "0"} + ) + + +@verifies("tool_req__coverage_gate_no_verdict", test_type="fault-injection", derivation="error-guessing") +class RunInputValidationTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + + def tearDown(self): + self.tmp.cleanup() + + def test_missing_report(self): + with self.assertRaises(gch.GenerateError): + _run(self.root, [], {"COVERAGE_THRESHOLD": "0"}) + + def test_report_is_not_a_zip(self): + _write(self.root / gch.COVERAGE_REPORT_REL, "TN:\nSF:foo\nend_of_record\n") + with self.assertRaises(gch.GenerateError): + _run(self.root, [], {"COVERAGE_THRESHOLD": "0"}) + + def test_zip_without_html_report(self): + _make_workspace(self.root, with_html=False) + with self.assertRaises(gch.GenerateError): + _run(self.root, [], {"COVERAGE_THRESHOLD": "0"}) + + def test_lcov_with_no_instrumented_lines_yields_no_verdict(self): + _make_workspace(self.root, lcov="SF:a\nLF:0\nLH:0\nend_of_record\n") + with self.assertRaises(gch.GenerateError): + _run(self.root, [], {"COVERAGE_THRESHOLD": "0"}) + + +@verifies( + "tool_req__coverage_gate_metric", + "tool_req__coverage_gate_exit_codes", + "tool_req__coverage_gate_no_verdict", + "tool_req__coverage_artifacts", +) +class RunWithYamlTest(unittest.TestCase): + """The justification layer is faked: these tests cover the orchestration around it.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = _make_workspace(Path(self.tmp.name)) + _write(self.root / "tools" / "coverage" / "coverage_justifications.yaml", "version: 1\njustifications: []\n") + self.calls = [] + + def tearDown(self): + self.tmp.cleanup() + + def _fake_effective(self, pct): + def fake(argv): + self.calls.append(("effective_coverage", argv)) + output = Path(argv[argv.index("--output") + 1]) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text( + json.dumps( + { + "summary": { + "effective_line_coverage_pct": pct, + "raw_line_coverage_pct": 25.0, + "justified_lines": 3, + } + } + ), + encoding="utf-8", + ) + (output.parent / "summary.txt").write_text(f"Effective line coverage: {pct}%\n", encoding="utf-8") + + return fake + + def _fake_justify(self, argv): + self.calls.append(("justify", argv)) + Path(argv[argv.index("--output") + 1]).parent.mkdir(parents=True, exist_ok=True) + Path(argv[argv.index("--output") + 1]).write_text("{}", encoding="utf-8") + + def _run_yaml(self, extra, environ, pct=90.0): + with ( + mock.patch.object(gch.justify, "main", side_effect=self._fake_justify), + mock.patch.object(gch.effective_coverage, "main", side_effect=self._fake_effective(pct)), + ): + return _run(self.root, ["--yaml", "tools/coverage/coverage_justifications.yaml"] + extra, environ) + + def test_gates_on_effective_coverage(self): + rc, out, _ = self._run_yaml([], {"COVERAGE_THRESHOLD": "85"}) + self.assertEqual(rc, gch.EXIT_OK) + self.assertIn("Effective line coverage: 90.0%", out) + rc, _, err = self._run_yaml([], {"COVERAGE_THRESHOLD": "95"}) + self.assertEqual(rc, gch.EXIT_GATE_FAILED) + self.assertIn("Effective coverage 90.00% is below threshold 95%", err) + + def test_tools_receive_workspace_relative_inputs(self): + self._run_yaml(["--platform", "qnx"], {"COVERAGE_THRESHOLD": "0"}) + names = [c[0] for c in self.calls] + self.assertEqual(names, ["justify", "effective_coverage"]) + justify_argv = self.calls[0][1] + self.assertEqual(justify_argv[justify_argv.index("--platform") + 1], "qnx") + self.assertEqual(justify_argv[justify_argv.index("--source-root") + 1], str(self.root)) + self.assertTrue(justify_argv[justify_argv.index("--yaml") + 1].endswith("coverage_justifications.yaml")) + eff_argv = self.calls[1][1] + self.assertEqual(eff_argv[eff_argv.index("--html-dir") + 1], str(self.root / "coverage_qnx")) + + def test_missing_yaml_is_an_error(self): + with mock.patch.object(gch.justify, "main") as justify_main: + with self.assertRaises(gch.GenerateError): + _run(self.root, ["--yaml", "nope.yaml"], {"COVERAGE_THRESHOLD": "0"}) + justify_main.assert_not_called() + + def test_justify_failure_is_an_error_not_a_verdict(self): + def failing(argv): + raise SystemExit(1) + + with mock.patch.object(gch.justify, "main", side_effect=failing), self.assertRaises(gch.GenerateError): + _run(self.root, ["--yaml", "tools/coverage/coverage_justifications.yaml"], {"COVERAGE_THRESHOLD": "0"}) + + def test_missing_summary_is_an_error(self): + def no_summary(argv): + output = Path(argv[argv.index("--output") + 1]) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps({"summary": {"effective_line_coverage_pct": 99.0}}), encoding="utf-8") + + with ( + mock.patch.object(gch.justify, "main", side_effect=self._fake_justify), + mock.patch.object(gch.effective_coverage, "main", side_effect=no_summary), + self.assertRaises(gch.GenerateError), + ): + _run(self.root, ["--yaml", "tools/coverage/coverage_justifications.yaml"], {"COVERAGE_THRESHOLD": "0"}) + + def test_archive_includes_justification_report(self): + rc, _, _ = self._run_yaml(["--archive-dir", "out"], {"COVERAGE_THRESHOLD": "0"}) + self.assertEqual(rc, gch.EXIT_OK) + self.assertTrue((self.root / "out" / "justification_report" / "summary.txt").is_file()) + self.assertTrue((self.root / "out" / "justification_report" / "report.json").is_file()) + + +@verifies("tool_req__coverage_gate_exit_codes") +class MainTest(unittest.TestCase): + def test_requires_build_workspace_directory(self): + with mock.patch.dict("os.environ", {}, clear=True), redirect_stderr(io.StringIO()): + self.assertEqual(gch.main([]), gch.EXIT_ERROR) + + def test_generate_error_maps_to_exit_error(self): + with tempfile.TemporaryDirectory() as tmp: + env = {"BUILD_WORKSPACE_DIRECTORY": tmp, "COVERAGE_THRESHOLD": "0"} + with mock.patch.dict("os.environ", env, clear=True), redirect_stderr(io.StringIO()): + self.assertEqual(gch.main([]), gch.EXIT_ERROR) # no report in an empty workspace + + def test_end_to_end_exit_codes(self): + with tempfile.TemporaryDirectory() as tmp: + _make_workspace(Path(tmp)) + with ( + mock.patch.dict( + "os.environ", {"BUILD_WORKSPACE_DIRECTORY": tmp, "COVERAGE_THRESHOLD": "10"}, clear=True + ), + redirect_stdout(io.StringIO()), + ): + self.assertEqual(gch.main([]), gch.EXIT_OK) + with ( + mock.patch.dict("os.environ", {"BUILD_WORKSPACE_DIRECTORY": tmp}, clear=True), + redirect_stdout(io.StringIO()), + redirect_stderr(io.StringIO()), + ): + self.assertEqual(gch.main([]), gch.EXIT_GATE_FAILED) + + +if __name__ == "__main__": + unittest.main() diff --git a/score_coverage/tests/justify_test.py b/score_coverage/tests/justify_test.py new file mode 100644 index 0000000..3ac4f22 --- /dev/null +++ b/score_coverage/tests/justify_test.py @@ -0,0 +1,422 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Unit tests for justify: YAML validation, marker scanning and manifest generation.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import io +import json +import tempfile +import unittest +from contextlib import redirect_stderr +from pathlib import Path + +from score_coverage import justify +from score_coverage.tests.traceability import verifies + +VALID_ENTRY = { + "id": "defensive-null-check", + "category": "defensive_programming", + "platforms": ["linux"], + "reason": "Cannot be reached: the pointer is validated by the caller.", +} + + +def _valid_yaml(**overrides): + entry = dict(VALID_ENTRY) + entry.update(overrides) + return {"version": 1, "justifications": [entry]} + + +def _validate(data): + """Run validate_yaml quietly; return None on success or the SystemExit code.""" + with redirect_stderr(io.StringIO()): + try: + justify.validate_yaml(data) + except SystemExit as exc: + return exc.code + return None + + +@verifies("tool_req__coverage_just_yaml", derivation="equivalence-classes") +class ValidateYamlTest(unittest.TestCase): + def test_valid_document(self): + self.assertIsNone(_validate(_valid_yaml())) + + def test_valid_with_locations(self): + locations = [ + {"file": "src/a.cpp", "line": 3}, + {"file": "src/a.cpp", "line_start": 10, "line_end": 12}, + {"file": "src/b.rs", "lines": [1, 2, 3]}, + ] + self.assertIsNone(_validate(_valid_yaml(locations=locations))) + + def test_empty_justifications_is_valid(self): + self.assertIsNone(_validate({"version": 1, "justifications": []})) + + def test_root_must_be_mapping(self): + self.assertEqual(_validate(["not", "a", "mapping"]), 1) + self.assertEqual(_validate(None), 1) + + def test_version_field(self): + self.assertEqual(_validate({"justifications": []}), 1) + self.assertEqual(_validate({"version": "1", "justifications": []}), 1) + + def test_justifications_field(self): + self.assertEqual(_validate({"version": 1}), 1) + self.assertEqual(_validate({"version": 1, "justifications": {"a": 1}}), 1) + + def test_entry_shape(self): + self.assertEqual(_validate({"version": 1, "justifications": ["string"]}), 1) + entry = dict(VALID_ENTRY) + del entry["id"] + self.assertEqual(_validate({"version": 1, "justifications": [entry]}), 1) + self.assertEqual(_validate(_valid_yaml(id=42)), 1) + + def test_duplicate_ids(self): + data = {"version": 1, "justifications": [dict(VALID_ENTRY), dict(VALID_ENTRY)]} + self.assertEqual(_validate(data), 1) + + def test_id_must_be_kebab_case(self): + for bad in ["Defensive", "has_underscore", "trailing-", "-leading", "double--dash", "with space", ""]: + with self.subTest(bad=bad): + self.assertEqual(_validate(_valid_yaml(id=bad)), 1) + for good in ["a", "a1", "abc-def-123"]: + with self.subTest(good=good): + self.assertIsNone(_validate(_valid_yaml(id=good))) + + def test_category(self): + entry = dict(VALID_ENTRY) + del entry["category"] + self.assertEqual(_validate({"version": 1, "justifications": [entry]}), 1) + self.assertEqual(_validate(_valid_yaml(category=3)), 1) + self.assertEqual(_validate(_valid_yaml(category="unknown")), 1) + for cat in sorted(justify.VALID_CATEGORIES): + with self.subTest(cat=cat): + self.assertIsNone(_validate(_valid_yaml(category=cat))) + + def test_platforms(self): + entry = dict(VALID_ENTRY) + del entry["platforms"] + self.assertEqual(_validate({"version": 1, "justifications": [entry]}), 1) + self.assertEqual(_validate(_valid_yaml(platforms="linux")), 1) + self.assertEqual(_validate(_valid_yaml(platforms=[])), 1) + self.assertEqual(_validate(_valid_yaml(platforms=[1])), 1) + self.assertEqual(_validate(_valid_yaml(platforms=["windows"])), 1) + self.assertIsNone(_validate(_valid_yaml(platforms=["linux", "qnx"]))) + + def test_reason(self): + entry = dict(VALID_ENTRY) + del entry["reason"] + self.assertEqual(_validate({"version": 1, "justifications": [entry]}), 1) + self.assertEqual(_validate(_valid_yaml(reason=5)), 1) + self.assertEqual(_validate(_valid_yaml(reason=" ")), 1) + + def test_locations(self): + self.assertEqual(_validate(_valid_yaml(locations={"file": "a"})), 1) + self.assertEqual(_validate(_valid_yaml(locations=["a"])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"line": 1}])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"file": 1, "line": 1}])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"file": "a", "line": "1"}])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"file": "a", "line_start": "1", "line_end": 2}])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"file": "a", "lines": 3}])), 1) + self.assertEqual(_validate(_valid_yaml(locations=[{"file": "a", "lines": [1, "2"]}])), 1) + + def test_all_errors_are_reported_together(self): + err = io.StringIO() + entry = {"id": "Bad_Id", "category": "nope", "platforms": [], "reason": ""} + with redirect_stderr(err), self.assertRaises(SystemExit): + justify.validate_yaml({"version": 1, "justifications": [entry]}) + text = err.getvalue() + for fragment in ["kebab-case", "invalid category", "must not be empty", "'reason' must not be empty"]: + self.assertIn(fragment, text) + + +@verifies("tool_req__coverage_just_markers") +class ResolveLocationLinesTest(unittest.TestCase): + def test_explicit_lines(self): + self.assertEqual(justify.resolve_location_lines({"lines": [3, 1, 2]}), [3, 1, 2]) + + def test_range_is_inclusive(self): + self.assertEqual(justify.resolve_location_lines({"line_start": 10, "line_end": 12}), [10, 11, 12]) + + def test_single_line(self): + self.assertEqual(justify.resolve_location_lines({"line": 7}), [7]) + + def test_no_line_information(self): + self.assertEqual(justify.resolve_location_lines({"file": "a"}), []) + + def test_lines_take_precedence(self): + self.assertEqual(justify.resolve_location_lines({"lines": [1], "line": 5}), [1]) + + +@verifies("tool_req__coverage_just_platform") +class MatchesPlatformTest(unittest.TestCase): + def test_platform_membership(self): + entry = {"platforms": ["linux"]} + self.assertTrue(justify._matches_platform(entry, "linux")) + self.assertFalse(justify._matches_platform(entry, "qnx")) + self.assertFalse(justify._matches_platform({}, "linux")) + + +@verifies("tool_req__coverage_just_markers", "tool_req__coverage_just_unknown_id") +class ScanFileForMarkersTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + self.by_id = { + "reason-a": {"id": "reason-a", "category": "other", "reason": " because A "}, + "reason-b": {"id": "reason-b", "category": "platform_specific", "reason": "because B"}, + } + + def tearDown(self): + self.tmp.cleanup() + + def _scan(self, text): + path = self.root / "f.cpp" + path.write_text(text, encoding="utf-8") + return justify.scan_file_for_markers(path, "f.cpp", self.by_id) + + def test_single_line_marker(self): + warnings, lines = self._scan("int a;\nfoo(); // COV_JUSTIFIED reason-a\nint b;\n") + self.assertEqual(warnings, []) + self.assertEqual(lines, {2: {"id": "reason-a", "category": "other", "reason": "because A"}}) + + def test_region_excludes_marker_lines(self): + text = "a\n// COV_JUSTIFIED_START reason-b\nx\ny\n// COV_JUSTIFIED_STOP\nz\n" + warnings, lines = self._scan(text) + self.assertEqual(warnings, []) + self.assertEqual(sorted(lines), [3, 4]) + self.assertTrue(all(v["id"] == "reason-b" for v in lines.values())) + + def test_empty_region_justifies_nothing(self): + warnings, lines = self._scan("// COV_JUSTIFIED_START reason-a\n// COV_JUSTIFIED_STOP\n") + self.assertEqual(warnings, []) + self.assertEqual(lines, {}) + + def test_nested_regions_inner_wins(self): + text = ( + "// COV_JUSTIFIED_START reason-a\n" # 1 + "a\n" # 2 -> reason-a + "// COV_JUSTIFIED_START reason-b\n" # 3 + "b\n" # 4 -> reason-b, then overwritten by outer STOP? No: outer range re-assigns. + "// COV_JUSTIFIED_STOP\n" # 5 + "c\n" # 6 -> reason-a + "// COV_JUSTIFIED_STOP\n" # 7 + ) + warnings, lines = self._scan(text) + self.assertEqual(warnings, []) + self.assertEqual(sorted(lines), [2, 3, 4, 5, 6]) + # The outer region is closed last and covers lines 2..6, so it overwrites the inner assignment. + self.assertEqual(lines[4]["id"], "reason-a") + + def test_unknown_ids_warn_and_do_not_justify(self): + text = "x // COV_JUSTIFIED nope\n// COV_JUSTIFIED_START nope2\ny\n// COV_JUSTIFIED_STOP\n" + warnings, lines = self._scan(text) + self.assertEqual(lines, {}) + self.assertEqual(len(warnings), 3) + self.assertIn("f.cpp:1: COV_JUSTIFIED references unknown ID 'nope'", warnings[0]) + self.assertIn("f.cpp:2: COV_JUSTIFIED_START references unknown ID 'nope2'", warnings[1]) + self.assertIn("f.cpp:4: COV_JUSTIFIED_STOP without matching START", warnings[2]) + + def test_unclosed_region_warns(self): + warnings, lines = self._scan("// COV_JUSTIFIED_START reason-a\nx\n") + self.assertEqual(lines, {}) + self.assertEqual(warnings, ["f.cpp:1: COV_JUSTIFIED_START 'reason-a' without matching STOP"]) + + def test_stop_without_start_warns(self): + warnings, lines = self._scan("x\n// COV_JUSTIFIED_STOP\n") + self.assertEqual(lines, {}) + self.assertEqual(warnings, ["f.cpp:2: COV_JUSTIFIED_STOP without matching START"]) + + def test_marker_id_characters(self): + _warnings, lines = self._scan("x // COV_JUSTIFIED reason-a; trailing text\n") + self.assertEqual(sorted(lines), [1]) + + def test_unreadable_file_yields_nothing(self): + warnings, lines = justify.scan_file_for_markers(self.root / "missing.cpp", "missing.cpp", self.by_id) + self.assertEqual((warnings, lines), ([], {})) + + def test_non_utf8_content_is_tolerated(self): + path = self.root / "f.cpp" + path.write_bytes(b"\xff\xfe junk\nfoo(); // COV_JUSTIFIED reason-a\n") + _warnings, lines = justify.scan_file_for_markers(path, "f.cpp", self.by_id) + self.assertEqual(sorted(lines), [2]) + + +@verifies("tool_req__coverage_just_markers") +class CollectSourceFilesTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + for rel in ["src/a.cpp", "src/b.h", "src/c.rs", "src/d.py", "bazel-out/e.cpp", "bazel-bin/f.rs", "docs/g.hpp"]: + p = self.root / rel + p.parent.mkdir(parents=True, exist_ok=True) + p.write_text("", encoding="utf-8") + + def tearDown(self): + self.tmp.cleanup() + + def _rel(self, files): + return sorted(str(f.relative_to(self.root)) for f in files) + + def test_default_filter_and_bazel_dirs_skipped(self): + files = justify.collect_source_files(self.root, "cpp,h,hpp,cc,rs") + self.assertEqual(self._rel(files), ["docs/g.hpp", "src/a.cpp", "src/b.h", "src/c.rs"]) + + def test_custom_filter(self): + files = justify.collect_source_files(self.root, "py, rs") + self.assertEqual(self._rel(files), ["src/c.rs", "src/d.py"]) + + def test_empty_filter_uses_defaults(self): + files = justify.collect_source_files(self.root, "") + self.assertIn("src/a.cpp", self._rel(files)) + self.assertNotIn("src/d.py", self._rel(files)) + + +@verifies("tool_req__coverage_just_yaml") +class LoadYamlTest(unittest.TestCase): + def test_missing_file_exits(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + justify.load_yaml(Path("/nonexistent/justifications.yaml")) + + def test_loads_document(self): + with tempfile.TemporaryDirectory() as tmp: + path = Path(tmp) / "j.yaml" + path.write_text("version: 1\njustifications: []\n", encoding="utf-8") + self.assertEqual(justify.load_yaml(path), {"version": 1, "justifications": []}) + + +@verifies( + "tool_req__coverage_just_markers", + "tool_req__coverage_just_platform", + "tool_req__coverage_just_missing_file", + "tool_req__coverage_just_yaml", +) +class MainTest(unittest.TestCase): + """End-to-end: YAML locations + in-code markers -> manifest.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + (self.root / "src").mkdir() + (self.root / "src" / "a.cpp").write_text( + "int a;\nfoo(); // COV_JUSTIFIED marker-linux\nbar(); // COV_JUSTIFIED marker-qnx\nbaz();\n", + encoding="utf-8", + ) + (self.root / "src" / "b.rs").write_text("fn b() {}\nfn c() {}\n", encoding="utf-8") + self.yaml = self.root / "j.yaml" + self.yaml.write_text( + "\n".join( + [ + "version: 1", + "justifications:", + " - id: marker-linux", + " category: defensive_programming", + " platforms: [linux]", + " reason: linux only marker", + " - id: marker-qnx", + " category: platform_specific", + " platforms: [qnx]", + " reason: qnx only marker", + " - id: yaml-loc", + " category: other", + " platforms: [linux, qnx]", + " reason: ' located via yaml '", + " locations:", + " - file: src/b.rs", + " line_start: 1", + " line_end: 2", + "", + ] + ), + encoding="utf-8", + ) + self.out = self.root / "out" / "manifest.json" + + def tearDown(self): + self.tmp.cleanup() + + def _run(self, platform): + argv = ["--yaml", str(self.yaml), "--source-root", str(self.root), "--output", str(self.out)] + if platform: + argv += ["--platform", platform] + err = io.StringIO() + code = None + with redirect_stderr(err): + try: + justify.main(argv) + except SystemExit as exc: + code = exc.code + manifest = json.loads(self.out.read_text(encoding="utf-8")) if self.out.exists() else None + return code, manifest, err.getvalue() + + def test_linux_manifest(self): + code, manifest, err = self._run("linux") + self.assertIsNone(code) + self.assertEqual(manifest["version"], 1) + self.assertEqual(manifest["source_root"], str(self.root)) + self.assertEqual(sorted(manifest["justified_files"]), ["src/a.cpp", "src/b.rs"]) + a = manifest["justified_files"]["src/a.cpp"] + self.assertEqual(list(a), ["2"]) # the qnx-only marker is filtered out; keys are strings + self.assertEqual( + a["2"], {"id": "marker-linux", "category": "defensive_programming", "reason": "linux only marker"} + ) + b = manifest["justified_files"]["src/b.rs"] + self.assertEqual(sorted(b), ["1", "2"]) + self.assertEqual(b["1"]["reason"], "located via yaml") + # The filtered-out marker is reported as unknown for this platform. + self.assertTrue(any("marker-qnx" in w for w in manifest["warnings"])) + self.assertEqual(manifest["errors"], []) + self.assertIn("Resolved 3 justified lines across 2 files", err) + + def test_qnx_manifest(self): + code, manifest, _ = self._run("qnx") + self.assertIsNone(code) + self.assertEqual(list(manifest["justified_files"]["src/a.cpp"]), ["3"]) + + def test_no_platform_keeps_all(self): + code, manifest, _ = self._run(None) + self.assertIsNone(code) + self.assertEqual(sorted(manifest["justified_files"]["src/a.cpp"]), ["2", "3"]) + + def test_missing_location_file_is_an_error(self): + self.yaml.write_text( + "version: 1\njustifications:\n - id: gone\n category: other\n platforms: [linux]\n" + " reason: r\n locations:\n - file: src/missing.cpp\n line: 1\n", + encoding="utf-8", + ) + code, manifest, err = self._run("linux") + self.assertEqual(code, 1) + self.assertIn("File not found for justification 'gone'", err) + self.assertEqual(len(manifest["errors"]), 1) # the manifest is still written for diagnosis + + def test_invalid_yaml_exits_before_scanning(self): + self.yaml.write_text("version: 1\n", encoding="utf-8") + code, manifest, _ = self._run("linux") + self.assertEqual(code, 1) + self.assertIsNone(manifest) + + def test_bazel_symlinks_are_not_scanned(self): + (self.root / "bazel-out").mkdir() + (self.root / "bazel-out" / "gen.cpp").write_text("x // COV_JUSTIFIED marker-linux\n", encoding="utf-8") + code, manifest, _ = self._run("linux") + self.assertIsNone(code) + self.assertNotIn("bazel-out/gen.cpp", manifest["justified_files"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/score_coverage/tests/merger_test.py b/score_coverage/tests/merger_test.py new file mode 100644 index 0000000..a46af5e --- /dev/null +++ b/score_coverage/tests/merger_test.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Unit tests for the per-test coverage merger.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import io +import json +import os +import stat +import sys +import tempfile +import unittest +import zipfile +from contextlib import redirect_stderr +from pathlib import Path +from unittest import mock + +from score_coverage import merger +from score_coverage.merger import find_llvm_profdata, get_object_files_from_manifest, is_elf +from score_coverage.tests.traceability import verifies + + +@verifies("tool_req__coverage_merge_profraw") +class IsElfTest(unittest.TestCase): + def test_elf_magic_is_detected(self): + with tempfile.NamedTemporaryFile(suffix=".bin") as f: + f.write(b"\x7fELF" + b"\x00" * 12) + f.flush() + self.assertTrue(is_elf(Path(f.name))) + + def test_text_file_is_not_elf(self): + with tempfile.NamedTemporaryFile(suffix=".txt") as f: + f.write(b"just some text") + f.flush() + self.assertFalse(is_elf(Path(f.name))) + + def test_missing_file_is_not_elf(self): + self.assertFalse(is_elf(Path("/nonexistent/path/binary"))) + + +@verifies("tool_req__coverage_merge_tool_error") +class FindLlvmProfdataTest(unittest.TestCase): + def test_llvm_profdata_env_wins(self): + with tempfile.NamedTemporaryFile() as f, mock.patch.dict(os.environ, {"LLVM_PROFDATA": f.name}, clear=True): + self.assertEqual(find_llvm_profdata(), f.name) + + def test_rust_llvm_profdata_resolved_against_root(self): + with tempfile.TemporaryDirectory() as root: + tool = Path(root) / "bin" / "llvm-profdata" + tool.parent.mkdir() + tool.write_bytes(b"\x7fELF") + env = {"RUST_LLVM_PROFDATA": "bin/llvm-profdata", "ROOT": root} + with mock.patch.dict(os.environ, env, clear=True): + self.assertEqual(find_llvm_profdata(), str(tool)) + + def test_returns_empty_when_nothing_resolves(self): + env = {"RUST_LLVM_PROFDATA": "does/not/exist"} + with mock.patch.dict(os.environ, env, clear=True): + self.assertEqual(find_llvm_profdata(), "") + + +@verifies("tool_req__coverage_merge_profraw") +class GetObjectFilesFromManifestTest(unittest.TestCase): + def test_missing_root_env_is_a_hard_error(self): + """Without ROOT the merger cannot resolve manifest paths — must exit.""" + with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as manifest: + manifest.write("some/path\n") + manifest.flush() + with mock.patch.dict(os.environ, {}, clear=True), self.assertRaises(SystemExit): + get_object_files_from_manifest(Path(manifest.name)) + + def test_rust_elf_manifest_entry_is_collected(self): + """rules_rust lists the instrumented test executable in the manifest.""" + with tempfile.TemporaryDirectory() as root: + binary = Path(root) / "pkg" / "my_test" + binary.parent.mkdir() + binary.write_bytes(b"\x7fELF" + b"\x00" * 12) + with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as manifest: + manifest.write("pkg/my_test\n") + manifest.flush() + with mock.patch.dict(os.environ, {"ROOT": root}, clear=True): + objects = get_object_files_from_manifest(Path(manifest.name)) + self.assertEqual(objects, {str(binary)}) + + def test_external_manifest_entries_are_skipped(self): + """Toolchain-provided metadata files (external/) are not instrumented objects.""" + with tempfile.TemporaryDirectory() as root: + binary = Path(root) / "external" / "tool" + binary.parent.mkdir() + binary.write_bytes(b"\x7fELF" + b"\x00" * 12) + with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as manifest: + manifest.write("external/tool\n") + manifest.flush() + with mock.patch.dict(os.environ, {"ROOT": root}, clear=True): + objects = get_object_files_from_manifest(Path(manifest.name)) + self.assertEqual(objects, set()) + + def test_objects_list_entries_are_resolved(self): + """C++ tests provide an objects_list.txt with one object path per line.""" + with tempfile.TemporaryDirectory() as root: + obj = Path(root) / "bazel-out" / "lib.a" + obj.parent.mkdir() + obj.write_bytes(b"!\n") + objects_list = Path(root) / "objects_list.txt" + objects_list.write_text("bazel-out/lib.a\n") + with tempfile.NamedTemporaryFile(mode="w", suffix=".txt") as manifest: + manifest.write(f"{objects_list}\n") + manifest.flush() + with mock.patch.dict(os.environ, {"ROOT": root}, clear=True): + objects = get_object_files_from_manifest(Path(manifest.name)) + self.assertEqual(objects, {str(obj)}) + + +# --------------------------------------------------------------------------- +# Added for the score_coverage qualification: end-to-end behaviour of main() +# with a fake llvm-profdata, plus the helpers that were not covered. +# --------------------------------------------------------------------------- + + +def _fake_profdata(path: Path, fail: bool = False) -> Path: + """A stand-in llvm-profdata that concatenates its inputs into --output.""" + body = "#!/usr/bin/env python3\nimport sys\n" + if fail: + body += "print('boom'); sys.exit(3)\n" + else: + body += ( + "args = sys.argv[1:]\n" + "assert args[0] == 'merge' and '--sparse' in args, args\n" + "out = args[args.index('--output') + 1]\n" + "inputs = args[args.index('--output') + 2:]\n" + "with open(out, 'wb') as o:\n" + " for i in inputs:\n" + " o.write(open(i, 'rb').read())\n" + ) + path.write_text(body, encoding="utf-8") + path.chmod(path.stat().st_mode | stat.S_IXUSR) + return path + + +@verifies("tool_req__coverage_merge_profraw") +class CleanupDanglingSymlinksTest(unittest.TestCase): + def test_gcov_and_sandbox_links_removed_others_kept(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + (root / "keep.txt").write_text("x", encoding="utf-8") + (root / "gcov").symlink_to("/nonexistent/sandbox/gcov") + (root / "into_sandbox").symlink_to("/tmp/bazel-sandbox/123/thing") + (root / "other_link").symlink_to("/usr/bin") + merger.cleanup_dangling_symlinks(root) + self.assertFalse((root / "gcov").is_symlink()) + self.assertFalse((root / "into_sandbox").is_symlink()) + self.assertTrue((root / "other_link").is_symlink()) + self.assertTrue((root / "keep.txt").is_file()) + + +@verifies("tool_req__coverage_merge_profraw") +class CreateZipTest(unittest.TestCase): + def test_only_listed_directories_relative_to_root(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + (root / "a" / "sub").mkdir(parents=True) + (root / "a" / "sub" / "f.txt").write_text("f", encoding="utf-8") + (root / "b").mkdir() + (root / "b" / "g.txt").write_text("g", encoding="utf-8") + (root / "c").mkdir() + (root / "c" / "h.txt").write_text("h", encoding="utf-8") + out = root / "out.zip" + merger.create_zip(root, [root / "a", root / "b", root / "missing"], out) + with zipfile.ZipFile(out) as zf: + self.assertEqual(sorted(zf.namelist()), ["a/sub/f.txt", "b/g.txt"]) + + +@verifies("tool_req__coverage_merge_tool_error", test_type="fault-injection", derivation="error-guessing") +class RunCommandTest(unittest.TestCase): + def test_failure_exits_with_1(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit) as ctx: + merger.run_command([sys.executable, "-c", "import sys; print('bad'); sys.exit(7)"]) + self.assertEqual(ctx.exception.code, 1) + + def test_success_returns_output(self): + result = merger.run_command([sys.executable, "-c", "print('ok')"]) + self.assertEqual(result.stdout.strip(), "ok") + + +@verifies("tool_req__coverage_merge_profraw", "tool_req__coverage_merge_no_data", "tool_req__coverage_merge_tool_error") +class MergerMainTest(unittest.TestCase): + """main() against a fake Bazel coverage directory and a fake llvm-profdata.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + self.coverage_dir = self.root / "coverage_dir" + self.coverage_dir.mkdir() + # An "instrumented object" listed through objects_list.txt. + self.exec_root = self.root / "execroot" + (self.exec_root / "bazel-out" / "k8" / "bin").mkdir(parents=True) + self.obj = self.exec_root / "bazel-out" / "k8" / "bin" / "libfoo.a" + self.obj.write_bytes(b"!\n") + objects_list = self.root / "objects_list.txt" + objects_list.write_text("bazel-out/k8/bin/libfoo.a\n\n", encoding="utf-8") + self.manifest = self.root / "manifest.txt" + self.manifest.write_text(f"{objects_list}\n", encoding="utf-8") + self.output = self.root / "coverage.zip" + self.profdata = _fake_profdata(self.root / "llvm-profdata") + self.env = { + "ROOT": str(self.exec_root), + "RUNFILES_DIR": str(self.root / "no_runfiles"), + "TEST_WORKSPACE": "_main", + "LLVM_PROFDATA": str(self.profdata), + "TEST_TARGET": "//pkg:t", + "PATH": os.environ.get("PATH", ""), + } + + def tearDown(self): + self.tmp.cleanup() + + def _argv(self): + return [ + "--coverage_dir", + str(self.coverage_dir), + "--output_file", + str(self.output), + "--source_file_manifest", + str(self.manifest), + "--filter_sources", + "external/.*", + ] + + def _run(self): + err = io.StringIO() + with mock.patch.dict(os.environ, self.env, clear=True), redirect_stderr(err): + try: + merger.main(self._argv()) + except SystemExit as exc: + return exc.code, err.getvalue() + return None, err.getvalue() + + def test_merges_profraw_and_packages_meta(self): + (self.coverage_dir / "b.profraw").write_bytes(b"BBBB") + (self.coverage_dir / "a.profraw").write_bytes(b"AAAA") + (self.coverage_dir / "gcov").symlink_to("/sandbox/gone/gcov") + code, err = self._run() + self.assertIsNone(code, err) + self.assertIn("Coverage merger completed for '//pkg:t'", err) + with zipfile.ZipFile(self.output) as zf: + names = sorted(zf.namelist()) + self.assertEqual(names, ["meta/meta.json", "profdata/target.profdata"]) + self.assertEqual(zf.read("profdata/target.profdata"), b"AAAABBBB") # sorted input order + meta = json.loads(zf.read("meta/meta.json")) + self.assertEqual(meta, {"object_files": [os.path.realpath(self.obj)]}) + self.assertFalse((self.coverage_dir / "gcov").is_symlink()) + + def test_no_profraw_skips_quietly_with_exit_0(self): + code, err = self._run() + self.assertEqual(code, 0) + self.assertIn("No *.profraw files found", err) + self.assertFalse(self.output.exists()) + + def test_no_objects_skips_quietly_with_exit_0(self): + self.manifest.write_text("", encoding="utf-8") + (self.coverage_dir / "a.profraw").write_bytes(b"A") + code, err = self._run() + self.assertEqual(code, 0) + self.assertIn("No instrumented object files found", err) + + def test_missing_llvm_profdata_is_an_error(self): + (self.coverage_dir / "a.profraw").write_bytes(b"A") + self.env["LLVM_PROFDATA"] = str(self.root / "does_not_exist") + code, err = self._run() + self.assertEqual(code, 1) + self.assertIn("llvm-profdata not found", err) + + def test_failing_llvm_profdata_is_an_error(self): + (self.coverage_dir / "a.profraw").write_bytes(b"A") + _fake_profdata(self.profdata, fail=True) + code, err = self._run() + self.assertEqual(code, 1) + self.assertIn("Command failed with code 3", err) + self.assertFalse(self.output.exists()) + + def test_rust_llvm_profdata_fallback_is_used(self): + (self.coverage_dir / "a.profraw").write_bytes(b"A") + del self.env["LLVM_PROFDATA"] + self.env["RUST_LLVM_PROFDATA"] = str(self.profdata) + code, _ = self._run() + self.assertIsNone(code) + self.assertTrue(self.output.exists()) + + +if __name__ == "__main__": + unittest.main() diff --git a/score_coverage/tests/reporter_test.py b/score_coverage/tests/reporter_test.py new file mode 100644 index 0000000..ab21d9f --- /dev/null +++ b/score_coverage/tests/reporter_test.py @@ -0,0 +1,600 @@ +#!/usr/bin/env python3 +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Unit tests for the final coverage reporter.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import io +import json +import os +import stat +import sys +import tempfile +import unittest +import zipfile +from contextlib import redirect_stderr +from pathlib import Path +from unittest import mock + +from score_coverage import reporter +from score_coverage.reporter import ( + _filter_lcov, + _make_html_paths_relative, + _make_lcov_paths_relative, + _read_ar_members, + expand_rlib_archives, + write_empty_output, +) +from score_coverage.tests.traceability import verifies + + +def _ar_header(name: str, size: int) -> bytes: + """Build a 60-byte Unix ar member header.""" + return (f"{name:<16}{'0':<12}{'0':<6}{'0':<6}{'100644':<8}{size:<10}`\n").encode() + + +def _make_archive(members) -> bytes: + """Build a Unix ar archive from (name, data) tuples.""" + blob = b"!\n" + for name, data in members: + blob += _ar_header(name, len(data)) + data + if len(data) % 2 == 1: + blob += b"\n" + return blob + + +@verifies("tool_req__coverage_report_rlib_expansion") +class ReadArMembersTest(unittest.TestCase): + def test_non_archive_returns_empty(self): + with tempfile.NamedTemporaryFile(suffix=".a") as f: + f.write(b"\x7fELF not an archive") + f.flush() + self.assertEqual(_read_ar_members(f.name), []) + + def test_members_are_listed_with_sizes(self): + blob = _make_archive([("lib.rmeta/", b"META"), ("foo.o/", b"OBJDATA")]) + with tempfile.NamedTemporaryFile(suffix=".a") as f: + f.write(blob) + f.flush() + members = _read_ar_members(f.name) + self.assertEqual([(m[0], m[2]) for m in members], [("lib.rmeta", 4), ("foo.o", 7)]) + + def test_gnu_long_name_table_is_resolved(self): + longnames = b"a_very_long_object_file_name.o/\n" + blob = _make_archive([("//", longnames), ("/0", b"LONGOBJ")]) + with tempfile.NamedTemporaryFile(suffix=".a") as f: + f.write(blob) + f.flush() + members = _read_ar_members(f.name) + self.assertEqual([m[0] for m in members], ["a_very_long_object_file_name.o"]) + + +@verifies("tool_req__coverage_report_rlib_expansion") +class ExpandRlibArchivesTest(unittest.TestCase): + def test_rlib_is_expanded_to_object_members(self): + """Archives with a lib.rmeta member are replaced by their .o members.""" + blob = _make_archive([("lib.rmeta/", b"META"), ("crate.o/", b"OBJ1"), ("notes.txt/", b"TXT")]) + with tempfile.TemporaryDirectory() as tmp: + rlib = Path(tmp) / "libcrate.a" + rlib.write_bytes(blob) + workdir = Path(tmp) / "extracted" + result = expand_rlib_archives([str(rlib)], workdir) + self.assertEqual(len(result), 1) + self.assertTrue(result[0].endswith(".o")) + self.assertEqual(Path(result[0]).read_bytes(), b"OBJ1") + + def test_plain_cc_archive_passes_through(self): + blob = _make_archive([("mylib.o/", b"OBJ1")]) + with tempfile.TemporaryDirectory() as tmp: + archive = Path(tmp) / "libcc.a" + archive.write_bytes(blob) + result = expand_rlib_archives([str(archive)], Path(tmp) / "x") + self.assertEqual(result, [str(archive)]) + + def test_executable_passes_through(self): + with tempfile.TemporaryDirectory() as tmp: + binary = Path(tmp) / "my_tool" + binary.write_bytes(b"\x7fELF" + b"\x00" * 12) + result = expand_rlib_archives([str(binary)], Path(tmp) / "x") + self.assertEqual(result, [str(binary)]) + + +@verifies("tool_req__coverage_report_baseline_zero") +class FilterLcovTest(unittest.TestCase): + LCOV = "SF:src/foo.cpp\nDA:1,1\nLF:1\nLH:1\nend_of_record\nSF:src/bar.cpp\nDA:1,0\nLF:1\nLH:0\nend_of_record\n" + + def test_only_target_records_survive(self): + result = _filter_lcov(self.LCOV, {"src/bar.cpp"}) + self.assertIn("SF:src/bar.cpp", result) + self.assertNotIn("SF:src/foo.cpp", result) + + def test_suffix_matching(self): + result = _filter_lcov("SF:/abs/prefix/src/foo.cpp\nend_of_record\n", {"src/foo.cpp"}) + self.assertIn("SF:/abs/prefix/src/foo.cpp", result) + + +@verifies("tool_req__coverage_report_relative_paths") +class MakeLcovPathsRelativeTest(unittest.TestCase): + def test_workspace_paths_become_relative(self): + lcov = "SF:/ws/root/src/foo.cpp\nDA:1,1\nend_of_record\n" + result = _make_lcov_paths_relative(lcov, "/ws/root/") + self.assertEqual(result, "SF:src/foo.cpp\nDA:1,1\nend_of_record\n") + + def test_workspace_root_without_trailing_slash(self): + lcov = "SF:/ws/root/src/foo.cpp\nend_of_record\n" + result = _make_lcov_paths_relative(lcov, "/ws/root") + self.assertEqual(result, "SF:src/foo.cpp\nend_of_record\n") + + def test_external_paths_are_unchanged(self): + lcov = "SF:/other/place/dep.cpp\nend_of_record\n" + self.assertEqual(_make_lcov_paths_relative(lcov, "/ws/root/"), lcov) + + def test_non_sf_lines_are_preserved(self): + lcov = "TN:test\nSF:/ws/root/a.cpp\nDA:5,0\nLF:1\nLH:0\nend_of_record\n" + result = _make_lcov_paths_relative(lcov, "/ws/root/") + self.assertIn("TN:test\n", result) + self.assertIn("DA:5,0\n", result) + + +@verifies("tool_req__coverage_report_relative_paths") +class MakeHtmlPathsRelativeTest(unittest.TestCase): + def test_source_title_is_rewritten_and_hrefs_untouched(self): + html = ( + "
/ws/root/src/foo.cpp
" + "link" + ) + with tempfile.TemporaryDirectory() as tmp: + page = Path(tmp) / "page.html" + page.write_text(html) + _make_html_paths_relative(Path(tmp), "/ws/root/") + result = page.read_text() + self.assertIn("
src/foo.cpp
", result) + # The href embeds the path components without a leading slash and must + # never be rewritten. + self.assertIn("href='coverage/ws/root/src/foo.cpp.html'", result) + + def test_missing_dir_is_a_noop(self): + _make_html_paths_relative(Path("/nonexistent/html_dir"), "/ws/root/") + + +@verifies("tool_req__coverage_report_outputs") +class WriteEmptyOutputTest(unittest.TestCase): + def test_produces_valid_empty_zip(self): + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "out.zip" + write_empty_output(out) + self.assertTrue(zipfile.is_zipfile(out)) + with zipfile.ZipFile(out) as zf: + self.assertEqual(zf.namelist(), []) + + +# --------------------------------------------------------------------------- +# Added for the score_coverage qualification: helpers around llvm-cov and an +# end-to-end run of main() against fake llvm tools. +# --------------------------------------------------------------------------- + + +class _FakeRunfiles: + """Minimal stand-in for python.runfiles.Runfiles: maps rlocation paths to files.""" + + def __init__(self, mapping): + self.mapping = mapping + + def Rlocation(self, path): # noqa: N802 # pylint: disable=invalid-name + if os.path.isabs(path): + return path + return self.mapping.get(path) + + +def _write_tool(path: Path, body: str) -> Path: + path.write_text("#!/usr/bin/env python3\nimport sys, os\n" + body, encoding="utf-8") + path.chmod(path.stat().st_mode | stat.S_IXUSR) + return path + + +REPORT_TABLE = """Filename Regions Missed Cover Functions Missed Executed Lines Missed Cover +------------------------------------------------------------------------------------------------------- +/proc/self/cwd/src/a.cpp 4 1 75.00% 1 0 100.00% 10 2 80.00% +/ws/src/b.cpp 2 2 0.00% 1 1 0.00% 5 5 0.00% +rust/lib.rs 3 0 100.00% 2 0 100.00% 8 0 100.00% +------------------------------------------------------------------------------------------------------- +TOTAL 9 3 66.67% 4 1 75.00% 23 7 69.57% +""" + + +def _fake_llvm_cov(path: Path) -> Path: + """Fake llvm-cov: records argv, answers report/show/export plausibly.""" + body = f""" +args = sys.argv[1:] +with open(os.environ["FAKE_LLVM_COV_LOG"], "a") as log: + log.write(" ".join(args) + "\\n") +sub = args[0] +if sub == "report": + sys.stdout.write({REPORT_TABLE!r}) +elif sub == "export": + empty = "--empty-profile" in args + sys.stderr.write("warning: something cosmetic\\n") + if empty: + sys.stdout.write("SF:/ws/src/b.cpp\\nDA:1,0\\nLF:1\\nLH:0\\nend_of_record\\n") + else: + sys.stdout.write("SF:/ws/src/a.cpp\\nDA:1,1\\nLF:1\\nLH:1\\nend_of_record\\n") +elif sub == "show": + out = [a for a in args if a.startswith("--output-dir=")][0].split("=", 1)[1] + os.makedirs(os.path.join(out, "coverage", "ws", "src"), exist_ok=True) + open(os.path.join(out, "index.html"), "w").write("index") + open(os.path.join(out, "style.css"), "w").write("body {{}}") + open(os.path.join(out, "coverage", "ws", "src", "a.cpp.html"), "w").write( + "
/ws/src/a.cpp
") +else: + sys.exit(2) +""" + return _write_tool(path, body) + + +def _fake_llvm_profdata(path: Path) -> Path: + return _write_tool( + path, + "args = sys.argv[1:]\nout = args[args.index('--output') + 1]\n" + "open(out, 'wb').write(b''.join(open(i, 'rb').read() for i in args[args.index('--output') + 2:]))\n", + ) + + +@verifies("tool_req__coverage_report_merged_profile") +class ReadReportsFileTest(unittest.TestCase): + def test_blank_lines_dropped(self): + with tempfile.TemporaryDirectory() as tmp: + f = Path(tmp) / "reports.txt" + f.write_text("a.zip\n\n b.zip \n", encoding="utf-8") + self.assertEqual(reporter.read_reports_file(f), ["a.zip", "b.zip"]) + + +@verifies("tool_req__coverage_report_merged_profile", derivation="error-guessing") +class ExtractReportsTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + self.obj = self.root / "libx.a" + self.obj.write_bytes(b"!\n") + self.cwd = os.getcwd() + os.chdir(self.root) + + def tearDown(self): + os.chdir(self.cwd) + self.tmp.cleanup() + + def _zip(self, name, meta=None, profdata=b"PROF"): + path = self.root / name + with zipfile.ZipFile(path, "w") as zf: + if meta is not None: + zf.writestr("meta/meta.json", json.dumps(meta)) + if profdata is not None: + zf.writestr("profdata/target.profdata", profdata) + return str(path) + + def test_valid_reports_are_extracted(self): + good = self._zip("good.zip", {"object_files": [str(self.obj), str(self.root / "missing.a"), ""]}) + with redirect_stderr(io.StringIO()): + profdata, objects = reporter.extract_reports([good]) + self.assertEqual(len(profdata), 1) + self.assertTrue(Path(next(iter(profdata))).read_bytes() == b"PROF") + self.assertEqual(objects, {os.path.realpath(self.obj)}) + + def test_invalid_inputs_are_skipped(self): + empty = self.root / "empty.zip" + empty.write_bytes(b"") + notzip = self.root / "notzip.zip" + notzip.write_text("nope", encoding="utf-8") + no_meta = self._zip("nometa.zip", meta=None) + no_prof = self._zip("noprof.zip", meta={"object_files": []}, profdata=None) + bad_json = self.root / "badjson.zip" + with zipfile.ZipFile(bad_json, "w") as zf: + zf.writestr("meta/meta.json", "{bad") + zf.writestr("profdata/target.profdata", b"P") + err = io.StringIO() + with redirect_stderr(err): + profdata, objects = reporter.extract_reports( + [ + str(empty), + str(notzip), + no_meta, + no_prof, + str(bad_json), + str(self.root / "missing.zip"), + str(self.root / "baseline_coverage.dat"), + ] + ) + self.assertEqual((profdata, objects), (set(), set())) + self.assertEqual(err.getvalue().count("WARNING: Skipping invalid report"), 3) + + +@verifies("tool_req__coverage_report_merged_profile") +class ResolveToolTest(unittest.TestCase): + def test_preference_order(self): + with tempfile.TemporaryDirectory() as tmp: + real = Path(tmp) / "llvm-cov" + real.write_text("", encoding="utf-8") + fallback = Path(tmp) / "fallback-cov" + fallback.write_text("", encoding="utf-8") + rf = _FakeRunfiles({"toolchain/llvm-cov": str(real), "llvm_toolchain/llvm-cov": str(fallback)}) + self.assertEqual(reporter.resolve_tool(rf, "toolchain/llvm-cov", "llvm_toolchain/llvm-cov"), real) + self.assertEqual(reporter.resolve_tool(rf, None, "llvm_toolchain/llvm-cov"), fallback) + self.assertEqual(reporter.resolve_tool(rf, str(real), ""), real) # plain path + self.assertIsNone(reporter.resolve_tool(rf, "unknown", "also-unknown")) + self.assertIsNone(reporter.resolve_tool(None, "unknown", "")) + + +@verifies("tool_req__coverage_report_outputs") +class FindCxxfiltTest(unittest.TestCase): + def test_explicit_then_sibling_then_none(self): + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + (root / "bin").mkdir() + cov = root / "bin" / "llvm-cov" + cov.write_text("", encoding="utf-8") + explicit = root / "explicit-cxxfilt" + explicit.write_text("", encoding="utf-8") + rf = _FakeRunfiles({"x/llvm-cxxfilt": str(explicit)}) + self.assertEqual(reporter.find_cxxfilt(cov, rf, "x/llvm-cxxfilt"), str(explicit)) + sibling = root / "bin" / "llvm-cxxfilt" + sibling.write_text("", encoding="utf-8") + self.assertEqual(reporter.find_cxxfilt(cov, rf, None), str(sibling)) + sibling.unlink() + self.assertEqual(reporter.find_cxxfilt(cov, rf, None), "") + + +@verifies("tool_req__coverage_report_allowlist", "tool_req__coverage_report_missing_baseline") +class LoadAllowlistAndBaselineTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + + def tearDown(self): + self.tmp.cleanup() + + def test_allowlist_comments_and_blank_lines_ignored(self): + f = self.root / "allow.txt" + f.write_text("# comment\nsrc/a.cpp\n\n src/b.h \n", encoding="utf-8") + rf = _FakeRunfiles({"main/allow.txt": str(f)}) + self.assertEqual(reporter.load_coverage_allowlist(rf, "main/allow.txt"), ["src/a.cpp", "src/b.h"]) + self.assertEqual(reporter.load_coverage_allowlist(rf, "missing"), []) + + def test_baseline_objects_resolved_via_main_repo(self): + obj = self.root / "bazel-out" / "bin" / "libz.a" + obj.parent.mkdir(parents=True) + obj.write_bytes(b"") + manifest = self.root / "objects.txt" + manifest.write_text("# c\nbazel-out/bin/libz.a\n", encoding="utf-8") + rf = _FakeRunfiles({"main/objects.txt": str(manifest), "_main/bazel-out/bin/libz.a": str(obj)}) + self.assertEqual(reporter.load_baseline_objects(rf, "main/objects.txt"), [str(obj)]) + self.assertEqual(reporter.load_baseline_objects(rf, None), []) + with redirect_stderr(io.StringIO()): + self.assertEqual(reporter.load_baseline_objects(rf, "missing"), []) + + def test_missing_baseline_object_is_a_hard_error(self): + manifest = self.root / "objects.txt" + manifest.write_text("bazel-out/bin/gone.a\n", encoding="utf-8") + rf = _FakeRunfiles({"main/objects.txt": str(manifest), "_main/bazel-out/bin/gone.a": str(self.root / "gone")}) + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + reporter.load_baseline_objects(rf, "main/objects.txt") + + +@verifies("tool_req__coverage_report_outputs", test_type="fault-injection", derivation="error-guessing") +class RunCommandTest(unittest.TestCase): + def test_separate_stderr_keeps_stdout_clean(self): + err = io.StringIO() + with redirect_stderr(err): + result = reporter.run_command( + [sys.executable, "-c", "import sys; print('data'); print('warn', file=sys.stderr)"], + separate_stderr=True, + ) + self.assertEqual(result.stdout, "data\n") + self.assertIn("warn", err.getvalue()) + + def test_failure_exits(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + reporter.run_command([sys.executable, "-c", "import sys; sys.exit(4)"]) + + +@verifies( + "tool_req__coverage_report_allowlist", + "tool_req__coverage_report_baseline_zero", + "tool_req__coverage_report_outputs", +) +class LlvmCovInvocationsTest(unittest.TestCase): + """The exact llvm-cov command lines, checked through the fake tool's log.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + self.cov = _fake_llvm_cov(self.root / "llvm-cov") + self.log = self.root / "log.txt" + self.env = mock.patch.dict(os.environ, {"FAKE_LLVM_COV_LOG": str(self.log)}) + self.env.start() + + def tearDown(self): + self.env.stop() + self.tmp.cleanup() + + def _last(self): + return self.log.read_text(encoding="utf-8").splitlines()[-1].split(" ") + + def test_get_covered_files_normalises_paths(self): + with redirect_stderr(io.StringIO()): + files = reporter.get_covered_files(self.cov, ["/o/a.a", "/o/b.a"], None, "/ws/") + self.assertEqual(files, {"src/a.cpp", "src/b.cpp", "rust/lib.rs"}) + argv = self._last() + self.assertEqual(argv[:3], ["report", "--path-equivalence=/proc/self/cwd/,/ws/", "--empty-profile"]) + self.assertEqual(argv[3:], ["/o/a.a", "--object", "/o/b.a"]) + + def test_show_html_flags(self): + out = self.root / "html" + with redirect_stderr(io.StringIO()): + reporter.run_llvm_cov_show( + self.cov, ["/o/a.a"], "/p/merged.profdata", ["src/x\\.cpp$"], "/ws", "html", out, cxxfilt="/bin/cxxfilt" + ) + argv = self._last() + for flag in [ + "show", + "--format=html", + "--compilation-dir=/ws", + "--show-branches=count", + "--Xdemangler=/bin/cxxfilt", + "--ignore-filename-regex=src/x\\.cpp$", + f"--output-dir={out}", + "--coverage-watermark=100,50", + "--show-expansions", + "--instr-profile", + "/p/merged.profdata", + ]: + self.assertIn(flag, argv) + self.assertTrue((out / "index.html").is_file()) + + def test_export_separates_stderr(self): + err = io.StringIO() + with redirect_stderr(err): + result = reporter.run_llvm_cov_export(self.cov, ["/o/a.a"], "/p/m.profdata", [], "/ws") + self.assertTrue(result.stdout.startswith("SF:")) + self.assertNotIn("warning", result.stdout) + self.assertIn("warning: something cosmetic", err.getvalue()) + self.assertIn("--format=lcov", self._last()) + + def test_report_flags(self): + with redirect_stderr(io.StringIO()): + reporter.run_llvm_cov_report(self.cov, ["/o/a.a"], None, ["r$"], "/ws") + argv = self._last() + self.assertEqual(argv[0], "report") + for flag in [ + "--show-region-summary=0", + "--show-branch-summary=1", + "--ignore-filename-regex=r$", + "--empty-profile", + ]: + self.assertIn(flag, argv) + + +@verifies( + "tool_req__coverage_report_merged_profile", + "tool_req__coverage_report_allowlist", + "tool_req__coverage_report_relative_paths", + "tool_req__coverage_report_outputs", +) +class ReporterMainTest(unittest.TestCase): + """main() end to end with fake llvm tools and two per-test reports.""" + + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + self.cov = _fake_llvm_cov(self.root / "llvm-cov") + self.profdata = _fake_llvm_profdata(self.root / "llvm-profdata") + self.log = self.root / "log.txt" + self.obj = self.root / "test_bin" + self.obj.write_bytes(b"\x7fELF") + reports = [] + for i in range(2): + z = self.root / f"t{i}.zip" + with zipfile.ZipFile(z, "w") as zf: + zf.writestr("meta/meta.json", json.dumps({"object_files": [str(self.obj)]})) + zf.writestr("profdata/target.profdata", f"P{i}".encode()) + reports.append(str(z)) + self.reports_file = self.root / "reports.txt" + self.reports_file.write_text("\n".join(reports) + "\n", encoding="utf-8") + self.allowlist = self.root / "allow.txt" + self.allowlist.write_text("src/a.cpp\nsrc/b.cpp\n", encoding="utf-8") + self.output = self.root / "out.zip" + self.workdir = self.root / "work" + self.workdir.mkdir() + self.cwd = os.getcwd() + os.chdir(self.workdir) + self.env = mock.patch.dict(os.environ, {"FAKE_LLVM_COV_LOG": str(self.log)}) + self.env.start() + + def tearDown(self): + self.env.stop() + os.chdir(self.cwd) + self.tmp.cleanup() + + def _argv(self, **extra): + argv = [ + "--output_file", + str(self.output), + "--reports_file", + str(self.reports_file), + "--workspace_root", + "/ws", + "--llvm_cov", + str(self.cov), + "--llvm_profdata", + str(self.profdata), + "--coverage_allowlist", + str(self.allowlist), + ] + for k, v in extra.items(): + argv += [f"--{k}", str(v)] + return argv + + def test_full_report(self): + err = io.StringIO() + with redirect_stderr(err): + reporter.main(self._argv()) + with zipfile.ZipFile(self.output) as zf: + names = set(zf.namelist()) + lcov = zf.read("lcov_report/lcov.dat").decode() + summary = zf.read("text_report/summary.txt").decode() + page = zf.read("html_report/coverage/ws/src/a.cpp.html").decode() + self.assertIn("html_report/index.html", names) + self.assertIn("html_report/style.css", names) + # SF paths are made workspace-relative, llvm-cov's stderr warning is not in the data. + self.assertIn("SF:src/a.cpp\n", lcov) + self.assertNotIn("warning", lcov) + self.assertIn("TOTAL", summary) + # HTML title rewritten to a relative path. + self.assertIn("
src/a.cpp
", page) + # The merged profdata combined both per-test inputs. + self.assertEqual((self.workdir / "merged_coverage.profdata").read_bytes(), b"P0P1") + # rust/lib.rs is not in the allowlist and must be excluded from the report. + log = self.log.read_text(encoding="utf-8") + self.assertIn("--ignore-filename-regex=rust/lib\\.rs$", log) + self.assertIn("Using coverage allowlist with 2 source files", err.getvalue()) + + def test_no_reports_writes_empty_zip(self): + self.reports_file.write_text("", encoding="utf-8") + with redirect_stderr(io.StringIO()): + reporter.main(self._argv()) + with zipfile.ZipFile(self.output) as zf: + self.assertEqual(zf.namelist(), []) + + def test_invalid_reports_write_empty_zip(self): + (self.root / "t0.zip").write_text("junk", encoding="utf-8") + (self.root / "t1.zip").write_text("junk", encoding="utf-8") + with redirect_stderr(io.StringIO()): + reporter.main(self._argv()) + with zipfile.ZipFile(self.output) as zf: + self.assertEqual(zf.namelist(), []) + + def test_missing_llvm_tools_is_an_error(self): + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit) as ctx: + reporter.main(self._argv(llvm_cov=str(self.root / "nope"))) + self.assertEqual(ctx.exception.code, 1) + + def test_empty_allowlist_is_an_error(self): + self.allowlist.write_text("# nothing\n", encoding="utf-8") + with redirect_stderr(io.StringIO()), self.assertRaises(SystemExit): + reporter.main(self._argv()) + + +if __name__ == "__main__": + unittest.main() diff --git a/score_coverage/tests/starlark/BUILD b/score_coverage/tests/starlark/BUILD new file mode 100644 index 0000000..25f46cf --- /dev/null +++ b/score_coverage/tests/starlark/BUILD @@ -0,0 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load(":coverage_scope_tests.bzl", "coverage_scope_test_suite") + +coverage_scope_test_suite(name = "coverage_scope_tests") diff --git a/score_coverage/tests/starlark/coverage_scope_tests.bzl b/score_coverage/tests/starlark/coverage_scope_tests.bzl new file mode 100644 index 0000000..1e3be2d --- /dev/null +++ b/score_coverage/tests/starlark/coverage_scope_tests.bzl @@ -0,0 +1,177 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Analysis tests for the coverage_scope rule and its aspect. + +The rule writes two text files; rules_testing lets us read the content of +the FileWrite actions without executing anything, so these tests pin down +exactly which source files and archives end up in the coverage scope. +""" + +load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") +load("@rules_testing//lib:truth.bzl", "matching") +load("//score_coverage:coverage_scope.bzl", "coverage_scope") + +_FIX = "//score_coverage/tests/starlark/fixtures" +_PKG = "score_coverage/tests/starlark" + +def _allowlist(env, target): + return env.expect.that_target(target).action_generating( + _PKG + "/" + target.label.name + "_allowlist.txt", + ).content() + +def _objects(env, target): + return env.expect.that_target(target).action_generating( + _PKG + "/" + target.label.name + "_objects.txt", + ).content() + +# --- transitive deps ------------------------------------------------------- + +def _test_transitive_deps_are_collected(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":mid"]) + analysis_test(name = name, impl = _test_transitive_deps_are_collected_impl, target = name + "_subject") + +def _test_transitive_deps_are_collected_impl(env, target): + _allowlist(env, target).equals( + "\n".join([ + _PKG + "/fixtures/leaf.cpp", + _PKG + "/fixtures/leaf.h", + _PKG + "/fixtures/mid.cpp", + _PKG + "/fixtures/mid.h", + ]) + "\n", + ) + objects = _objects(env, target) + objects.contains("libleaf.a") + objects.contains("libmid.a") + +# --- implementation_deps --------------------------------------------------- + +def _test_implementation_deps_are_followed(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":impl_dep_user"]) + analysis_test(name = name, impl = _test_implementation_deps_are_followed_impl, target = name + "_subject") + +def _test_implementation_deps_are_followed_impl(env, target): + _allowlist(env, target).equals( + "\n".join([ + _PKG + "/fixtures/leaf.cpp", + _PKG + "/fixtures/leaf.h", + _PKG + "/fixtures/user.cpp", + ]) + "\n", + ) + +# --- deduplication across roots ------------------------------------------- + +def _test_shared_dependency_listed_once(name): + coverage_scope( + name = name + "_subject", + testonly = True, + deps = [_FIX + ":mid", _FIX + ":impl_dep_user", _FIX + ":leaf"], + ) + analysis_test(name = name, impl = _test_shared_dependency_listed_once_impl, target = name + "_subject") + +def _test_shared_dependency_listed_once_impl(env, target): + _allowlist(env, target).equals( + "\n".join([ + _PKG + "/fixtures/leaf.cpp", + _PKG + "/fixtures/leaf.h", + _PKG + "/fixtures/mid.cpp", + _PKG + "/fixtures/mid.h", + _PKG + "/fixtures/user.cpp", + ]) + "\n", + ) + +# --- header-only library --------------------------------------------------- + +def _test_header_only_library_has_no_archive(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":header_only"]) + analysis_test(name = name, impl = _test_header_only_library_has_no_archive_impl, target = name + "_subject") + +def _test_header_only_library_has_no_archive_impl(env, target): + _allowlist(env, target).equals(_PKG + "/fixtures/only.h\n") + _objects(env, target).equals("") + +# --- generated sources are excluded --------------------------------------- + +def _test_generated_sources_are_excluded(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":with_generated"]) + analysis_test(name = name, impl = _test_generated_sources_are_excluded_impl, target = name + "_subject") + +def _test_generated_sources_are_excluded_impl(env, target): + # Exactly the checked-in sources: generated.cpp is absent. + _allowlist(env, target).equals( + "\n".join([ + _PKG + "/fixtures/leaf.cpp", + _PKG + "/fixtures/leaf.h", + ]) + "\n", + ) + + # The archive of the library with the generated source is still a baseline object. + _objects(env, target).contains("libwith_generated.a") + +# --- Rust: rust_library (CcInfo) and rust_binary (CrateInfo only) ----------- + +def _test_rust_library_sources_and_archive(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":rlib"]) + analysis_test(name = name, impl = _test_rust_library_sources_and_archive_impl, target = name + "_subject") + +def _test_rust_library_sources_and_archive_impl(env, target): + _allowlist(env, target).equals(_PKG + "/fixtures/lib.rs\n") + + # rules_rust exposes the rlib through CcInfo as a static library; that is the baseline object. + _objects(env, target).contains("rlib") + +def _test_rust_binary_collects_crate_sources_and_executable(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":rbin"]) + analysis_test(name = name, impl = _test_rust_binary_collects_crate_sources_and_executable_impl, target = name + "_subject") + +def _test_rust_binary_collects_crate_sources_and_executable_impl(env, target): + _allowlist(env, target).equals( + "\n".join([ + _PKG + "/fixtures/lib.rs", + _PKG + "/fixtures/main.rs", + ]) + "\n", + ) + objects = _objects(env, target) + objects.contains(_PKG + "/fixtures/rbin") # the coverage-built executable itself + objects.contains("rlib") + +# --- providers / output groups -------------------------------------------- + +def _test_output_groups(name): + coverage_scope(name = name + "_subject", testonly = True, deps = [_FIX + ":mid"]) + analysis_test(name = name, impl = _test_output_groups_impl, target = name + "_subject") + +def _test_output_groups_impl(env, target): + subject = env.expect.that_target(target) + subject.output_group("allowlist").contains_exactly([_PKG + "/" + target.label.name + "_allowlist.txt"]) + subject.output_group("objects").contains_exactly([_PKG + "/" + target.label.name + "_objects.txt"]) + subject.output_group("object_files").contains_predicate(matching.file_basename_equals("libleaf.a")) + subject.default_outputs().contains_at_least([ + _PKG + "/" + target.label.name + "_allowlist.txt", + _PKG + "/" + target.label.name + "_objects.txt", + ]) + +def coverage_scope_test_suite(name): + test_suite( + name = name, + tests = [ + _test_transitive_deps_are_collected, + _test_implementation_deps_are_followed, + _test_shared_dependency_listed_once, + _test_header_only_library_has_no_archive, + _test_generated_sources_are_excluded, + _test_rust_library_sources_and_archive, + _test_rust_binary_collects_crate_sources_and_executable, + _test_output_groups, + ], + ) diff --git a/score_coverage/tests/starlark/fixtures/BUILD b/score_coverage/tests/starlark/fixtures/BUILD new file mode 100644 index 0000000..1ba42de --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/BUILD @@ -0,0 +1,80 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_cc//cc:cc_library.bzl", "cc_library") +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library") + +# Fixtures for the coverage_scope analysis tests. They are only analyzed, +# never built: `manual` keeps them out of wildcard builds. +package(default_visibility = ["//score_coverage/tests/starlark:__subpackages__"]) + +MANUAL = ["manual"] + +cc_library( + name = "leaf", + srcs = ["leaf.cpp"], + hdrs = ["leaf.h"], + tags = MANUAL, +) + +cc_library( + name = "mid", + srcs = ["mid.cpp"], + hdrs = ["mid.h"], + tags = MANUAL, + deps = [":leaf"], +) + +cc_library( + name = "impl_dep_user", + srcs = ["user.cpp"], + implementation_deps = [":leaf"], + tags = MANUAL, +) + +cc_library( + name = "header_only", + hdrs = ["only.h"], + tags = MANUAL, +) + +# A generated source must NOT enter the allowlist (only checked-in sources +# are coverage subjects). +genrule( + name = "gen_source", + outs = ["generated.cpp"], + cmd = "echo 'int g() { return 1; }' > $@", + tags = MANUAL, +) + +cc_library( + name = "with_generated", + srcs = ["generated.cpp"], + tags = MANUAL, + deps = [":leaf"], +) + +rust_library( + name = "rlib", + srcs = ["lib.rs"], + edition = "2021", + tags = MANUAL, +) + +rust_binary( + name = "rbin", + srcs = ["main.rs"], + edition = "2021", + tags = MANUAL, + deps = [":rlib"], +) diff --git a/score_coverage/tests/starlark/fixtures/leaf.cpp b/score_coverage/tests/starlark/fixtures/leaf.cpp new file mode 100644 index 0000000..0252db5 --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/leaf.cpp @@ -0,0 +1,14 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; only analyzed. +int leaf() { return 1; } diff --git a/score_coverage/tests/starlark/fixtures/leaf.h b/score_coverage/tests/starlark/fixtures/leaf.h new file mode 100644 index 0000000..fb28115 --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/leaf.h @@ -0,0 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; never compiled. diff --git a/score_coverage/tests/starlark/fixtures/lib.rs b/score_coverage/tests/starlark/fixtures/lib.rs new file mode 100644 index 0000000..338536f --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/lib.rs @@ -0,0 +1,16 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* +// Fixture for the coverage_scope analysis tests; only analyzed. +pub fn lib() -> i32 { + 1 +} diff --git a/score_coverage/tests/starlark/fixtures/main.rs b/score_coverage/tests/starlark/fixtures/main.rs new file mode 100644 index 0000000..cdfa2db --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/main.rs @@ -0,0 +1,16 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* +// Fixture for the coverage_scope analysis tests; only analyzed. +fn main() { + println!("{}", rlib::lib()); +} diff --git a/score_coverage/tests/starlark/fixtures/mid.cpp b/score_coverage/tests/starlark/fixtures/mid.cpp new file mode 100644 index 0000000..e57ce2d --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/mid.cpp @@ -0,0 +1,14 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; only analyzed. +int mid() { return 2; } diff --git a/score_coverage/tests/starlark/fixtures/mid.h b/score_coverage/tests/starlark/fixtures/mid.h new file mode 100644 index 0000000..fb28115 --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/mid.h @@ -0,0 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; never compiled. diff --git a/score_coverage/tests/starlark/fixtures/only.h b/score_coverage/tests/starlark/fixtures/only.h new file mode 100644 index 0000000..fb28115 --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/only.h @@ -0,0 +1,13 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; never compiled. diff --git a/score_coverage/tests/starlark/fixtures/user.cpp b/score_coverage/tests/starlark/fixtures/user.cpp new file mode 100644 index 0000000..50e0191 --- /dev/null +++ b/score_coverage/tests/starlark/fixtures/user.cpp @@ -0,0 +1,14 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +// Fixture for the coverage_scope analysis tests; only analyzed. +int user() { return 3; } diff --git a/score_coverage/tests/traceability.py b/score_coverage/tests/traceability.py new file mode 100644 index 0000000..f8b4761 --- /dev/null +++ b/score_coverage/tests/traceability.py @@ -0,0 +1,91 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Link test classes to the tool requirements they verify. + +``@verifies(...)`` applies score_tooling's ``add_test_properties`` to every +``test_*`` method of a ``unittest.TestCase`` class. Under ``score_py_pytest`` the +properties (``PartiallyVerifies`` / ``FullyVerifies``, ``TestType``, +``DerivationTechnique``) end up in the JUnit XML that docs-as-code turns into +``testcase`` needs and ``testlink`` back-references on the requirements +(``gd_req__verification_link_tests_python``). + +Outside Bazel (plain ``python -m unittest``) the plugin is absent and the +decorator is a no-op, so the tests stay runnable from an IDE. +""" + +from __future__ import annotations + +from collections.abc import Callable +from typing import Any, Literal + +try: + from attribute_plugin import add_test_properties # type: ignore[import-not-found] # ty: ignore[unresolved-import] +except ImportError: # pragma: no cover - only outside of score_py_pytest + + def add_test_properties(**_kwargs: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]: + """No-op replacement when the pytest plugin is not available.""" + + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + return func + + return decorator + + +TestType = Literal["fault-injection", "interface-test", "requirements-based", "resource-usage"] +Derivation = Literal[ + "requirements-analysis", + "design-analysis", + "boundary-values", + "equivalence-classes", + "fuzz-testing", + "error-guessing", + "explorative-testing", +] + + +def _description_from_name(name: str) -> str: + """``test_gate_fails_at_default_threshold`` -> ``Gate fails at default threshold.``""" + words = name.removeprefix("test_").replace("_", " ").strip() + return (words[:1].upper() + words[1:] + ".") if words else name + + +def verifies( + *partially: str, + fully: tuple[str, ...] = (), + test_type: TestType = "requirements-based", + derivation: Derivation = "requirements-analysis", +) -> Callable[[type], type]: + """Class decorator: every ``test_*`` method verifies the given requirement ids. + + Methods without a docstring get a description derived from their name; an + explicit docstring always wins. + """ + if not partially and not fully: + raise ValueError("verifies() needs at least one requirement id") + + def decorate(cls: type) -> type: + for name, member in list(vars(cls).items()): + if not name.startswith("test_") or not callable(member): + continue + if not (member.__doc__ or "").strip(): + member.__doc__ = _description_from_name(name) + annotated = add_test_properties( + partially_verifies=list(partially) or None, + fully_verifies=list(fully) or None, + test_type=test_type, + derivation_technique=derivation, + )(member) + setattr(cls, name, annotated) + return cls + + return decorate diff --git a/tools/BUILD b/tools/BUILD new file mode 100644 index 0000000..d7ce692 --- /dev/null +++ b/tools/BUILD @@ -0,0 +1,66 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +load("@rules_python//python:defs.bzl", "py_binary", "py_test") +load("@score_tooling//:defs.bzl", "copyright_checker") +load("@score_tooling//third_party/format:macros.bzl", "use_format_targets") + +# Repository hygiene (copyright headers, formatting). Kept out of the root +# package on purpose: these load from dev dependencies, which consumers of +# @score_coverage do not have. + +copyright_checker( + name = "copyright", + srcs = [ + ".bazelrc", + ".github", + "BUILD", + "MODULE.bazel", + "README.md", + "defs.bzl", + "docs", + "integration_tests", + "pyproject.toml", + "score_coverage", + "tools", + ], + config = "@score_tooling//cr_checker/resources:config", + template = "@score_tooling//cr_checker/resources:templates", + visibility = ["//visibility:public"], +) + +# C++ and Rust exist only as fixtures inside the nested integration_tests +# workspace, which has its own toolchains; the main module holds Python, +# Starlark and YAML. +use_format_targets(languages = [ + "python", + "starlark", + "yaml", +]) + +# Structural coverage of this repository's own Python (coverage.py via +# `bazel coverage --combined_report=lcov //score_coverage/tests:all`). +py_binary( + name = "self_coverage_gate", + srcs = ["self_coverage_gate.py"], +) + +py_test( + name = "self_coverage_gate_test", + srcs = [ + "self_coverage_gate.py", + "self_coverage_gate_test.py", + ], + imports = ["."], + main = "self_coverage_gate_test.py", +) diff --git a/tools/linters.bzl b/tools/linters.bzl new file mode 100644 index 0000000..d53d6e1 --- /dev/null +++ b/tools/linters.bzl @@ -0,0 +1,31 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +"""Static-analysis aspects for this repository's Python (ruff, pylint, ty). + +Declared here rather than in score_tooling so the config label resolves +against this repo. Wired through the `lint` config in .bazelrc: + + bazel build --config=lint //score_coverage/... //tools/... +""" + +load("@score_tooling//third_party/lint:macros.bzl", "pylint_lint_aspect", "ruff_lint_aspect", "ty_lint_aspect") + +ruff = ruff_lint_aspect(config = Label("//:pyproject.toml")) + +pylint = pylint_lint_aspect( + binary = Label("@score_tooling//third_party/lint:pylint"), + config = Label("//:pyproject.toml"), +) + +ty = ty_lint_aspect(config = Label("//:pyproject.toml")) diff --git a/tools/self_coverage_gate.py b/tools/self_coverage_gate.py new file mode 100644 index 0000000..7c5a192 --- /dev/null +++ b/tools/self_coverage_gate.py @@ -0,0 +1,205 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Structural-coverage gate for score_coverage's OWN Python code. + +The pipeline this repository ships measures C++ and Rust; its own code is +Python and is measured by coverage.py through `bazel coverage` (rules_python, +configure_coverage_tool = True). This script reads the combined LCOV that +Bazel writes, prints the per-file C0 (line) and C1 (branch) table the +verification report needs, and fails when the totals are below the thresholds. + +Usage: + bazel coverage --combined_report=lcov //score_coverage/tests:all + bazel run //tools:self_coverage_gate -- --min-lines 69 --min-branches 63 \\ + [--lcov bazel-out/_coverage/_coverage_report.dat] [--summary-md out.md] + +Only files under score_coverage/ (excluding tests/) count. +""" + +from __future__ import annotations + +import argparse +import os +import sys +from collections.abc import Sequence +from dataclasses import dataclass, field +from pathlib import Path + +DEFAULT_LCOV = Path("bazel-out/_coverage/_coverage_report.dat") +SCOPE_PREFIX = "score_coverage/" +EXCLUDED_PREFIX = "score_coverage/tests/" + + +@dataclass +class FileCoverage: + """Line and branch counters of one source file.""" + + path: str + lines_found: int = 0 + lines_hit: int = 0 + branches_found: int = 0 + branches_hit: int = 0 + + def add(self, other: FileCoverage) -> None: + """Accumulate another record of the same file (one per test target).""" + self.lines_found += other.lines_found + self.lines_hit += other.lines_hit + self.branches_found += other.branches_found + self.branches_hit += other.branches_hit + + +@dataclass +class Totals: + """All in-scope files plus their sums.""" + + files: list[FileCoverage] = field(default_factory=list) + + @property + def lines_found(self) -> int: + """Sum of ``lines_found`` over all files.""" + return sum(f.lines_found for f in self.files) + + @property + def lines_hit(self) -> int: + """Sum of ``lines_hit`` over all files.""" + return sum(f.lines_hit for f in self.files) + + @property + def branches_found(self) -> int: + """Sum of ``branches_found`` over all files.""" + return sum(f.branches_found for f in self.files) + + @property + def branches_hit(self) -> int: + """Sum of ``branches_hit`` over all files.""" + return sum(f.branches_hit for f in self.files) + + +def pct(hit: int, found: int) -> float | None: + """Percentage, or None when nothing was found (no verdict).""" + return None if found == 0 else 100.0 * hit / found + + +def in_scope(path: str) -> bool: + """True for the tool's own sources (score_coverage/, excluding tests/).""" + return path.startswith(SCOPE_PREFIX) and not path.startswith(EXCLUDED_PREFIX) + + +def parse_lcov(path: Path) -> Totals: + """Aggregate LF/LH/BRF/BRH per in-scope source file (records may repeat per test).""" + if not path.is_file(): + raise FileNotFoundError(f"LCOV file not found: {path}") + per_file: dict[str, FileCoverage] = {} + current: FileCoverage | None = None + with open(path, encoding="utf-8") as f: + for raw in f: + line = raw.rstrip("\n") + if line.startswith("SF:"): + current = FileCoverage(path=line[3:]) + elif line == "end_of_record": + if current is not None and in_scope(current.path): + per_file.setdefault(current.path, FileCoverage(path=current.path)).add(current) + current = None + elif current is not None: + key, _, value = line.partition(":") + if key in ("LF", "LH", "BRF", "BRH"): + number = int(value) + if number < 0: + raise ValueError(f"negative {key} in record for {current.path}") + attr = {"LF": "lines_found", "LH": "lines_hit", "BRF": "branches_found", "BRH": "branches_hit"}[key] + setattr(current, attr, getattr(current, attr) + number) + for fc in per_file.values(): + if fc.lines_hit > fc.lines_found or fc.branches_hit > fc.branches_found: + raise ValueError(f"corrupt LCOV record for {fc.path}: hit count exceeds found count") + return Totals(files=sorted(per_file.values(), key=lambda fc: fc.path)) + + +def fmt(value: float | None) -> str: + """Fixed-width percentage, or n/a.""" + return " n/a " if value is None else f"{value:6.2f}" + + +def render_table(totals: Totals, markdown: bool) -> str: + """Per-file C0/C1 table plus a TOTAL row, as plain text or markdown.""" + rows = [(f.path, f.lines_hit, f.lines_found, f.branches_hit, f.branches_found) for f in totals.files] + rows.append(("TOTAL", totals.lines_hit, totals.lines_found, totals.branches_hit, totals.branches_found)) + if markdown: + out = ["| File | Lines (C0) | Branches (C1) |", "|---|---:|---:|"] + for path, lh, lf, bh, bf in rows: + out.append( + f"| `{path}` | {fmt(pct(lh, lf)).strip()}% ({lh}/{lf}) | {fmt(pct(bh, bf)).strip()}% ({bh}/{bf}) |" + ) + return "\n".join(out) + "\n" + width = max(len(r[0]) for r in rows) + out = [f"{'File':<{width}} {'Lines (C0)':>22} {'Branches (C1)':>22}"] + for path, lh, lf, bh, bf in rows: + out.append(f"{path:<{width}} {fmt(pct(lh, lf))}% ({lh:>4}/{lf:>4}) {fmt(pct(bh, bf))}% ({bh:>4}/{bf:>4})") + return "\n".join(out) + "\n" + + +def evaluate(totals: Totals, min_lines: float, min_branches: float) -> list[str]: + """Return the list of gate violations (empty when the gate passes).""" + problems = [] + line_pct = pct(totals.lines_hit, totals.lines_found) + branch_pct = pct(totals.branches_hit, totals.branches_found) + if line_pct is None: + problems.append("no instrumented lines found in scope; nothing to gate on") + elif line_pct < min_lines: + problems.append(f"line coverage {line_pct:.2f}% is below the minimum of {min_lines:g}%") + if branch_pct is None: + problems.append("no branch data found in scope; nothing to gate on") + elif branch_pct < min_branches: + problems.append(f"branch coverage {branch_pct:.2f}% is below the minimum of {min_branches:g}%") + return problems + + +def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace: + """Parse the command line (``argv`` defaults to ``sys.argv[1:]``).""" + parser = argparse.ArgumentParser(description=(__doc__ or "").splitlines()[0]) + parser.add_argument("--lcov", type=Path, default=None, help=f"Combined LCOV (default: {DEFAULT_LCOV})") + parser.add_argument("--min-lines", type=float, required=True, help="Minimum line coverage in percent") + parser.add_argument("--min-branches", type=float, required=True, help="Minimum branch coverage in percent") + parser.add_argument("--summary-md", type=Path, default=None, help="Append a markdown table to this file") + return parser.parse_args(argv) + + +def main(argv: Sequence[str] | None = None) -> int: + """Entry point; returns the process exit code (0 pass, 1 below threshold, 2 no verdict).""" + args = parse_args(argv) + workspace = Path(os.environ.get("BUILD_WORKSPACE_DIRECTORY", ".")) + lcov = args.lcov if args.lcov is not None else workspace / DEFAULT_LCOV + if not lcov.is_absolute(): + lcov = workspace / lcov + for threshold in (args.min_lines, args.min_branches): + if not 0.0 <= threshold <= 100.0: + print(f"ERROR: thresholds must be within [0, 100], got {threshold}", file=sys.stderr) + return 2 + try: + totals = parse_lcov(lcov) + except (FileNotFoundError, ValueError) as exc: + print(f"ERROR: {exc}", file=sys.stderr) + return 2 + print(render_table(totals, markdown=False)) + if args.summary_md is not None: + target = args.summary_md if args.summary_md.is_absolute() else workspace / args.summary_md + with open(target, "a", encoding="utf-8") as f: + f.write("## Structural coverage of score_coverage (coverage.py)\n\n") + f.write(render_table(totals, markdown=True)) + problems = evaluate(totals, args.min_lines, args.min_branches) + for problem in problems: + print(f"ERROR: {problem}", file=sys.stderr) + return 1 if problems else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/self_coverage_gate_test.py b/tools/self_coverage_gate_test.py new file mode 100644 index 0000000..5e5d4f8 --- /dev/null +++ b/tools/self_coverage_gate_test.py @@ -0,0 +1,119 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +"""Tests for the repository's own coverage gate.""" +# Test modules: docstrings on every test method add nothing, tests exercise +# private helpers on purpose, TemporaryDirectory is closed in tearDown, and setUp +# fixtures are attributes. +# pylint: disable=missing-function-docstring,missing-class-docstring,protected-access,consider-using-with +# pylint: disable=too-many-instance-attributes + +import io +import tempfile +import unittest +from contextlib import redirect_stderr, redirect_stdout +from pathlib import Path + +import self_coverage_gate as gate + +LCOV = ( + "SF:score_coverage/a.py\nLF:10\nLH:8\nBRF:4\nBRH:2\nend_of_record\n" + "SF:score_coverage/a.py\nLF:10\nLH:9\nBRF:4\nBRH:3\nend_of_record\n" # same file from a second test + "SF:score_coverage/tests/a_test.py\nLF:50\nLH:50\nBRF:0\nBRH:0\nend_of_record\n" # excluded + "SF:external/other.py\nLF:5\nLH:0\nend_of_record\n" # out of scope + "SF:score_coverage/b.py\nLF:10\nLH:0\nBRF:2\nBRH:0\nend_of_record\n" +) + + +class ParseLcovTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.lcov = Path(self.tmp.name) / "lcov.dat" + self.lcov.write_text(LCOV, encoding="utf-8") + + def tearDown(self): + self.tmp.cleanup() + + def test_scope_and_aggregation(self): + totals = gate.parse_lcov(self.lcov) + self.assertEqual([f.path for f in totals.files], ["score_coverage/a.py", "score_coverage/b.py"]) + a = totals.files[0] + self.assertEqual((a.lines_found, a.lines_hit, a.branches_found, a.branches_hit), (20, 17, 8, 5)) + self.assertEqual((totals.lines_found, totals.lines_hit), (30, 17)) + self.assertEqual((totals.branches_found, totals.branches_hit), (10, 5)) + + def test_missing_file(self): + with self.assertRaises(FileNotFoundError): + gate.parse_lcov(self.lcov.parent / "missing") + + def test_corrupt_record(self): + self.lcov.write_text("SF:score_coverage/a.py\nLF:1\nLH:2\nend_of_record\n", encoding="utf-8") + with self.assertRaises(ValueError): + gate.parse_lcov(self.lcov) + + +class EvaluateTest(unittest.TestCase): + def _totals(self, lh, lf, bh, bf): + return gate.Totals(files=[gate.FileCoverage("score_coverage/x.py", lf, lh, bf, bh)]) + + def test_pass_and_fail(self): + self.assertEqual(gate.evaluate(self._totals(17, 30, 5, 10), 50, 50), []) + problems = gate.evaluate(self._totals(17, 30, 5, 10), 60, 51) + self.assertEqual(len(problems), 2) + self.assertIn("line coverage 56.67%", problems[0]) + self.assertIn("branch coverage 50.00%", problems[1]) + + def test_no_data_is_a_failure(self): + self.assertEqual(len(gate.evaluate(gate.Totals(), 0, 0)), 2) + + +class MainTest(unittest.TestCase): + def setUp(self): + self.tmp = tempfile.TemporaryDirectory() + self.root = Path(self.tmp.name) + (self.root / "lcov.dat").write_text(LCOV, encoding="utf-8") + + def tearDown(self): + self.tmp.cleanup() + + def _main(self, argv): + out, err = io.StringIO(), io.StringIO() + with redirect_stdout(out), redirect_stderr(err): + rc = gate.main(argv) + return rc, out.getvalue(), err.getvalue() + + def test_exit_codes_and_summary(self): + lcov = str(self.root / "lcov.dat") + rc, out, _ = self._main(["--lcov", lcov, "--min-lines", "50", "--min-branches", "50"]) + self.assertEqual(rc, 0) + self.assertIn("TOTAL", out) + self.assertIn("score_coverage/b.py", out) + rc, _, err = self._main(["--lcov", lcov, "--min-lines", "90", "--min-branches", "50"]) + self.assertEqual(rc, 1) + self.assertIn("below the minimum", err) + md = self.root / "summary.md" + md.write_text("# before\n", encoding="utf-8") + rc, _, _ = self._main(["--lcov", lcov, "--min-lines", "0", "--min-branches", "0", "--summary-md", str(md)]) + self.assertEqual(rc, 0) + text = md.read_text(encoding="utf-8") + self.assertTrue(text.startswith("# before\n")) + self.assertIn("| `score_coverage/a.py` | 85.00% (17/20) | 62.50% (5/8) |", text) + + def test_bad_inputs(self): + rc, _, _ = self._main(["--lcov", str(self.root / "nope"), "--min-lines", "0", "--min-branches", "0"]) + self.assertEqual(rc, 2) + rc, _, _ = self._main(["--lcov", str(self.root / "lcov.dat"), "--min-lines", "101", "--min-branches", "0"]) + self.assertEqual(rc, 2) + + +if __name__ == "__main__": + unittest.main()