diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..18bb4182d --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +7.5.0 diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index b7c08484a..e4e3e5f67 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -2,13 +2,16 @@ name: Build and Test on: pull_request: + types: [opened, reopened, synchronize, ready_for_review, review_requested] branches-ignore: - - 'gh-pages' + - "gh-pages" push: branches: - - 'master' + - "master" + - "prepare-release" tags: - v* + workflow_dispatch: permissions: contents: read @@ -16,7 +19,7 @@ permissions: jobs: check_code_format: name: Check code formatting - runs-on: 'ubuntu-20.04' + runs-on: "ubuntu-22.04" # The code currently doesn't pass formatting. # Enable this workflow job once it does, to detect regressions. if: false @@ -28,7 +31,7 @@ jobs: plain_makefile: name: Build and test using plain Makefile - runs-on: 'ubuntu-20.04' + runs-on: "ubuntu-22.04" steps: - uses: actions/checkout@v4 - name: Build (make all) @@ -40,19 +43,27 @@ jobs: python_module: name: Build and test Python module - runs-on: 'ubuntu-20.04' + runs-on: "ubuntu-22.04" steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.9" - name: Build run: | - python setup.py build + pip install build + python -m build --sdist --wheel - name: Test run: | - python setup.py test + python -m venv --upgrade-deps --clear trial && + cd trial && + source bin/activate && + pip install ../dist/jsonnet-*.whl && + python3 ../python/_jsonnet_test.py cmake_build: name: Build and test using CMake - runs-on: 'ubuntu-20.04' + runs-on: "ubuntu-22.04" steps: - uses: actions/checkout@v4 - name: Configure (cmake) @@ -69,12 +80,22 @@ jobs: bazel_build: name: Build and test using Bazel - runs-on: 'ubuntu-20.04' + runs-on: "ubuntu-22.04" steps: - uses: actions/checkout@v4 - name: Build run: | - bazel build -c opt //cmd:all + bazelisk build --lockfile_mode=error -c opt //cmd:all - name: Test run: | - bazel test //... + bazelisk test --lockfile_mode=error //... + + bazel_use_module: + name: Build Bazel example + runs-on: "ubuntu-22.04" + steps: + - uses: actions/checkout@v4 + - name: Build + run: | + cd examples/bazel + bazelisk build --lockfile_mode=off //... diff --git a/.github/workflows/build_python_wheel.yml b/.github/workflows/build_python_wheel.yml deleted file mode 100644 index d0d1fb613..000000000 --- a/.github/workflows/build_python_wheel.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build Python Wheel - -# For now, just trigger this workflow manually. -on: [workflow_dispatch] - -jobs: - build_wheels: - name: Build wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - #os: [ubuntu-20.04, windows-latest, macos-latest] - os: [ubuntu-20.04, windows-latest] - - # We're using third party actions (not just the official GitHub-maintained actions), - # so it's very important to minimise the ability for this workflow to do anything dangerous. - # Grant it only read access to the repository content (which is public anyway); it shouldn't - # need anything else. - permissions: - contents: read - - steps: - - uses: actions/checkout@v4 - - - name: Build wheels - uses: pypa/cibuildwheel@v2.16.5 - env: - # Skip PyPy, 32-bit Windows, 32-bit Linux, and CPython before 3.9. - # See https://cibuildwheel.readthedocs.io/en/stable/options/#examples_1 - CIBW_SKIP: "*-win32 pp* *-manylinux_i686 *-musllinux_i686 cp36-* cp37-* cp38-*" - CIBW_TEST_COMMAND: > - python {package}/python/_jsonnet_test.py - - - uses: actions/upload-artifact@v4 - with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} - path: ./wheelhouse/*.whl diff --git a/.github/workflows/create_archive.sh b/.github/workflows/create_archive.sh new file mode 100755 index 000000000..5e0da8177 --- /dev/null +++ b/.github/workflows/create_archive.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit -o nounset -o pipefail + +JSONNET_VERSION="$(grep -Ee '^\s*#\s*define\s+LIB_JSONNET_VERSION\s+"[^"]+"\s*$' include/libjsonnet.h | sed -E -e 's/[^"]+"([^"]+)".*/\1/')" + +# GITHUB_REF is set by GH actions, see +# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables + +VERSION_SUFFIX= +if [[ ( "${GITHUB_REF_TYPE}" != 'branch' || "${GITHUB_REF_NAME}" != "prepare-release" ) && + ( "${GITHUB_REF_TYPE}" != 'tag' || "${GITHUB_REF_NAME}" != "${JSONNET_VERSION}" ) ]]; then + >&2 echo 'WARNING: Jsonnet library version in header does not match release ref. Adding commit suffix.' + VERSION_SUFFIX="-${GITHUB_SHA:0:9}" +fi + +# A prefix is added to better match the GitHub generated archives. +PREFIX="jsonnet-${JSONNET_VERSION}${VERSION_SUFFIX}" +ARCHIVE="jsonnet-${JSONNET_VERSION}${VERSION_SUFFIX}.tar.gz" +git archive --format=tar --prefix=${PREFIX}/ "${GITHUB_SHA}" | gzip > "$ARCHIVE" +ARCHIVE_SHA=$(shasum -a 256 "$ARCHIVE" | awk '{print $1}') + +echo "archive_sha256=${ARCHIVE_SHA}" >> "$GITHUB_OUTPUT" +echo "jsonnet_version=${JSONNET_VERSION}" >> "$GITHUB_OUTPUT" +echo "jsonnet_version_permanent=${JSONNET_VERSION}${VERSION_SUFFIX}" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/create_archive_and_notes.sh b/.github/workflows/create_archive_and_notes.sh deleted file mode 100755 index 460ea3f74..000000000 --- a/.github/workflows/create_archive_and_notes.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2023 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -o errexit -o nounset -o pipefail - -# Set by GH actions, see -# https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables -TAG=${GITHUB_REF_NAME} -# A prefix is added to better match the GitHub generated archives. -PREFIX="jsonnet-${TAG}" -ARCHIVE="jsonnet-$TAG.tar.gz" -git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE -SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}') - -cat > release_notes.txt << EOF -### Importing Jsonnet in a project that uses Bazel - -#### Using Bzlmod with Bazel 6 - -Add to your \`MODULE.bazel\` file: - -\`\`\`starlark -bazel_dep(name = "jsonnet", version = "${TAG}") -\`\`\` - -#### Using WORKSPACE - -Paste this snippet into your \`WORKSPACE\` file: - -\`\`\`starlark -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -http_archive( - name = "jsonnet", - sha256 = "${SHA}", - strip_prefix = "${PREFIX}", - url = "https://github.com/google/jsonnet/releases/download/${TAG}/jsonnet-${TAG}.tar.gz", -) -\`\`\` - -EOF diff --git a/.github/workflows/publish-python.yml b/.github/workflows/publish-python.yml new file mode 100644 index 000000000..1c5a83454 --- /dev/null +++ b/.github/workflows/publish-python.yml @@ -0,0 +1,108 @@ +name: Build and Publish Python Package + +# Be very careful granting extra permissions here, as this workflow uses third party actions. +# Prefer to pin to exact commits for third-party actions. I'm making an exception for actions +# maintained by GitHub itself. + +# For now, just trigger this workflow manually. +on: + workflow_dispatch: + inputs: + upload_to_pypi: + description: "Upload generate package files to PyPI" + required: true + type: boolean + pypi_environment: + description: "Which PyPI instance to publish to" + required: true + type: choice + options: + - testpypi + - pypi + +jobs: + build_sdist: + name: Build Python sdist + runs-on: ubuntu-24.04 + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + cache: "pip" + + - run: pip install 'build==1.2.2' + + - name: Build sdist + run: python3 -m build --sdist + + - uses: actions/upload-artifact@v4 + with: + name: sdist + path: ./dist/*.gz + if-no-files-found: error + + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, windows-latest, macos-13, macos-latest] + + permissions: + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Build wheels + uses: pypa/cibuildwheel@ee63bf16da6cddfb925f542f2c7b59ad50e93969 # v2.22.0 + env: + # Skip PyPy, 32-bit Windows, 32-bit Linux, and CPython before 3.9. + # See https://cibuildwheel.readthedocs.io/en/stable/options/#examples_1 + CIBW_SKIP: "*-win32 pp* *-manylinux_i686 *-musllinux_i686 cp36-* cp37-* cp38-*" + CIBW_TEST_COMMAND: > + python {package}/python/_jsonnet_test.py + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }} + path: ./wheelhouse/*.whl + if-no-files-found: error + + upload_to_pypi: + name: "Upload packages to PyPI" + needs: [build_sdist, build_wheels] + runs-on: ubuntu-24.04 + if: "${{ inputs.upload_to_pypi }}" + permissions: + contents: read + id-token: write # Needed for PyPI Trusted Publishing + environment: + name: "${{ inputs.pypi_environment }}" + url: "${{ inputs.pypi_environment == 'pypi' && 'https://pypi.org/p/jsonnet' || 'https://test.pypi.org/p/jsonnet' }}" + steps: + - uses: actions/download-artifact@v4 + with: + path: cibw-wheels + pattern: cibw-wheels-* + - uses: actions/download-artifact@v4 + with: + path: sdist + name: sdist + - name: Flatten wheels to one directory + run: | + mkdir dist + find cibw-wheels/ -type f -name '*.whl' -exec mv '{}' ./dist/ ';' + find sdist/ -type f -name '*.gz' -exec mv '{}' ./dist/ ';' + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 + with: + verbose: true + print-hash: true + repository-url: "${{ inputs.pypi_environment == 'testpypi' && 'https://test.pypi.org/legacy/' || '' }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d497b3e48..b8ba3fbf2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,23 +16,30 @@ name: Release on: - push: - tags: - - "*.*.*" + workflow_dispatch: + inputs: + prerelease: + description: If set, publish this as a release candidate / prerelease version. + type: boolean + required: true jobs: build: - runs-on: ubuntu-latest + permissions: + contents: write + runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v2 - - name: Create release archive and notes - run: .github/workflows/create_archive_and_notes.sh + uses: actions/checkout@v4 + - name: Create release archive + id: create_archive + run: .github/workflows/create_archive.sh - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1 with: - # Use GH feature to populate the changelog automatically - generate_release_notes: true - body_path: release_notes.txt + name: ${{ steps.create_archive.outputs.jsonnet_version }} + tag_name: ${{ steps.create_archive.outputs.jsonnet_version }} + prerelease: ${{ inputs.prerelease }} + draft: true fail_on_unmatched_files: true files: jsonnet-*.tar.gz diff --git a/CMakeLists.txt b/CMakeLists.txt index 213539449..3413ea14f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 2.8.7...4.0) project(jsonnet C CXX) include(ExternalProject) @@ -36,8 +36,8 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${GLOBAL_OUTPUT_PATH}) if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") set(OPT "-O3") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Wextra -pedantic -std=c99 -O3 ${OPT}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Woverloaded-virtual -pedantic -std=c++17 -fPIC ${OPT}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Wextra -Wimplicit-fallthrough -pedantic -std=c99 ${OPT}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Wimplicit-fallthrough -Woverloaded-virtual -pedantic -std=c++17 -fPIC ${OPT}") else() # TODO: Windows support. message(FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER_ID} not supported") @@ -133,6 +133,6 @@ if (BUILD_TESTS) # target runs tests without building them. add_custom_target(run_tests COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS libjsonnet_test libjsonnet_test_file libjsonnet_test_snippet - jsonnet parser_test lexer_test libjsonnet++_test libjsonnet_test_locale + jsonnet unicode_test parser_test lexer_test libjsonnet++_test libjsonnet_test_locale ) endif() diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index 41fac662e..7f7d802ad 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -1,7 +1,7 @@ # CMake script run a generation-time. This must be separate from the main # CMakeLists.txt file to allow downloading and building googletest at generation # time. -cmake_minimum_required(VERSION 2.8.2) +cmake_minimum_required(VERSION 2.8.2...4.0) project(googletest-download NONE) diff --git a/MODULE.bazel b/MODULE.bazel index 94ac2641a..32c00af66 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,12 +1,7 @@ -module(name = "jsonnet", version = "0.0.0") - -bazel_dep(name = "googletest", version = "1.11.0", repo_name = "com_google_googletest") - -build_defs = use_extension("//tools/build_defs:extensions.bzl", "build_defs") -use_repo( - build_defs, - "default_python3_headers", - "io_bazel_rules_jsonnet", +module( + name = "jsonnet", + version = "0.21.0", ) -register_toolchains("//platform_defs:default_python3_toolchain") +bazel_dep(name = "googletest", version = "1.16.0") +bazel_dep(name = "rules_python", version = "1.2.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 000000000..4ffe2d900 --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,3263 @@ +{ + "lockFileVersion": 13, + "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.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/source.json": "1b996859f840d8efc7c720efc61dcf2a84b1261cb3974cbbe9b6666ebf567775", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.15.1/source.json": "517f2b77430084c541bc9be2db63fdcbb7102938c5f64c17ee60ffda2e5cf07b", + "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "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.21.0/source.json": "3e8379efaaef53ce35b7b8ba419df829315a880cb0a030e5bb45c96d6d5ecb5f", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "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.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", + "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/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/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.16.0/MODULE.bazel": "a175623c69e94fca4ca7acbc12031e637b0c489318cd4805606981d4d7adb34a", + "https://bcr.bazel.build/modules/googletest/1.16.0/source.json": "dd011b202542efcd4c0e3df34b1558d41598c6f287846728315ded5f7984b77a", + "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/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5", + "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/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "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-rc3/source.json": "c16a6488fb279ef578da7098e605082d72ed85fc8d843eaae81e7d27d0f4625d", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "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.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca", + "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.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.17/source.json": "4db99b3f55c90ab28d14552aa0632533e3e8e5e9aea0f5c24ac0014282c2a7c5", + "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_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.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.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1", + "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.5.1/source.json": "db1a77d81b059e0f84985db67a22f3f579a529a86b7997605be3d214a0abe38e", + "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/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.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_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.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "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.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/source.json": "17a2e195f56cb28d6bbf763e49973d13890487c6945311ed141e196fb660426d", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "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.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "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.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.2.0/MODULE.bazel": "5aeeb48b2a6c19d668b48adf2b8a2b209a6310c230db0ce77450f148a89846e4", + "https://bcr.bazel.build/modules/rules_python/1.2.0/source.json": "5b7892685c9a843526fd5a31e7d7a93eb819c59fd7b7fc444b5b143558e1b073", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95", + "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.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "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/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "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.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": { + "general": { + "bzlTransitiveDigest": "ltCGFbl/LQQZXn/LEMXfKX7pGwyqNiOCHcmiQW0tmjM=", + "usagesDigest": "2Jj0sTGzjx2KfYRjWYbL6DZ1bi8HL2roIAGfOViiul8=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_apple_cc_toolchains": { + "bzlFile": "@@apple_support~//crosstool:setup.bzl", + "ruleClassName": "_apple_cc_autoconf_toolchains", + "attributes": {} + }, + "local_config_apple_cc": { + "bzlFile": "@@apple_support~//crosstool:setup.bzl", + "ruleClassName": "_apple_cc_autoconf", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "apple_support~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@platforms//host:extension.bzl%host_platform": { + "general": { + "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", + "usagesDigest": "hgylFkgWSg0ulUwWZzEM1aIftlUnbmw2ynWLdEfHnZc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "host_platform": { + "bzlFile": "@@platforms//host:extension.bzl", + "ruleClassName": "host_platform_repo", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@pybind11_bazel~//:internal_configure.bzl%internal_configure_extension": { + "general": { + "bzlTransitiveDigest": "CyAKLVVonohnkTSqg9II/HA7M49sOlnMkgMHL3CmDuc=", + "usagesDigest": "mFrTHX5eCiNU/OIIGVHH3cOILY9Zmjqk8RQYv8o6Thk=", + "recordedFileInputs": { + "@@pybind11_bazel~//MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "pybind11": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "build_file": "@@pybind11_bazel~//:pybind11-BUILD.bazel", + "strip_prefix": "pybind11-2.12.0", + "urls": [ + "https://github.com/pybind/pybind11/archive/v2.12.0.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "pybind11_bazel~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_fuzzing~//fuzzing/private:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "hVgJRQ3Er45/UUAgNn1Yp2Khcp/Y8WyafA2kXIYmQ5M=", + "usagesDigest": "YnIrdgwnf3iCLfChsltBdZ7yOJh706lpa2vww/i2pDI=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "platforms": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@rules_fuzzing~//fuzzing/private/oss_fuzz:repository.bzl", + "ruleClassName": "oss_fuzz_repository", + "attributes": {} + }, + "honggfuzz": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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_java~//java:rules_java_deps.bzl%compatibility_proxy": { + "general": { + "bzlTransitiveDigest": "KIX40nDfygEWbU+rq3nYpt3tVgTK/iO8PKh5VMBlN7M=", + "usagesDigest": "pwHZ+26iLgQdwvdZeA5wnAjKnNI3y6XO2VbhOTeo5h8=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "compatibility_proxy": { + "bzlFile": "@@rules_java~//java:rules_java_deps.bzl", + "ruleClassName": "_compatibility_proxy_repo_rule", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_java~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_kotlin~//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "fus14IFJ/1LGWWGKPH/U18VnJCoMjfDt1ckahqCnM0A=", + "usagesDigest": "aJF6fLy82rR95Ff5CZPAqxNoFgOMLMN5ImfBS0nhnkg=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "bzlFile": "@@rules_kotlin~//src/main/starlark/core/repositories:compiler.bzl", + "ruleClassName": "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": { + "bzlFile": "@@rules_kotlin~//src/main/starlark/core/repositories:compiler.bzl", + "ruleClassName": "kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "bzlFile": "@@rules_kotlin~//src/main/starlark/core/repositories:ksp.bzl", + "ruleClassName": "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": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "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:pip.bzl%pip": { + "general": { + "bzlTransitiveDigest": "AKdrDf9J5WoBrjLNa6jeljwaBd18qkcctOY+/TfZOJg=", + "usagesDigest": "DDv8+OI32dAZE66sQjDPLMBD6x6+Bq7lrimlbCRZ+/Q=", + "recordedFileInputs": { + "@@rules_python~//tools/publish/requirements_linux.txt": "d576e0d8542df61396a9b38deeaa183c24135ed5e8e73bb9622f298f2671811e", + "@@rules_fuzzing~//fuzzing/requirements.txt": "ab04664be026b632a0d2a2446c4f65982b7654f5b6851d2f9d399a19b7242a5b", + "@@rules_python~//tools/publish/requirements_windows.txt": "d18538a3982beab378fd5687f4db33162ee1ece69801f9a451661b1b64286b76", + "@@protobuf~//python/requirements.txt": "983be60d3cec4b319dcab6d48aeb3f5b2f7c3350f26b3a9e97486c37967c73c5", + "@@rules_python~//tools/publish/requirements_darwin.txt": "095d4a4f3d639dce831cd493367631cd51b53665292ab20194bac2c0c6458fa8" + }, + "recordedDirentsInputs": {}, + "envVariables": { + "RULES_PYTHON_REPO_DEBUG": null, + "RULES_PYTHON_REPO_DEBUG_VERBOSITY": null + }, + "generatedRepoSpecs": { + "pip_deps_310_numpy": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_10_host//:python", + "repo": "pip_deps_310", + "requirement": "numpy<=1.26.1" + } + }, + "pip_deps_310_setuptools": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_10_host//:python", + "repo": "pip_deps_310", + "requirement": "setuptools<=70.3.0" + } + }, + "pip_deps_311_numpy": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "pip_deps_311", + "requirement": "numpy<=1.26.1" + } + }, + "pip_deps_311_setuptools": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "pip_deps_311", + "requirement": "setuptools<=70.3.0" + } + }, + "pip_deps_312_numpy": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "repo": "pip_deps_312", + "requirement": "numpy<=1.26.1" + } + }, + "pip_deps_312_setuptools": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "repo": "pip_deps_312", + "requirement": "setuptools<=70.3.0" + } + }, + "pip_deps_38_numpy": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_8_host//:python", + "repo": "pip_deps_38", + "requirement": "numpy<=1.26.1" + } + }, + "pip_deps_38_setuptools": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_8_host//:python", + "repo": "pip_deps_38", + "requirement": "setuptools<=70.3.0" + } + }, + "pip_deps_39_numpy": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_9_host//:python", + "repo": "pip_deps_39", + "requirement": "numpy<=1.26.1" + } + }, + "pip_deps_39_setuptools": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@pip_deps//{name}:{target}", + "python_interpreter_target": "@@rules_python~~python~python_3_9_host//:python", + "repo": "pip_deps_39", + "requirement": "setuptools<=70.3.0" + } + }, + "rules_fuzzing_py_deps_310_absl_py": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_10_host//:python", + "repo": "rules_fuzzing_py_deps_310", + "requirement": "absl-py==2.0.0 --hash=sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3" + } + }, + "rules_fuzzing_py_deps_310_six": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_10_host//:python", + "repo": "rules_fuzzing_py_deps_310", + "requirement": "six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + } + }, + "rules_fuzzing_py_deps_311_absl_py": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_fuzzing_py_deps_311", + "requirement": "absl-py==2.0.0 --hash=sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3" + } + }, + "rules_fuzzing_py_deps_311_six": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_fuzzing_py_deps_311", + "requirement": "six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + } + }, + "rules_fuzzing_py_deps_312_absl_py": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "repo": "rules_fuzzing_py_deps_312", + "requirement": "absl-py==2.0.0 --hash=sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3" + } + }, + "rules_fuzzing_py_deps_312_six": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "repo": "rules_fuzzing_py_deps_312", + "requirement": "six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + } + }, + "rules_fuzzing_py_deps_38_absl_py": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_8_host//:python", + "repo": "rules_fuzzing_py_deps_38", + "requirement": "absl-py==2.0.0 --hash=sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3" + } + }, + "rules_fuzzing_py_deps_38_six": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_8_host//:python", + "repo": "rules_fuzzing_py_deps_38", + "requirement": "six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + } + }, + "rules_fuzzing_py_deps_39_absl_py": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_9_host//:python", + "repo": "rules_fuzzing_py_deps_39", + "requirement": "absl-py==2.0.0 --hash=sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3" + } + }, + "rules_fuzzing_py_deps_39_six": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_fuzzing_py_deps//{name}:{target}", + "extra_pip_args": [ + "--require-hashes" + ], + "python_interpreter_target": "@@rules_python~~python~python_3_9_host//:python", + "repo": "rules_fuzzing_py_deps_39", + "requirement": "six==1.16.0 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + } + }, + "rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "backports.tarfile-1.2.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", + "urls": [ + "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "backports_tarfile-1.2.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", + "urls": [ + "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_certifi_py3_none_any_922820b5": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "certifi-2024.8.30-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "urls": [ + "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_certifi_sdist_bec941d2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "certifi-2024.8.30.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", + "urls": [ + "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "urls": [ + "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "urls": [ + "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "urls": [ + "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "urls": [ + "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "urls": [ + "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", + "urls": [ + "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_sdist_1c39c601": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cffi-1.17.1.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "urls": [ + "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "urls": [ + "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "urls": [ + "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "urls": [ + "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "urls": [ + "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "urls": [ + "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "urls": [ + "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "urls": [ + "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "urls": [ + "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "urls": [ + "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "urls": [ + "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "urls": [ + "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "urls": [ + "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "urls": [ + "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_sdist_223217c3": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "charset_normalizer-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "urls": [ + "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "urls": [ + "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "urls": [ + "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", + "urls": [ + "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "urls": [ + "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "urls": [ + "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "urls": [ + "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_sdist_315b9001": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cryptography-43.0.3.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "urls": [ + "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "docutils-0.21.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", + "urls": [ + "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_docutils_sdist_3a6b1873": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "docutils-0.21.2.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "urls": [ + "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_idna_py3_none_any_946d195a": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "idna-3.10-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", + "urls": [ + "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_idna_sdist_12f65c9b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "idna-3.10.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "urls": [ + "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "importlib_metadata-8.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "urls": [ + "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_sdist_71522656": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "importlib_metadata-8.5.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", + "urls": [ + "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.classes-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", + "urls": [ + "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco.classes-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "urls": [ + "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.context-6.0.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", + "urls": [ + "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_context-6.0.1.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "urls": [ + "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.functools-4.1.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649", + "urls": [ + "https://files.pythonhosted.org/packages/9f/4f/24b319316142c44283d7540e76c7b5a6dbd5db623abd86bb7b3491c21018/jaraco.functools-4.1.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_functools-4.1.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "urls": [ + "https://files.pythonhosted.org/packages/ab/23/9894b3df5d0a6eb44611c36aec777823fc2e07740dabbd0b810e19594013/jaraco_functools-4.1.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "jeepney-0.8.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755", + "urls": [ + "https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jeepney_sdist_5efe48d2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jeepney-0.8.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", + "urls": [ + "https://files.pythonhosted.org/packages/d6/f4/154cf374c2daf2020e05c3c6a03c91348d59b23c5366e968feb198306fdf/jeepney-0.8.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_keyring_py3_none_any_5426f817": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "keyring-25.4.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", + "urls": [ + "https://files.pythonhosted.org/packages/83/25/e6d59e5f0a0508d0dca8bb98c7f7fd3772fc943ac3f53d5ab18a218d32c0/keyring-25.4.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_keyring_sdist_b07ebc55": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "keyring-25.4.1.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "b07ebc55f3e8ed86ac81dd31ef14e81ace9dd9c3d4b5d77a6e9a2016d0d71a1b", + "urls": [ + "https://files.pythonhosted.org/packages/a5/1c/2bdbcfd5d59dc6274ffb175bc29aa07ecbfab196830e0cfbde7bd861a2ea/keyring-25.4.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "markdown_it_py-3.0.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "urls": [ + "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "markdown-it-py-3.0.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", + "urls": [ + "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_mdurl_py3_none_any_84008a41": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "mdurl-0.1.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "urls": [ + "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_mdurl_sdist_bb413d29": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "mdurl-0.1.2.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", + "urls": [ + "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "more_itertools-10.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", + "urls": [ + "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_sdist_5482bfef": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "more-itertools-10.5.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", + "urls": [ + "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86", + "urls": [ + "https://files.pythonhosted.org/packages/b3/89/1daff5d9ba5a95a157c092c7c5f39b8dd2b1ddb4559966f808d31cfb67e0/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811", + "urls": [ + "https://files.pythonhosted.org/packages/2c/b6/42fc3c69cabf86b6b81e4c051a9b6e249c5ba9f8155590222c2622961f58/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200", + "urls": [ + "https://files.pythonhosted.org/packages/45/b9/833f385403abaf0023c6547389ec7a7acf141ddd9d1f21573723a6eab39a/nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164", + "urls": [ + "https://files.pythonhosted.org/packages/05/2b/85977d9e11713b5747595ee61f381bc820749daf83f07b90b6c9964cf932/nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189", + "urls": [ + "https://files.pythonhosted.org/packages/72/f2/5c894d5265ab80a97c68ca36f25c8f6f0308abac649aaf152b74e7e854a8/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad", + "urls": [ + "https://files.pythonhosted.org/packages/ab/a7/375afcc710dbe2d64cfbd69e31f82f3e423d43737258af01f6a56d844085/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b", + "urls": [ + "https://files.pythonhosted.org/packages/c2/a8/3bb02d0c60a03ad3a112b76c46971e9480efa98a8946677b5a59f60130ca/nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307", + "urls": [ + "https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe", + "urls": [ + "https://files.pythonhosted.org/packages/a3/da/0c4e282bc3cff4a0adf37005fa1fb42257673fbc1bbf7d1ff639ec3d255a/nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a", + "urls": [ + "https://files.pythonhosted.org/packages/de/81/c291231463d21da5f8bba82c8167a6d6893cc5419b0639801ee5d3aeb8a9/nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204", + "urls": [ + "https://files.pythonhosted.org/packages/eb/61/73a007c74c37895fdf66e0edcd881f5eaa17a348ff02f4bb4bc906d61085/nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-win_amd64.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844", + "urls": [ + "https://files.pythonhosted.org/packages/26/8d/53c5b19c4999bdc6ba95f246f4ef35ca83d7d7423e5e38be43ad66544e5d/nh3-0.2.18-cp37-abi3-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_sdist_94a16692": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "nh3-0.2.18.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4", + "urls": [ + "https://files.pythonhosted.org/packages/62/73/10df50b42ddb547a907deeb2f3c9823022580a7a47281e8eae8e003a9639/nh3-0.2.18.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pkginfo-1.10.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097", + "urls": [ + "https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_sdist_5df73835": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pkginfo-1.10.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", + "urls": [ + "https://files.pythonhosted.org/packages/2f/72/347ec5be4adc85c182ed2823d8d1c7b51e13b9a6b0c1aae59582eca652df/pkginfo-1.10.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "pycparser-2.22-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", + "urls": [ + "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pycparser_sdist_491c8be9": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pycparser-2.22.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "urls": [ + "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pygments-2.18.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", + "urls": [ + "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pygments_sdist_786ff802": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pygments-2.18.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "urls": [ + "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "filename": "pywin32_ctypes-0.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", + "urls": [ + "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pywin32-ctypes-0.2.3.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", + "urls": [ + "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "readme_renderer-44.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "urls": [ + "https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_sdist_8712034e": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "readme_renderer-44.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1", + "urls": [ + "https://files.pythonhosted.org/packages/5a/a9/104ec9234c8448c4379768221ea6df01260cd6c2ce13182d4eac531c8342/readme_renderer-44.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_py3_none_any_70761cfe": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests-2.32.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", + "urls": [ + "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_sdist_55365417": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-2.32.3.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "urls": [ + "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests_toolbelt-1.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", + "urls": [ + "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-toolbelt-1.0.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "urls": [ + "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rfc3986-2.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "urls": [ + "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_sdist_97aacf9d": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rfc3986-2.0.0.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", + "urls": [ + "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rich_py3_none_any_6049d5e6": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rich-13.9.4-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.4", + "sha256": "6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", + "urls": [ + "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rich_sdist_43959497": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rich-13.9.4.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.4", + "sha256": "439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", + "urls": [ + "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "SecretStorage-3.3.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", + "urls": [ + "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_sdist_2403533e": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "SecretStorage-3.3.3.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", + "urls": [ + "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_twine_py3_none_any_215dbe7b": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "twine-5.1.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997", + "urls": [ + "https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_twine_sdist_9aa08251": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "twine-5.1.1.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db", + "urls": [ + "https://files.pythonhosted.org/packages/77/68/bd982e5e949ef8334e6f7dcf76ae40922a8750aa2e347291ae1477a4782b/twine-5.1.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "urllib3-2.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "urls": [ + "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_urllib3_sdist_e7d814a8": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "urllib3-2.2.3.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", + "urls": [ + "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_zipp_py3_none_any_a817ac80": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "zipp-3.20.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "urls": [ + "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_zipp_sdist_bc9eb26f": { + "bzlFile": "@@rules_python~//python/private/pypi:whl_library.bzl", + "ruleClassName": "whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "zipp-3.20.2.tar.gz", + "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", + "urls": [ + "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz" + ] + } + }, + "pip_deps": { + "bzlFile": "@@rules_python~//python/private/pypi:hub_repository.bzl", + "ruleClassName": "hub_repository", + "attributes": { + "repo_name": "pip_deps", + "extra_hub_aliases": {}, + "whl_map": { + "numpy": "{\"pip_deps_310_numpy\":[{\"version\":\"3.10\"}],\"pip_deps_311_numpy\":[{\"version\":\"3.11\"}],\"pip_deps_312_numpy\":[{\"version\":\"3.12\"}],\"pip_deps_38_numpy\":[{\"version\":\"3.8\"}],\"pip_deps_39_numpy\":[{\"version\":\"3.9\"}]}", + "setuptools": "{\"pip_deps_310_setuptools\":[{\"version\":\"3.10\"}],\"pip_deps_311_setuptools\":[{\"version\":\"3.11\"}],\"pip_deps_312_setuptools\":[{\"version\":\"3.12\"}],\"pip_deps_38_setuptools\":[{\"version\":\"3.8\"}],\"pip_deps_39_setuptools\":[{\"version\":\"3.9\"}]}" + }, + "packages": [ + "numpy", + "setuptools" + ], + "groups": {} + } + }, + "rules_fuzzing_py_deps": { + "bzlFile": "@@rules_python~//python/private/pypi:hub_repository.bzl", + "ruleClassName": "hub_repository", + "attributes": { + "repo_name": "rules_fuzzing_py_deps", + "extra_hub_aliases": {}, + "whl_map": { + "absl_py": "{\"rules_fuzzing_py_deps_310_absl_py\":[{\"version\":\"3.10\"}],\"rules_fuzzing_py_deps_311_absl_py\":[{\"version\":\"3.11\"}],\"rules_fuzzing_py_deps_312_absl_py\":[{\"version\":\"3.12\"}],\"rules_fuzzing_py_deps_38_absl_py\":[{\"version\":\"3.8\"}],\"rules_fuzzing_py_deps_39_absl_py\":[{\"version\":\"3.9\"}]}", + "six": "{\"rules_fuzzing_py_deps_310_six\":[{\"version\":\"3.10\"}],\"rules_fuzzing_py_deps_311_six\":[{\"version\":\"3.11\"}],\"rules_fuzzing_py_deps_312_six\":[{\"version\":\"3.12\"}],\"rules_fuzzing_py_deps_38_six\":[{\"version\":\"3.8\"}],\"rules_fuzzing_py_deps_39_six\":[{\"version\":\"3.9\"}]}" + }, + "packages": [ + "absl_py", + "six" + ], + "groups": {} + } + }, + "rules_python_publish_deps": { + "bzlFile": "@@rules_python~//python/private/pypi:hub_repository.bzl", + "ruleClassName": "hub_repository", + "attributes": { + "repo_name": "rules_python_publish_deps", + "extra_hub_aliases": {}, + "whl_map": { + "backports_tarfile": "{\"rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7\":[{\"filename\":\"backports.tarfile-1.2.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2\":[{\"filename\":\"backports_tarfile-1.2.0.tar.gz\",\"version\":\"3.11\"}]}", + "certifi": "{\"rules_python_publish_deps_311_certifi_py3_none_any_922820b5\":[{\"filename\":\"certifi-2024.8.30-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_certifi_sdist_bec941d2\":[{\"filename\":\"certifi-2024.8.30.tar.gz\",\"version\":\"3.11\"}]}", + "cffi": "{\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783\":[{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cffi_sdist_1c39c601\":[{\"filename\":\"cffi-1.17.1.tar.gz\",\"version\":\"3.11\"}]}", + "charset_normalizer": "{\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f\":[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe\":[{\"filename\":\"charset_normalizer-3.4.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_charset_normalizer_sdist_223217c3\":[{\"filename\":\"charset_normalizer-3.4.0.tar.gz\",\"version\":\"3.11\"}]}", + "cryptography": "{\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d\":[{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_cryptography_sdist_315b9001\":[{\"filename\":\"cryptography-43.0.3.tar.gz\",\"version\":\"3.11\"}]}", + "docutils": "{\"rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9\":[{\"filename\":\"docutils-0.21.2-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_docutils_sdist_3a6b1873\":[{\"filename\":\"docutils-0.21.2.tar.gz\",\"version\":\"3.11\"}]}", + "idna": "{\"rules_python_publish_deps_311_idna_py3_none_any_946d195a\":[{\"filename\":\"idna-3.10-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_idna_sdist_12f65c9b\":[{\"filename\":\"idna-3.10.tar.gz\",\"version\":\"3.11\"}]}", + "importlib_metadata": "{\"rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197\":[{\"filename\":\"importlib_metadata-8.5.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_importlib_metadata_sdist_71522656\":[{\"filename\":\"importlib_metadata-8.5.0.tar.gz\",\"version\":\"3.11\"}]}", + "jaraco_classes": "{\"rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b\":[{\"filename\":\"jaraco.classes-3.4.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5\":[{\"filename\":\"jaraco.classes-3.4.0.tar.gz\",\"version\":\"3.11\"}]}", + "jaraco_context": "{\"rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48\":[{\"filename\":\"jaraco.context-6.0.1-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5\":[{\"filename\":\"jaraco_context-6.0.1.tar.gz\",\"version\":\"3.11\"}]}", + "jaraco_functools": "{\"rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13\":[{\"filename\":\"jaraco.functools-4.1.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2\":[{\"filename\":\"jaraco_functools-4.1.0.tar.gz\",\"version\":\"3.11\"}]}", + "jeepney": "{\"rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad\":[{\"filename\":\"jeepney-0.8.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_jeepney_sdist_5efe48d2\":[{\"filename\":\"jeepney-0.8.0.tar.gz\",\"version\":\"3.11\"}]}", + "keyring": "{\"rules_python_publish_deps_311_keyring_py3_none_any_5426f817\":[{\"filename\":\"keyring-25.4.1-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_keyring_sdist_b07ebc55\":[{\"filename\":\"keyring-25.4.1.tar.gz\",\"version\":\"3.11\"}]}", + "markdown_it_py": "{\"rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684\":[{\"filename\":\"markdown_it_py-3.0.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94\":[{\"filename\":\"markdown-it-py-3.0.0.tar.gz\",\"version\":\"3.11\"}]}", + "mdurl": "{\"rules_python_publish_deps_311_mdurl_py3_none_any_84008a41\":[{\"filename\":\"mdurl-0.1.2-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_mdurl_sdist_bb413d29\":[{\"filename\":\"mdurl-0.1.2.tar.gz\",\"version\":\"3.11\"}]}", + "more_itertools": "{\"rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32\":[{\"filename\":\"more_itertools-10.5.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_more_itertools_sdist_5482bfef\":[{\"filename\":\"more-itertools-10.5.0.tar.gz\",\"version\":\"3.11\"}]}", + "nh3": "{\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819\":[{\"filename\":\"nh3-0.2.18-cp37-abi3-win_amd64.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_nh3_sdist_94a16692\":[{\"filename\":\"nh3-0.2.18.tar.gz\",\"version\":\"3.11\"}]}", + "pkginfo": "{\"rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2\":[{\"filename\":\"pkginfo-1.10.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_pkginfo_sdist_5df73835\":[{\"filename\":\"pkginfo-1.10.0.tar.gz\",\"version\":\"3.11\"}]}", + "pycparser": "{\"rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d\":[{\"filename\":\"pycparser-2.22-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_pycparser_sdist_491c8be9\":[{\"filename\":\"pycparser-2.22.tar.gz\",\"version\":\"3.11\"}]}", + "pygments": "{\"rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0\":[{\"filename\":\"pygments-2.18.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_pygments_sdist_786ff802\":[{\"filename\":\"pygments-2.18.0.tar.gz\",\"version\":\"3.11\"}]}", + "pywin32_ctypes": "{\"rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337\":[{\"filename\":\"pywin32_ctypes-0.2.3-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04\":[{\"filename\":\"pywin32-ctypes-0.2.3.tar.gz\",\"version\":\"3.11\"}]}", + "readme_renderer": "{\"rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b\":[{\"filename\":\"readme_renderer-44.0-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_readme_renderer_sdist_8712034e\":[{\"filename\":\"readme_renderer-44.0.tar.gz\",\"version\":\"3.11\"}]}", + "requests": "{\"rules_python_publish_deps_311_requests_py3_none_any_70761cfe\":[{\"filename\":\"requests-2.32.3-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_requests_sdist_55365417\":[{\"filename\":\"requests-2.32.3.tar.gz\",\"version\":\"3.11\"}]}", + "requests_toolbelt": "{\"rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66\":[{\"filename\":\"requests_toolbelt-1.0.0-py2.py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3\":[{\"filename\":\"requests-toolbelt-1.0.0.tar.gz\",\"version\":\"3.11\"}]}", + "rfc3986": "{\"rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b\":[{\"filename\":\"rfc3986-2.0.0-py2.py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_rfc3986_sdist_97aacf9d\":[{\"filename\":\"rfc3986-2.0.0.tar.gz\",\"version\":\"3.11\"}]}", + "rich": "{\"rules_python_publish_deps_311_rich_py3_none_any_6049d5e6\":[{\"filename\":\"rich-13.9.4-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_rich_sdist_43959497\":[{\"filename\":\"rich-13.9.4.tar.gz\",\"version\":\"3.11\"}]}", + "secretstorage": "{\"rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662\":[{\"filename\":\"SecretStorage-3.3.3-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_secretstorage_sdist_2403533e\":[{\"filename\":\"SecretStorage-3.3.3.tar.gz\",\"version\":\"3.11\"}]}", + "twine": "{\"rules_python_publish_deps_311_twine_py3_none_any_215dbe7b\":[{\"filename\":\"twine-5.1.1-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_twine_sdist_9aa08251\":[{\"filename\":\"twine-5.1.1.tar.gz\",\"version\":\"3.11\"}]}", + "urllib3": "{\"rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0\":[{\"filename\":\"urllib3-2.2.3-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_urllib3_sdist_e7d814a8\":[{\"filename\":\"urllib3-2.2.3.tar.gz\",\"version\":\"3.11\"}]}", + "zipp": "{\"rules_python_publish_deps_311_zipp_py3_none_any_a817ac80\":[{\"filename\":\"zipp-3.20.2-py3-none-any.whl\",\"version\":\"3.11\"}],\"rules_python_publish_deps_311_zipp_sdist_bc9eb26f\":[{\"filename\":\"zipp-3.20.2.tar.gz\",\"version\":\"3.11\"}]}" + }, + "packages": [ + "backports_tarfile", + "certifi", + "charset_normalizer", + "docutils", + "idna", + "importlib_metadata", + "jaraco_classes", + "jaraco_context", + "jaraco_functools", + "keyring", + "markdown_it_py", + "mdurl", + "more_itertools", + "nh3", + "pkginfo", + "pygments", + "readme_renderer", + "requests", + "requests_toolbelt", + "rfc3986", + "rich", + "twine", + "urllib3", + "zipp" + ], + "groups": {} + } + } + }, + "moduleExtensionMetadata": { + "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_python~", + "bazel_features", + "bazel_features~" + ], + [ + "rules_python~", + "bazel_skylib", + "bazel_skylib~" + ], + [ + "rules_python~", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python~", + "pypi__build", + "rules_python~~internal_deps~pypi__build" + ], + [ + "rules_python~", + "pypi__click", + "rules_python~~internal_deps~pypi__click" + ], + [ + "rules_python~", + "pypi__colorama", + "rules_python~~internal_deps~pypi__colorama" + ], + [ + "rules_python~", + "pypi__importlib_metadata", + "rules_python~~internal_deps~pypi__importlib_metadata" + ], + [ + "rules_python~", + "pypi__installer", + "rules_python~~internal_deps~pypi__installer" + ], + [ + "rules_python~", + "pypi__more_itertools", + "rules_python~~internal_deps~pypi__more_itertools" + ], + [ + "rules_python~", + "pypi__packaging", + "rules_python~~internal_deps~pypi__packaging" + ], + [ + "rules_python~", + "pypi__pep517", + "rules_python~~internal_deps~pypi__pep517" + ], + [ + "rules_python~", + "pypi__pip", + "rules_python~~internal_deps~pypi__pip" + ], + [ + "rules_python~", + "pypi__pip_tools", + "rules_python~~internal_deps~pypi__pip_tools" + ], + [ + "rules_python~", + "pypi__pyproject_hooks", + "rules_python~~internal_deps~pypi__pyproject_hooks" + ], + [ + "rules_python~", + "pypi__setuptools", + "rules_python~~internal_deps~pypi__setuptools" + ], + [ + "rules_python~", + "pypi__tomli", + "rules_python~~internal_deps~pypi__tomli" + ], + [ + "rules_python~", + "pypi__wheel", + "rules_python~~internal_deps~pypi__wheel" + ], + [ + "rules_python~", + "pypi__zipp", + "rules_python~~internal_deps~pypi__zipp" + ], + [ + "rules_python~", + "pythons_hub", + "rules_python~~python~pythons_hub" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_10_host", + "rules_python~~python~python_3_10_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_11_host", + "rules_python~~python~python_3_11_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_host", + "rules_python~~python~python_3_12_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_8_host", + "rules_python~~python~python_3_8_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_9_host", + "rules_python~~python~python_3_9_host" + ] + ] + } + } + } +} diff --git a/Makefile b/Makefile index 8c602ef33..5fbaaa059 100644 --- a/Makefile +++ b/Makefile @@ -224,7 +224,7 @@ $(RELEASE_FILE): bins dist: $(RELEASE_FILE) clean: - rm -vf */*~ *~ .*~ */.*.swp .*.swp $(ALL) *.o core/*.jsonnet.h Makefile.depend *.so.* $(RELEASE_FILE) + rm -rvf */*~ *~ .*~ */.*.swp .*.swp $(ALL) *.o core/*.jsonnet.h Makefile.depend *.so.* build jsonnet.egg-info $(RELEASE_FILE) -include Makefile.depend diff --git a/README.md b/README.md index 1740fd0a4..00a898ede 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,12 @@ For an introduction to Jsonnet and documentation, [visit our website](https://jsonnet.org). -This repository contains the original implementation. You can also try [go-jsonnet](https://github.com/google/go-jsonnet), a newer implementation which in some cases is orders of magnitude faster. +This repository contains the original implementation. You can also try [go-jsonnet](https://github.com/google/go-jsonnet), a newer implementation which in some cases is orders of magnitude faster, and is recommended in preference to the C++ version. Visit our [discussion forum](https://groups.google.com/g/jsonnet). +**Security note:** If you need to process *untrusted inputs* (untrusted Jsonnet code), it is best not to use the C++ implementation, as it is not hardened for that use-case. The expected use-case is for evaluating Jsonnet code that you / your organisation has written and trusts not to be malicious. + ## Packages Jsonnet is available on Homebrew: diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index 97dfb640e..000000000 --- a/WORKSPACE +++ /dev/null @@ -1,26 +0,0 @@ -workspace(name = "jsonnet") - -load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") - -git_repository( - name = "io_bazel_rules_jsonnet", - commit = "ad2b4204157ddcf7919e8bd210f607f8a801aa7f", - remote = "https://github.com/bazelbuild/rules_jsonnet.git", - shallow_since = "1556260764 +0200", -) - -git_repository( - name = "com_google_googletest", - remote = "https://github.com/google/googletest.git", - # If updating googletest version, also update CMakeLists.txt.in. - commit = "2fe3bd994b3189899d93f1d5a881e725e046fdc2", # release: release-1.8.1 - shallow_since = "1535728917 -0400", -) - -# This allows using py_test and py_library against python3. -register_toolchains("//platform_defs:default_python3_toolchain") - -# This allows building C++ against python3 headers. -load("//tools/build_defs:python_repo.bzl", "python_headers") -python_headers(name = "default_python3_headers") - diff --git a/cmd/BUILD b/cmd/BUILD index 41d3c23c0..51803a4b6 100644 --- a/cmd/BUILD +++ b/cmd/BUILD @@ -1,4 +1,4 @@ -package(default_visibility = ["//visibility:public"]) +package(default_visibility = ["//visibility:private"]) cc_library( name = "utils", @@ -10,6 +10,7 @@ cc_library( cc_binary( name = "jsonnet", srcs = ["jsonnet.cpp"], + visibility = ["//visibility:public"], deps = [ ":utils", "//core:libjsonnet", @@ -19,6 +20,7 @@ cc_binary( cc_binary( name = "jsonnetfmt", srcs = ["jsonnetfmt.cpp"], + visibility = ["//visibility:public"], deps = [ ":utils", "//core:libjsonnet", diff --git a/core/BUILD b/core/BUILD index 62b4459f5..55084889a 100644 --- a/core/BUILD +++ b/core/BUILD @@ -1,45 +1,46 @@ -package(default_visibility = ["//visibility:public"]) +package(default_visibility = ["//visibility:private"]) cc_library( name = "libjsonnet", srcs = [ - "desugarer.cpp", - "formatter.cpp", - "lexer.cpp", - "libjsonnet.cpp", - "parser.cpp", - "pass.cpp", - "path_utils.cpp", - "static_analysis.cpp", - "string_utils.cpp", - "vm.cpp", - ], - hdrs = [ "ast.h", + "desugarer.cpp", "desugarer.h", + "formatter.cpp", "formatter.h", "json.h", + "lexer.cpp", "lexer.h", + "libjsonnet.cpp", + "parser.cpp", "parser.h", + "pass.cpp", "pass.h", + "path_utils.cpp", "path_utils.h", "state.h", + "static_analysis.cpp", "static_analysis.h", "static_error.h", + "string_utils.cpp", "string_utils.h", "unicode.h", + "vm.cpp", "vm.h", ], - includes = ["."], - linkopts = ["-lm"], - deps = [ - "//include:libjsonnet", - "//include:libjsonnet_fmt", + copts = ["-I."], + implementation_deps = [ "//stdlib:std", "//third_party/json", "//third_party/md5:libmd5", "//third_party/rapidyaml:ryml", ], + linkopts = ["-lm"], + visibility = ["//visibility:public"], + deps = [ + "//include:libjsonnet", + "//include:libjsonnet_fmt", + ], ) cc_test( @@ -48,7 +49,7 @@ cc_test( deps = [ ":libjsonnet", # Note: On Ubuntu, apt-get install libgtest-dev google-mock - "@com_google_googletest//:gtest_main", + "@googletest//:gtest_main", ], ) @@ -57,7 +58,7 @@ cc_test( srcs = ["parser_test.cpp"], deps = [ ":libjsonnet", - "@com_google_googletest//:gtest_main", + "@googletest//:gtest_main", ], ) @@ -66,6 +67,15 @@ cc_test( srcs = ["libjsonnet_test.cpp"], deps = [ ":libjsonnet", - "@com_google_googletest//:gtest_main", + "@googletest//:gtest_main", + ], +) + +cc_test( + name = "unicode_test", + srcs = ["unicode_test.cpp"], + deps = [ + ":libjsonnet", + "@googletest//:gtest_main", ], ) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 048addb24..726ce25f4 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -34,6 +34,8 @@ add_library(libjsonnet SHARED ${LIBJSONNET_HEADERS} ${LIBJSONNET_SOURCE}) add_dependencies(libjsonnet md5 stdlib) target_link_libraries(libjsonnet md5 nlohmann_json::nlohmann_json ryml) +# Version extraction logic duplicated in ../cpp/CMakeLists.txt +# TODO: Put this logic somewhere else. file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/../include/libjsonnet.h JSONNET_VERSION_DEF REGEX "[#]define[ \t]+LIB_JSONNET_VERSION[ \t]+") string(REGEX REPLACE ".*\"v([^\"]+)\".*" "\\1" JSONNET_VERSION ${JSONNET_VERSION_DEF}) @@ -87,6 +89,9 @@ function(add_test_executable test_name) endfunction() if (BUILD_TESTS) + add_test_executable(unicode_test) + add_test(unicode_test ${GLOBAL_OUTPUT_PATH}/unicode_test) + add_test_executable(lexer_test) add_test(lexer_test ${GLOBAL_OUTPUT_PATH}/lexer_test) diff --git a/core/desugarer.cpp b/core/desugarer.cpp index 5fd9acfd5..3ed2b453e 100644 --- a/core/desugarer.cpp +++ b/core/desugarer.cpp @@ -36,7 +36,7 @@ struct BuiltinDecl { std::vector params; }; -static unsigned long max_builtin = 38; +static unsigned long max_builtin = 40; BuiltinDecl jsonnet_builtin_decl(unsigned long builtin) { switch (builtin) { @@ -79,6 +79,8 @@ BuiltinDecl jsonnet_builtin_decl(unsigned long builtin) case 36: return {U"parseYaml", {U"str"}}; case 37: return {U"encodeUTF8", {U"str"}}; case 38: return {U"decodeUTF8", {U"arr"}}; + case 39: return {U"atan2", {U"y", U"x"}}; + case 40: return {U"hypot", {U"a", U"b"}}; default: std::cerr << "INTERNAL ERROR: Unrecognized builtin function: " << builtin << std::endl; std::abort(); @@ -100,6 +102,7 @@ static constexpr char STD_CODE[] = { */ class Desugarer { Allocator *alloc; + bool isStdlib; template T *make(Args &&... args) @@ -139,7 +142,10 @@ class Desugarer { Var *std(void) { - return var(id(U"std")); + // In most places, there is a "$std" variable inserted by + // the desugarer. On the standard library itself there isn't, + // so use "std" instead. + return var(id(isStdlib ? U"std" : U"$std")); } Local::Bind bind(const Identifier *id, AST *body) @@ -219,7 +225,7 @@ class Desugarer { } public: - Desugarer(Allocator *alloc) : alloc(alloc) {} + Desugarer(Allocator *alloc, bool isStdlib = false) : alloc(alloc), isStdlib(isStdlib) {} void desugarParams(ArgParams ¶ms, unsigned obj_level) { @@ -728,7 +734,7 @@ class Desugarer { } break; case BOP_MANIFEST_UNEQUAL: invert = true; - /* fallthrough */ + [[fallthrough]]; case BOP_MANIFEST_EQUAL: { ast_ = equals(ast->location, ast->left, ast->right); if (invert) @@ -999,13 +1005,17 @@ class Desugarer { make(E, line_end, body))); } - // local std = (std.jsonnet stuff); ast - ast = make(ast->location, EF, singleBind(id(U"std"), std_obj), ast); + // local $std = (std.jsonnet stuff); std = $std; ast + // The standard library is bound to $std, which cannot be overriden, + // so redefining std won't break expressions that desugar to calls + // to standard library functions. + ast = make(ast->location, EF, singleBind(id(U"std"), std()), ast); + ast = make(ast->location, EF, singleBind(id(U"$std"), std_obj), ast); } }; DesugaredObject *makeStdlibAST(Allocator *alloc, std::string filename) { - Desugarer desugarer(alloc); + Desugarer desugarer(alloc, true); return desugarer.stdlibAST(filename); } diff --git a/core/formatter.cpp b/core/formatter.cpp index cad3369c1..ac6d4b1e3 100644 --- a/core/formatter.cpp +++ b/core/formatter.cpp @@ -500,7 +500,11 @@ class Unparser { o << encode_utf8(ast->value); o << "'"; } else if (ast->tokenKind == LiteralString::BLOCK) { - o << "|||\n"; + o << "|||"; + if (ast->value.back() != U'\n') { + o << "-"; + } + o << "\n"; if (ast->value.c_str()[0] != U'\n') o << ast->blockIndent; for (const char32_t *cp = ast->value.c_str(); *cp != U'\0'; ++cp) { @@ -513,6 +517,9 @@ class Unparser { o << ast->blockIndent; } } + if (ast->value.back() != U'\n') { + o << "\n"; + } o << ast->blockTermIndent << "|||"; } else if (ast->tokenKind == LiteralString::VERBATIM_DOUBLE) { o << "@\""; diff --git a/core/lexer.cpp b/core/lexer.cpp index 31599f4d7..10319875c 100644 --- a/core/lexer.cpp +++ b/core/lexer.cpp @@ -704,6 +704,13 @@ Tokens jsonnet_lex(const std::string &filename, const char *input) // Text block if (*c == '|' && *(c + 1) == '|' && *(c + 2) == '|') { c += 3; // Skip the "|||". + + bool chomp_trailing_nl = false; + if (*c == '-') { + chomp_trailing_nl = true; + c++; + } + while (is_horz_ws(*c)) ++c; // Chomp whitespace at end of line. if (*c != '\n') { auto msg = "text block syntax requires new line after |||."; @@ -762,6 +769,10 @@ Tokens jsonnet_lex(const std::string &filename, const char *input) c += 3; // Leave after the last | data = block.str(); kind = Token::STRING_BLOCK; + if (chomp_trailing_nl) { + assert(data.back() == '\n'); + data.pop_back(); + } break; // Out of the while loop. } } diff --git a/core/parser.cpp b/core/parser.cpp index 8a9316aea..7b895f214 100644 --- a/core/parser.cpp +++ b/core/parser.cpp @@ -56,6 +56,12 @@ namespace { static const Fodder EMPTY_FODDER; +/** Maximum parsing depth to avoid stack overflow due to pathological or malicious code. + * This is especially important when parsing deeply nested structures that could lead to + * excessive recursion in the parser functions. + */ +static const unsigned MAX_PARSER_DEPTH = 1000; + static bool op_is_unary(const std::string &op, UnaryOp &uop) { auto it = unary_map.find(op); @@ -151,12 +157,13 @@ class Parser { /** Parse a comma-separated list of expressions. * * Allows an optional ending comma. - * \param exprs Expressions added here. - * \param end The token that ends the list (e.g. ] or )). + * \param args Expressions added here. * \param element_kind Used in error messages when a comma was not found. + * \param got_comma Whether a trailing comma was found. + * \param current_depth Current recursion depth to prevent stack overflow. * \returns The last token (the one that matched parameter end). */ - Token parseArgs(ArgParams &args, const std::string &element_kind, bool &got_comma) + Token parseArgs(ArgParams &args, const std::string &element_kind, bool &got_comma, unsigned current_depth) { got_comma = false; bool first = true; @@ -186,7 +193,7 @@ class Parser { pop(); // eq } } - AST *expr = parse(MAX_PRECEDENCE); + AST *expr = parse(MAX_PRECEDENCE, current_depth + 1); got_comma = false; first = false; Fodder comma_fodder; @@ -199,10 +206,18 @@ class Parser { } while (true); } - ArgParams parseParams(const std::string &element_kind, bool &got_comma, Fodder &close_fodder) + /** Parse function parameters. + * + * \param element_kind Used in error messages. + * \param got_comma Whether a trailing comma was found. + * \param close_fodder Fodder after the closing parenthesis. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The parameters as ArgParams. + */ + ArgParams parseParams(const std::string &element_kind, bool &got_comma, Fodder &close_fodder, unsigned current_depth) { ArgParams params; - Token paren_r = parseArgs(params, element_kind, got_comma); + Token paren_r = parseArgs(params, element_kind, got_comma, current_depth); // Check they're all identifiers // parseArgs returns f(x) with x as an expression. Convert it here. @@ -223,7 +238,13 @@ class Parser { return params; } - Token parseBind(Local::Binds &binds) + /** Parse a local bind statement. + * + * \param binds The bindings to be populated. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The token after the binding (comma or semicolon). + */ + Token parseBind(Local::Binds &binds, unsigned current_depth) { Token var_id = popExpect(Token::IDENTIFIER); auto *id = alloc->makeIdentifier(var_id.data32()); @@ -238,11 +259,11 @@ class Parser { if (peek().kind == Token::PAREN_L) { Token paren_l = pop(); fodder_l = paren_l.fodder; - params = parseParams("function parameter", trailing_comma, fodder_r); + params = parseParams("function parameter", trailing_comma, fodder_r, current_depth); is_function = true; } Token eq = popExpect(Token::OPERATOR, "="); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); Token delim = pop(); binds.emplace_back(var_id.fodder, id, @@ -257,8 +278,19 @@ class Parser { return delim; } - Token parseObjectRemainder(AST *&obj, const Token &tok) + /** Parse the remainder of an object after the opening brace. + * + * \param obj The object AST to be populated. + * \param tok The opening brace token. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The closing brace token. + */ + Token parseObjectRemainder(AST *&obj, const Token &tok, unsigned current_depth) { + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + ObjectFields fields; std::set literal_fields; // For duplicate fields detection. std::set binds; // For duplicate locals detection. @@ -309,7 +341,7 @@ class Parser { } std::vector specs; - Token last = parseComprehensionSpecs(Token::BRACE_R, next.fodder, specs); + Token last = parseComprehensionSpecs(Token::BRACE_R, next.fodder, specs, current_depth + 1); obj = alloc->make( span(tok, last), tok.fodder, fields, got_comma, specs, last.fodder); @@ -383,7 +415,7 @@ class Parser { } else { kind = ObjectField::FIELD_EXPR; fodder1 = next.fodder; - expr1 = parse(MAX_PRECEDENCE); + expr1 = parse(MAX_PRECEDENCE, current_depth + 1); Token bracket_r = popExpect(Token::BRACKET_R); fodder2 = bracket_r.fodder; } @@ -396,7 +428,7 @@ class Parser { if (peek().kind == Token::PAREN_L) { Token paren_l = pop(); fodder_l = paren_l.fodder; - params = parseParams("method parameter", meth_comma, fodder_r); + params = parseParams("method parameter", meth_comma, fodder_r, current_depth); is_method = true; } @@ -442,7 +474,7 @@ class Parser { } } - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); Fodder comma_fodder; next = pop(); @@ -487,10 +519,10 @@ class Parser { Token paren_l = pop(); paren_l_fodder = paren_l.fodder; is_method = true; - params = parseParams("function parameter", func_comma, paren_r_fodder); + params = parseParams("function parameter", func_comma, paren_r_fodder, current_depth); } Token eq = popExpect(Token::OPERATOR, "="); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); binds.insert(id); Fodder comma_fodder; @@ -516,13 +548,13 @@ class Parser { case Token::ASSERT: { Fodder assert_fodder = next.fodder; - AST *cond = parse(MAX_PRECEDENCE); + AST *cond = parse(MAX_PRECEDENCE, current_depth + 1); AST *msg = nullptr; Fodder colon_fodder; if (peek().kind == Token::OPERATOR && peek().data == ":") { Token colon = pop(); colon_fodder = colon.fodder; - msg = parse(MAX_PRECEDENCE); + msg = parse(MAX_PRECEDENCE, current_depth + 1); } Fodder comma_fodder; @@ -542,22 +574,34 @@ class Parser { } while (true); } - /** parses for x in expr for y in expr if expr for z in expr ... */ + /** Parses for x in expr for y in expr if expr for z in expr ... + * + * \param end The token that ends the comprehension (e.g. ] or }). + * \param for_fodder Fodder before the first 'for'. + * \param specs The comprehension specs to be populated. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The closing token. + */ Token parseComprehensionSpecs(Token::Kind end, Fodder for_fodder, - std::vector &specs) + std::vector &specs, + unsigned current_depth) { + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + while (true) { LocationRange l; Token id_token = popExpect(Token::IDENTIFIER); const Identifier *id = alloc->makeIdentifier(id_token.data32()); Token in_token = popExpect(Token::IN); - AST *arr = parse(MAX_PRECEDENCE); + AST *arr = parse(MAX_PRECEDENCE, current_depth + 1); specs.emplace_back( ComprehensionSpec::FOR, for_fodder, id_token.fodder, id, in_token.fodder, arr); Token maybe_if = pop(); for (; maybe_if.kind == Token::IF; maybe_if = pop()) { - AST *cond = parse(MAX_PRECEDENCE); + AST *cond = parse(MAX_PRECEDENCE, current_depth + 1); specs.emplace_back( ComprehensionSpec::IF, maybe_if.fodder, Fodder{}, nullptr, Fodder{}, cond); } @@ -573,8 +617,18 @@ class Parser { } } - AST *parseTerminalBracketsOrUnary(void) + /** Parse a terminal (literal, var, import, etc.), an object declaration, unary operator, + * or a parenthesized expression. + * + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The parsed AST. + */ + AST *parseTerminalBracketsOrUnary(unsigned current_depth) { + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + Token tok = pop(); switch (tok.kind) { case Token::ASSERT: @@ -606,12 +660,12 @@ class Parser { ss << "not a unary operator: " << tok.data; throw StaticError(tok.location, ss.str()); } - AST *expr = parse(UNARY_PRECEDENCE); + AST *expr = parse(UNARY_PRECEDENCE, current_depth + 1); return alloc->make(span(tok, expr), tok.fodder, uop, expr); } case Token::BRACE_L: { AST *obj; - parseObjectRemainder(obj, tok); + parseObjectRemainder(obj, tok, current_depth + 1); return obj; } @@ -622,7 +676,7 @@ class Parser { return alloc->make( span(tok, next), tok.fodder, Array::Elements{}, false, bracket_r.fodder); } - AST *first = parse(MAX_PRECEDENCE); + AST *first = parse(MAX_PRECEDENCE, current_depth + 1); bool got_comma = false; Fodder comma_fodder; next = peek(); @@ -637,7 +691,7 @@ class Parser { // It's a comprehension Token for_token = pop(); std::vector specs; - Token last = parseComprehensionSpecs(Token::BRACKET_R, for_token.fodder, specs); + Token last = parseComprehensionSpecs(Token::BRACKET_R, for_token.fodder, specs, current_depth + 1); return alloc->make(span(tok, last), tok.fodder, first, @@ -661,7 +715,7 @@ class Parser { ss << "expected a comma before next array element."; throw StaticError(next.location, ss.str()); } - AST *expr = parse(MAX_PRECEDENCE); + AST *expr = parse(MAX_PRECEDENCE, current_depth + 1); comma_fodder.clear(); got_comma = false; next = peek(); @@ -676,7 +730,7 @@ class Parser { } case Token::PAREN_L: { - auto *inner = parse(MAX_PRECEDENCE); + auto *inner = parse(MAX_PRECEDENCE, current_depth + 1); Token close = popExpect(Token::PAREN_R); return alloc->make(span(tok, close), tok.fodder, inner, close.fodder); } @@ -730,7 +784,7 @@ class Parser { id = alloc->makeIdentifier(field_id.data32()); } break; case Token::BRACKET_L: { - index = parse(MAX_PRECEDENCE); + index = parse(MAX_PRECEDENCE, current_depth + 1); Token bracket_r = popExpect(Token::BRACKET_R); id_fodder = bracket_r.fodder; // Not id_fodder, but use the same var. } break; @@ -746,11 +800,19 @@ class Parser { return nullptr; // Quiet, compiler. } - // If the first token makes it clear that we will parsing a greedy construct, then return the - // AST. Otherwise, return nullptr. Greedy constructs are those that consume as many tokens - // as possible on the right hand side, because they have no closing token. - AST *maybeParseGreedy(void) + /** If the first token makes it clear that we will be parsing a greedy construct, return the AST. + * Otherwise, return nullptr. Greedy constructs are those that consume as many tokens as possible + * on the right hand side because they have no closing token. + * + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The parsed AST or nullptr. + */ + AST *maybeParseGreedy(unsigned current_depth) { + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + // Allocate this on the heap to control stack growth. std::unique_ptr begin_(new Token(peek())); const Token &begin = *begin_; @@ -760,16 +822,16 @@ class Parser { // call to parse will parse them. case Token::ASSERT: { pop(); - AST *cond = parse(MAX_PRECEDENCE); + AST *cond = parse(MAX_PRECEDENCE, current_depth + 1); Fodder colonFodder; AST *msg = nullptr; if (peek().kind == Token::OPERATOR && peek().data == ":") { Token colon = pop(); colonFodder = colon.fodder; - msg = parse(MAX_PRECEDENCE); + msg = parse(MAX_PRECEDENCE, current_depth + 1); } Token semicolon = popExpect(Token::SEMICOLON); - AST *rest = parse(MAX_PRECEDENCE); + AST *rest = parse(MAX_PRECEDENCE, current_depth + 1); return alloc->make(span(begin, rest), begin.fodder, cond, @@ -781,18 +843,18 @@ class Parser { case Token::ERROR: { pop(); - AST *expr = parse(MAX_PRECEDENCE); + AST *expr = parse(MAX_PRECEDENCE, current_depth + 1); return alloc->make(span(begin, expr), begin.fodder, expr); } case Token::IF: { pop(); - AST *cond = parse(MAX_PRECEDENCE); + AST *cond = parse(MAX_PRECEDENCE, current_depth + 1); Token then = popExpect(Token::THEN); - AST *branch_true = parse(MAX_PRECEDENCE); + AST *branch_true = parse(MAX_PRECEDENCE, current_depth + 1); if (peek().kind == Token::ELSE) { Token else_ = pop(); - AST *branch_false = parse(MAX_PRECEDENCE); + AST *branch_false = parse(MAX_PRECEDENCE, current_depth + 1); return alloc->make(span(begin, branch_false), begin.fodder, cond, @@ -817,8 +879,8 @@ class Parser { std::vector params_asts; bool got_comma; Fodder paren_r_fodder; - ArgParams params = parseParams("function parameter", got_comma, paren_r_fodder); - AST *body = parse(MAX_PRECEDENCE); + ArgParams params = parseParams("function parameter", got_comma, paren_r_fodder, current_depth); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); return alloc->make(span(begin, body), begin.fodder, paren_l.fodder, @@ -835,7 +897,7 @@ class Parser { case Token::IMPORT: { pop(); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); if (body->type == AST_LITERAL_STRING) { auto *lit = static_cast(body); if (lit->tokenKind == LiteralString::BLOCK) { @@ -852,7 +914,7 @@ class Parser { case Token::IMPORTSTR: { pop(); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); if (body->type == AST_LITERAL_STRING) { auto *lit = static_cast(body); if (lit->tokenKind == LiteralString::BLOCK) { @@ -869,7 +931,7 @@ class Parser { case Token::IMPORTBIN: { pop(); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); if (body->type == AST_LITERAL_STRING) { auto *lit = static_cast(body); if (lit->tokenKind == LiteralString::BLOCK) { @@ -888,7 +950,7 @@ class Parser { pop(); Local::Binds binds; do { - Token delim = parseBind(binds); + Token delim = parseBind(binds, current_depth + 1); if (delim.kind != Token::SEMICOLON && delim.kind != Token::COMMA) { std::stringstream ss; ss << "expected , or ; but got " << delim; @@ -897,7 +959,7 @@ class Parser { if (delim.kind == Token::SEMICOLON) break; } while (true); - AST *body = parse(MAX_PRECEDENCE); + AST *body = parse(MAX_PRECEDENCE, current_depth + 1); return alloc->make(span(begin, body), begin.fodder, binds, body); } @@ -906,12 +968,21 @@ class Parser { } } - // Parse a general expression. - // - // Consume infix tokens up to (but not including) max_precedence, then stop. - AST *parse(unsigned max_precedence) + + /** Parse a general expression. + * + * Consume infix tokens up to (but not including) max_precedence, then stop. + * \param max_precedence The maximum precedence to consider. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The parsed AST. + */ + AST *parse(unsigned max_precedence, unsigned current_depth) { - AST *ast = maybeParseGreedy(); + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + + AST *ast = maybeParseGreedy(current_depth + 1); // There cannot be an operator after a greedy parse. if (ast != nullptr) return ast; @@ -921,13 +992,25 @@ class Parser { std::unique_ptr begin_(new Token(peek())); const Token &begin = *begin_; - AST *lhs = parseTerminalBracketsOrUnary(); + AST *lhs = parseTerminalBracketsOrUnary(current_depth + 1); - return parseInfix(lhs, begin, max_precedence); + return parseInfix(lhs, begin, max_precedence, current_depth + 1); } - AST *parseInfix(AST *lhs, const Token &begin, unsigned max_precedence) + /** Parse infix operators (binary operators, indexing, function calls). + * + * \param lhs Left-hand side of the operator. + * \param begin The token representing the beginning of the expression. + * \param max_precedence The maximum precedence to consider. + * \param current_depth Current recursion depth to prevent stack overflow. + * \returns The parsed AST. + */ + AST *parseInfix(AST *lhs, const Token &begin, unsigned max_precedence, unsigned current_depth) { + if (current_depth >= MAX_PARSER_DEPTH) { + throw StaticError(peek().location, "Exceeded maximum parse depth limit."); + } + while (true) { BinaryOp bop = BOP_PLUS; @@ -982,7 +1065,7 @@ class Parser { throw unexpected(pop(), "parsing index"); if (peek().data != ":" && peek().data != "::") { - first = parse(MAX_PRECEDENCE); + first = parse(MAX_PRECEDENCE, current_depth + 1); } if (peek().kind == Token::OPERATOR && peek().data == "::") { @@ -992,7 +1075,7 @@ class Parser { second_fodder = joined.fodder; if (peek().kind != Token::BRACKET_R) - third = parse(MAX_PRECEDENCE); + third = parse(MAX_PRECEDENCE, current_depth + 1); } else if (peek().kind != Token::BRACKET_R) { is_slice = true; @@ -1003,7 +1086,7 @@ class Parser { second_fodder = delim.fodder; if (peek().data != ":" && peek().kind != Token::BRACKET_R) - second = parse(MAX_PRECEDENCE); + second = parse(MAX_PRECEDENCE, current_depth + 1); if (peek().kind != Token::BRACKET_R) { Token delim = pop(); @@ -1013,7 +1096,7 @@ class Parser { third_fodder = delim.fodder; if (peek().kind != Token::BRACKET_R) - third = parse(MAX_PRECEDENCE); + third = parse(MAX_PRECEDENCE, current_depth + 1); } } else { is_slice = false; @@ -1046,7 +1129,7 @@ class Parser { case Token::PAREN_L: { ArgParams args; bool got_comma; - Token end = parseArgs(args, "function argument", got_comma); + Token end = parseArgs(args, "function argument", got_comma, current_depth); bool got_named = false; for (const auto& arg : args) { if (arg.id != nullptr) { @@ -1077,7 +1160,7 @@ class Parser { } case Token::BRACE_L: { AST *obj; - Token end = parseObjectRemainder(obj, op); + Token end = parseObjectRemainder(obj, op, current_depth + 1); lhs = alloc->make(span(begin, end), EMPTY_FODDER, lhs, obj); break; } @@ -1088,7 +1171,7 @@ class Parser { lhs = alloc->make( span(begin, super), EMPTY_FODDER, lhs, op.fodder, super.fodder); } else { - AST *rhs = parse(op_precedence); + AST *rhs = parse(op_precedence, current_depth + 1); lhs = alloc->make( span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs); } @@ -1096,7 +1179,7 @@ class Parser { } case Token::OPERATOR: { - AST *rhs = parse(op_precedence); + AST *rhs = parse(op_precedence, current_depth + 1); lhs = alloc->make( span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs); break; @@ -1126,7 +1209,8 @@ class Parser { AST *jsonnet_parse(Allocator *alloc, Tokens &tokens) { Parser parser(tokens, alloc); - AST *expr = parser.parse(MAX_PRECEDENCE); + unsigned parse_depth = 0; + AST *expr = parser.parse(MAX_PRECEDENCE, parse_depth); if (tokens.front().kind != Token::END_OF_FILE) { std::stringstream ss; ss << "did not expect: " << tokens.front(); diff --git a/core/unicode.h b/core/unicode.h index 56484cc2d..b28fcd4b7 100644 --- a/core/unicode.h +++ b/core/unicode.h @@ -114,7 +114,7 @@ static inline char32_t decode_utf8(const std::string &str, size_t &i) if ((c3 & 0xC0) != 0x80) { return JSONNET_CODEPOINT_ERROR; } - return ((c0 & 0x7) << 24ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F); + return ((c0 & 0x7) << 18ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F); } else { return JSONNET_CODEPOINT_ERROR; } diff --git a/core/unicode_test.cpp b/core/unicode_test.cpp new file mode 100644 index 000000000..c16bd2b5a --- /dev/null +++ b/core/unicode_test.cpp @@ -0,0 +1,114 @@ +/* +Copyright 2025 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include +#include +#include +#include "unicode.h" +#include "gtest/gtest.h" + +namespace jsonnet::internal { +namespace { + +void testEncodeDecode(char32_t codepoint, const std::string &expect_utf8) { + std::string buffer; + size_t len = encode_utf8(codepoint, buffer); + EXPECT_EQ(len, expect_utf8.size()); + EXPECT_EQ(buffer, expect_utf8); + + size_t at = 0; + char32_t decoded = decode_utf8(expect_utf8, at); + EXPECT_EQ(decoded, codepoint); + EXPECT_EQ(at, expect_utf8.size() - 1); +} + +TEST(Unicode, TestUTF8) +{ + // ASCII encodes as itself. + testEncodeDecode(0x00, std::string("\x00", 1)); + testEncodeDecode(0x41, "A"); + testEncodeDecode(0x7f, "\x7f"); + + testEncodeDecode(0x80, "\xc2\x80"); + testEncodeDecode(0x100, "\xc4\x80"); + testEncodeDecode(0x7ff, "\xdf\xbf"); + + testEncodeDecode(0x800, "\xe0\xa0\x80"); + testEncodeDecode(0x1482, "\xe1\x92\x82"); + testEncodeDecode(0xffff, "\xef\xbf\xbf"); + + testEncodeDecode(0x010000, "\xf0\x90\x80\x80"); + testEncodeDecode(0x01f600, "\xf0\x9f\x98\x80"); // U+1F600 "Grinning Face" + testEncodeDecode(0x0f057e, "\xf3\xb0\x95\xbe"); // U+F057E Private use area character + testEncodeDecode(0x10ffff, "\xf4\x8f\xbf\xbf"); +} + +TEST(Unicode, TestUTF8RejectBad) +{ + const auto test_cases = std::array{ + "\x80", // Continuation byte without leading byte + "\xa0", // Continuation byte without leading byte + "\xbf", // Continuation byte without leading byte + "\xc0", // Leading byte for 2-byte sequence (missing tail) + "\xe0", // Leading byte for 3-byte sequence (missing tail) + "\xf0", // Leading byte for 4-byte sequence (missing tail) + "\xf8\x83\x83\x83", // Invalid leading byte + "\xe0\x80", // Leading byte for 3-byte sequence (missing tail) + "\xf0\x80", // Leading byte for 4-byte sequence (missing tail) + "\xf0\x80\x80", // Leading byte for 4-byte sequence (missing tail) + "\xc0\xcf", // Leading byte for 2-byte sequence (incorrect tail) + "\xe0\xcf", // Leading byte for 3-byte sequence (incorrect tail) + "\xf0\xcf", // Leading byte for 4-byte sequence (incorrect tail) + "\xe0\xcf\x80", // Leading byte for 3-byte sequence (incorrect tail) + "\xf0\xcf\x80", // Leading byte for 4-byte sequence (incorrect tail) + "\xe0\x80\xcf", // Leading byte for 3-byte sequence (incorrect tail) + "\xf0\x80\xcf", // Leading byte for 4-byte sequence (incorrect tail) + "\xf0\x80\x80\xcf", // Leading byte for 4-byte sequence (incorrect tail) + "\xf0\x80\xcf\x80", // Leading byte for 4-byte sequence (incorrect tail) + "\xf0\xcf\x80\x80", // Leading byte for 4-byte sequence (incorrect tail) + }; + for (size_t i = 0; i < test_cases.size(); ++i) { + const auto str = test_cases[i]; + size_t at = 0; + char32_t c = decode_utf8(str, at); + + EXPECT_EQ(c, JSONNET_CODEPOINT_ERROR) << "expect decode to reject. case " << i << std::endl; + } +} + +TEST(Unicode, TestUTF8RoundTripExhaustive) +{ + // Encode every Unicode code-point as UTF-8 and verify that + // it decodes to the same value. + std::string buffer; + for (int x = 0; x < JSONNET_CODEPOINT_MAX; ++x) { + if (x == JSONNET_CODEPOINT_ERROR) { + continue; + } + buffer.clear(); + encode_utf8(x, buffer); + + size_t at = 0; + char32_t y = decode_utf8(buffer, at); + EXPECT_NE(y, JSONNET_CODEPOINT_ERROR) << "UTF-8 roundtrip failed for codepoint " << x << " decode rejects" << std::endl; + EXPECT_EQ(x, y) << "UTF-8 roundtrip failed for codepoint " << x << " converts to " << y << std::endl; + EXPECT_EQ(at, buffer.size() - 1) << "UTF-8 roundtrip failed for codepoint " << x << " decodes incorrect length" << std::endl; + } +} + +} // namespace +} // namespace jsonnet::internal diff --git a/core/vm.cpp b/core/vm.cpp index 0e21c82aa..0d702de41 100644 --- a/core/vm.cpp +++ b/core/vm.cpp @@ -873,6 +873,40 @@ class Interpreter { } } + /** Safely converts a double to an int64_t, with range and validity checks. + * + * This function is used primarily for bitwise operations which require integer operands. + * It performs two safety checks: + * 1. Verifies the value is finite (not NaN or Infinity) + * 2. Ensures the value is within the safe integer range [-2^53, 2^53] + * + * The safe integer range limitation is necessary because IEEE 754 double precision + * floating point numbers can only precisely represent integers in the range [-2^53, 2^53]. + * Beyond this range, precision is lost, which would lead to unpredictable results + * in bitwise operations that depend on exact bit patterns. + * + * \param value The double value to convert + * \param loc The location in source code (for error reporting) + * \throws RuntimeError if value is not finite or outside the safe integer range + * \returns The value converted to int64_t + */ + int64_t safeDoubleToInt64(double value, const internal::LocationRange& loc) { + if (std::isnan(value) || std::isinf(value)) { + throw internal::StaticError(loc, "numeric value is not finite"); + } + + // Constants for safe double-to-int conversion + // Jsonnet uses IEEE 754 doubles, which precisely represent integers in the range [-2^53 + 1, 2^53 - 1]. + constexpr int64_t DOUBLE_MAX_SAFE_INTEGER = (1LL << 53) - 1; + constexpr int64_t DOUBLE_MIN_SAFE_INTEGER = -((1LL << 53) - 1); + + // Check if the value is within the safe integer range + if (value < DOUBLE_MIN_SAFE_INTEGER || value > DOUBLE_MAX_SAFE_INTEGER) { + throw makeError(loc, "numeric value outside safe integer range for bitwise operation."); + } + return static_cast(value); + } + public: /** Create a new interpreter. * @@ -937,6 +971,8 @@ class Interpreter { builtins["parseYaml"] = &Interpreter::builtinParseYaml; builtins["encodeUTF8"] = &Interpreter::builtinEncodeUTF8; builtins["decodeUTF8"] = &Interpreter::builtinDecodeUTF8; + builtins["atan2"] = &Interpreter::builtinAtan2; + builtins["hypot"] = &Interpreter::builtinHypot; DesugaredObject *stdlib = makeStdlibAST(alloc, "__internal__"); jsonnet_static_analysis(stdlib); @@ -1099,6 +1135,20 @@ class Interpreter { return nullptr; } + const AST *builtinAtan2(const LocationRange &loc, const std::vector &args) + { + validateBuiltinArgs(loc, "atan2", args, {Value::NUMBER, Value::NUMBER}); + scratch = makeNumberCheck(loc, std::atan2(args[0].v.d, args[1].v.d)); + return nullptr; + } + + const AST *builtinHypot(const LocationRange &loc, const std::vector &args) + { + validateBuiltinArgs(loc, "hypot", args, {Value::NUMBER, Value::NUMBER}); + scratch = makeNumberCheck(loc, std::hypot(args[0].v.d, args[1].v.d)); + return nullptr; + } + const AST *builtinType(const LocationRange &, const std::vector &args) { switch (args[0].t) { @@ -2390,7 +2440,7 @@ class Interpreter { stack.top().val2 = scratch; stack.top().kind = FRAME_BINARY_OP; } - // Falls through. + [[fallthrough]]; case FRAME_BINARY_OP: { const auto &ast = *static_cast(f.ast); const Value &lhs = stack.top().val; @@ -2543,36 +2593,45 @@ class Interpreter { case BOP_SHIFT_L: { if (rhs.v.d < 0) throw makeError(ast.location, "shift by negative exponent."); - int64_t long_l = lhs.v.d; - int64_t long_r = rhs.v.d; + + int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location); + int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location); long_r = long_r % 64; + + // Additional safety check for left shifts to prevent undefined behavior + if (long_r >= 1 && long_l >= (1LL << (63 - long_r))) { + throw makeError(ast.location, + "numeric value outside safe integer range for bitwise operation."); + } + scratch = makeNumber(long_l << long_r); } break; case BOP_SHIFT_R: { if (rhs.v.d < 0) throw makeError(ast.location, "shift by negative exponent."); - int64_t long_l = lhs.v.d; - int64_t long_r = rhs.v.d; + + int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location); + int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location); long_r = long_r % 64; scratch = makeNumber(long_l >> long_r); } break; case BOP_BITWISE_AND: { - int64_t long_l = lhs.v.d; - int64_t long_r = rhs.v.d; + int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location); + int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location); scratch = makeNumber(long_l & long_r); } break; case BOP_BITWISE_XOR: { - int64_t long_l = lhs.v.d; - int64_t long_r = rhs.v.d; + int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location); + int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location); scratch = makeNumber(long_l ^ long_r); } break; case BOP_BITWISE_OR: { - int64_t long_l = lhs.v.d; - int64_t long_r = rhs.v.d; + int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location); + int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location); scratch = makeNumber(long_l | long_r); } break; diff --git a/core/vm.h b/core/vm.h index 830972eb1..c4207ab96 100644 --- a/core/vm.h +++ b/core/vm.h @@ -18,6 +18,7 @@ limitations under the License. #define JSONNET_VM_H #include +#include #include "ast.h" diff --git a/cpp/BUILD b/cpp/BUILD index 6c8266c41..ca996c3a3 100644 --- a/cpp/BUILD +++ b/cpp/BUILD @@ -1,8 +1,9 @@ -package(default_visibility = ["//visibility:public"]) +package(default_visibility = ["//visibility:private"]) cc_library( name = "libjsonnet++", srcs = ["libjsonnet++.cpp"], + visibility = ["//visibility:public"], deps = [ "//core:libjsonnet", "//include:libjsonnet++", @@ -15,6 +16,6 @@ cc_test( data = ["//cpp/testdata"], deps = [ ":libjsonnet++", - "@com_google_googletest//:gtest_main", + "@googletest//:gtest_main", ], ) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 500f65106..b6faddfbd 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -12,10 +12,17 @@ add_library(libjsonnet++ SHARED ${LIBJSONNETPP_HEADERS} ${LIBJSONNETPP_SOURCE}) add_dependencies(libjsonnet++ jsonnet) target_link_libraries(libjsonnet++ libjsonnet) +# Version extraction logic duplicated from ../core/CMakeLists.txt +# TODO: Put this logic somewhere else. +file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/../include/libjsonnet.h JSONNET_VERSION_DEF + REGEX "[#]define[ \t]+LIB_JSONNET_VERSION[ \t]+") +string(REGEX REPLACE ".*\"v([^\"]+)\".*" "\\1" JSONNET_VERSION ${JSONNET_VERSION_DEF}) +message("Extracted Jsonnet version: " ${JSONNET_VERSION}) + # CMake prepends CMAKE_SHARED_LIBRARY_PREFIX to shared libraries, so without # this step the output would be |liblibjsonnet|. set_target_properties(libjsonnet++ PROPERTIES OUTPUT_NAME jsonnet++ - VERSION "0.20.0" + VERSION "${JSONNET_VERSION}" SOVERSION "0" PUBLIC_HEADER "${LIB_HEADER}") install(TARGETS libjsonnet++ diff --git a/cpp/testdata/BUILD b/cpp/testdata/BUILD index b504c2c20..c019693b1 100644 --- a/cpp/testdata/BUILD +++ b/cpp/testdata/BUILD @@ -1,40 +1,27 @@ -package(default_visibility = ["//visibility:public"]) +load("//tools/build_defs:golden_test.bzl", "jsonnet_json_golden_test") -load( - "@io_bazel_rules_jsonnet//jsonnet:jsonnet.bzl", - "jsonnet_to_json_test", - "jsonnet_library", -) +package(default_visibility = ["//visibility:public"]) -jsonnet_to_json_test( +jsonnet_json_golden_test( name = "example_test", src = "example.jsonnet", golden = "example_golden.json", ) -jsonnet_to_json_test( +jsonnet_json_golden_test( name = "importing_test", src = "importing.jsonnet", + data = ["example.jsonnet"], golden = "importing_golden.json", - imports = ["."], - deps = [":testlib"], ) -jsonnet_to_json_test( +jsonnet_json_golden_test( name = "invalid_test", src = "invalid.jsonnet", - error = 1, + expect_error = True, golden = "invalid.out", ) -jsonnet_library( - name = "testlib", - srcs = [ - "example.jsonnet", - "importing.jsonnet", - ], -) - filegroup( name = "testdata", srcs = [ diff --git a/doc/_layouts/base.html b/doc/_layouts/base.html index efc2a199a..38b4da6bd 100644 --- a/doc/_layouts/base.html +++ b/doc/_layouts/base.html @@ -20,6 +20,7 @@ }); + @@ -134,6 +135,14 @@ + diff --git a/doc/_layouts/stdlib.html b/doc/_layouts/stdlib.html new file mode 100644 index 000000000..b50ed1823 --- /dev/null +++ b/doc/_layouts/stdlib.html @@ -0,0 +1,14 @@ +--- +layout: base +viewport_width: 576 +--- +{{ content }} + + diff --git a/doc/_stdlib_gen/stdlib-content.jsonnet b/doc/_stdlib_gen/stdlib-content.jsonnet index c36e1c5a8..52ac42f12 100644 --- a/doc/_stdlib_gen/stdlib-content.jsonnet +++ b/doc/_stdlib_gen/stdlib-content.jsonnet @@ -1,5 +1,14 @@ local html = import 'html.libsonnet'; +local exampleDocMultiline(mid, ex) = + html.spaceless([ + html.p({}, 'Example:'), + html.pre({}, ex.input), + html.p({}, mid), + html.pre({}, ex.output), + ]) +; + { intro: html.paragraphs([ ||| @@ -98,6 +107,8 @@ local html = import 'html.libsonnet';
    std.pow(x, n)
    std.exp(x)
    std.log(x)
+
    std.log2(x)
+
    std.log10(x)
    std.exponent(x)
    std.mantissa(x)
    std.floor(x)
@@ -109,12 +120,19 @@ local html = import 'html.libsonnet';
    std.asin(x)
    std.acos(x)
    std.atan(x)
+
    std.atan2(y, x)
+
    std.deg2rad(x)
+
    std.rad2deg(x)
+
    std.hypot(a, b)
    std.round(x)
    std.isEven(x)
    std.isOdd(x)
    std.isInteger(x)
    std.isDecimal(x)
+

+ The constant std.pi is also available. +

The function std.mod(a, b) is what the % operator is desugared to. It performs modulo arithmetic if the left hand side is a number, or if the left hand side is a string, @@ -199,11 +217,18 @@ local html = import 'html.libsonnet'; name: 'substr', params: ['str', 'from', 'len'], availableSince: '0.10.0', - description: ||| - Returns a string that is the part of s that starts at offset from - and is len codepoints long. If the string s is shorter than - from+len, the suffix starting at position from will be returned. - |||, + description: html.paragraphs([ + ||| + Returns a string that is the part of str that starts at offset from + and is len codepoints long. If the string str is shorter than + from+len, the suffix starting at position from will be returned. + |||, + ||| + The slice operator (e.g., str[from:to]) can also be used on strings, as an + alternative to this function. However, note that the slice operator takes a start and an + end index, but std.substr takes a start index and a length. + |||, + ]), }, { name: 'findSubstr', @@ -382,7 +407,7 @@ local html = import 'html.libsonnet'; { name: 'trim', params: ['str'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: ||| Returns a copy of string after eliminating leading and trailing whitespaces. |||, @@ -390,7 +415,7 @@ local html = import 'html.libsonnet'; { name: 'equalsIgnoreCase', params: ['str1', 'str2'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: ||| Returns true if the the given str1 is equal to str2 by doing case insensitive comparison, false otherwise. |||, @@ -763,7 +788,7 @@ local html = import 'html.libsonnet'; |||), ], examples: [ - { + exampleDocMultiline('Yields a string containing this JSON:', { input: ||| std.manifestJsonEx( { @@ -787,8 +812,8 @@ local html = import 'html.libsonnet'; y: { a: 1, b: 2, c: [1, 2] }, }, ' ' ), - }, - { + }), + exampleDocMultiline('Yields a string containing this JSON:', { input: ||| std.manifestJsonEx( { @@ -803,7 +828,7 @@ local html = import 'html.libsonnet'; y: { a: 1, b: [1, 2] }, }, '', ' ', ' : ' ), - }, + }), ], }, { @@ -815,7 +840,7 @@ local html = import 'html.libsonnet'; it calls std.manifestJsonEx with a 4-space indent: |||, examples: [ - { + exampleDocMultiline('Yields a string containing this JSON:', { input: ||| std.manifestJson( { @@ -839,7 +864,7 @@ local html = import 'html.libsonnet'; y: { a: 1, b: 2, c: [1, 2] }, } ), - }, + }), ], }, { @@ -851,7 +876,7 @@ local html = import 'html.libsonnet'; it calls std.manifestJsonEx: |||, examples: [ - { + exampleDocMultiline('Yields a string containing this JSON:', { input: ||| std.manifestJsonMinified( { @@ -875,7 +900,7 @@ local html = import 'html.libsonnet'; y: { a: 1, b: 2, c: [1, 2] }, } ), - }, + }), ], }, { @@ -1046,7 +1071,7 @@ local html = import 'html.libsonnet'; one or more whitespaces that are used for indentation: |||, examples: [ - { + exampleDocMultiline('Yields a string containing this TOML file:', { input: ||| std.manifestTomlEx({ key1: "value", @@ -1085,7 +1110,7 @@ local html = import 'html.libsonnet'; ], }, ' ') ), - }, + }), ], }, ], @@ -1209,21 +1234,31 @@ local html = import 'html.libsonnet'; name: 'foldl', params: ['func', 'arr', 'init'], availableSince: '0.10.0', - description: ||| - Classic foldl function. Calls the function on the result of the previous function call and - each array element, or init in the case of the initial element. Traverses the - array from left to right. - |||, + description: html.paragraphs([ + ||| + Classic foldl function. Calls the function for each array element, passing the result from + the previous call (or init for the first call), and the array element. Traverses + the array from left to right. + |||, + ||| + For example: foldl(f, [1,2,3], 0) is equivalent to f(f(f(0, 1), 2), 3). + |||, + ]), }, { name: 'foldr', params: ['func', 'arr', 'init'], availableSince: '0.10.0', - description: ||| - Classic foldr function. Calls the function on the result of the previous function call and - each array element, or init in the case of the initial element. Traverses the - array from right to left. - |||, + description: html.paragraphs([ + ||| + Classic foldr function. Calls the function for each array element, passing the array element + and the result from the previous call (or init for the first call). Traverses + the array from right to left. + |||, + ||| + For example: foldr(f, [1,2,3], 0) is equivalent to f(1, f(2, f(3, 0))). + |||, + ]), }, { name: 'range', @@ -1303,6 +1338,26 @@ local html = import 'html.libsonnet'; }, ], }, + { + name: 'deepJoin', + params: ['arr'], + availableSince: '0.10.0', + description: ||| + Concatenate an array containing strings and arrays to form a single string. If arr is + a string, it is returned unchanged. If it is an array, it is flattened and the string elements are + concatenated together with no separator. + |||, + examples: [ + { + input: 'std.deepJoin(["one ", ["two ", "three ", ["four "], []], "five ", ["six"]])', + output: std.deepJoin(["one ", ["two ", "three ", ["four "], []], "five ", ["six"]]), + }, + { + input: 'std.deepJoin("hello")', + output: std.deepJoin("hello") + }, + ], + }, { name: 'lines', params: ['arr'], @@ -1329,7 +1384,7 @@ local html = import 'html.libsonnet'; { name: 'flattenDeepArray', params: ['value'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: ||| Concatenate an array containing values and arrays into a single flattened array. |||, @@ -1415,27 +1470,35 @@ local html = import 'html.libsonnet'; { name: 'minArray', params: ['arr', 'keyF', 'onEmpty'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: html.paragraphs([ ||| - Return the min of all element in arr. + Return the minimum of all elements in arr. If keyF is provided, it is called on each element + of the array and should return a comparator value, and in this case minArray will return an element + with the minimum comparator value. If onEmpty is provided, and arr is empty, then + minArray will return the provided onEmpty value. If onEmpty is not provided, + then an empty arr will raise an error. |||, ]), }, { name: 'maxArray', params: ['arr', 'keyF', 'onEmpty'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: html.paragraphs([ ||| - Return the max of all element in arr. + Return the maximum of all elements in arr. If keyF is provided, it is called on each element + of the array and should return a comparator value, and in this case maxArray will return an element + with the maximum comparator value. If onEmpty is provided, and arr is empty, then + maxArray will return the provided onEmpty value. If onEmpty is not provided, + then an empty arr will raise an error. |||, ]), }, { name: 'contains', params: ['arr', 'elem'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: html.paragraphs([ ||| Return true if given elem is present in arr, false otherwise. @@ -1455,7 +1518,7 @@ local html = import 'html.libsonnet'; { name: 'remove', params: ['arr', 'elem'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: html.paragraphs([ ||| Remove first occurrence of elem from arr. @@ -1465,7 +1528,7 @@ local html = import 'html.libsonnet'; { name: 'removeAt', params: ['arr', 'idx'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: html.paragraphs([ ||| Remove element at idx index from arr. @@ -1593,7 +1656,7 @@ local html = import 'html.libsonnet'; params: ['o'], availableSince: '0.20.0', description: ||| - Returns an array of objects from the given object, each object having two fields: + Returns an array of objects from the given object, each object having two fields: key (string) and value (object). Does not include hidden fields. |||, }, @@ -1632,7 +1695,7 @@ local html = import 'html.libsonnet'; { name: 'objectRemoveKey', params: ['obj', 'key'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: ||| Returns a new object after removing the given key from object. |||, @@ -1699,7 +1762,7 @@ local html = import 'html.libsonnet'; { name: 'sha1', params: ['s'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: [ html.p({}, ||| Encodes the given value into an SHA1 string. @@ -1712,7 +1775,7 @@ local html = import 'html.libsonnet'; { name: 'sha256', params: ['s'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: [ html.p({}, ||| Encodes the given value into an SHA256 string. @@ -1725,7 +1788,7 @@ local html = import 'html.libsonnet'; { name: 'sha512', params: ['s'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: [ html.p({}, ||| Encodes the given value into an SHA512 string. @@ -1738,7 +1801,7 @@ local html = import 'html.libsonnet'; { name: 'sha3', params: ['s'], - availableSince: 'upcoming', + availableSince: '0.21.0', description: [ html.p({}, ||| Encodes the given value into an SHA3 string. diff --git a/doc/_stdlib_gen/stdlib.jsonnet b/doc/_stdlib_gen/stdlib.jsonnet index 00841cf87..abeba5267 100644 --- a/doc/_stdlib_gen/stdlib.jsonnet +++ b/doc/_stdlib_gen/stdlib.jsonnet @@ -15,7 +15,10 @@ local exampleDoc(ex) = else html.spaceless([html.code({}, ex.input), ' yields ', html.code({}, manifestJsonSingleLine(ex.output))]) ; - html.p({}, html.spaceless(['Example: ', exRep, '.'])) + if std.objectHas(ex, 'type') then + ex + else + html.p({}, html.spaceless(['Example: ', exRep, '.'])) ; local hgroup(body) = html.div({ class: 'hgroup' }, body); @@ -40,7 +43,7 @@ local fieldDescription(f) = local fieldDoc(f, prefix) = [ - in_panel(html.h4({ id: f.name }, prefix + '.' + f.name + fieldParams(f))), + in_panel(html.h4({ id: 'std-' + f.name }, prefix + '.' + f.name + fieldParams(f))), in_panel([ if std.objectHas(f, 'availableSince') then ( html.p( @@ -73,7 +76,7 @@ local group(group_spec, prefix) = ]; local stdlibPage = [ - in_panel(html.h1({id: 'standard_library'}, 'Standard Library')), + in_panel(html.h1({ id: 'standard_library' }, 'Standard Library')), '', in_panel(content.intro), '', @@ -81,7 +84,7 @@ local stdlibPage = [ ]; local stdlibFrontMatter = { - layout: 'default', + layout: 'stdlib', title: 'Standard Library', }; diff --git a/doc/articles/fractal.1.html b/doc/articles/fractal.1.html index 98123a120..abb7fc143 100644 --- a/doc/articles/fractal.1.html +++ b/doc/articles/fractal.1.html @@ -82,9 +82,8 @@

Example Web Application

The example application allows the user to zoom and pan a Mandelbrot fractal (dynamically rendered server side, in C++). The user is able to save the location of features they find, deep in the fractal, and a time-ordered list of these with thumbnails is displayed in the - left hand pane. The application is provisionally hosted here, but you can easily deploy your own as all - required files are available in the Jsonnet repository. + left hand pane. All required files are available in the Jsonnet repository if you want to + deploy this yourself.

Although admittedly a little contrived, this example is intended to represent the structure diff --git a/doc/js/codemirror-mode-jsonnet.js b/doc/js/codemirror-mode-jsonnet.js index b0b826bbe..ec8649746 100644 --- a/doc/js/codemirror-mode-jsonnet.js +++ b/doc/js/codemirror-mode-jsonnet.js @@ -176,7 +176,7 @@ } // Enter text block. - if (stream.match(/\|\|\|/)) { + if (stream.match(/\|\|\|-?/)) { state.textBlock = true; state.textBlockIndent = null; return "string"; diff --git a/doc/learning/getting_started.html b/doc/learning/getting_started.html index 778b0a697..88ce2ed1e 100644 --- a/doc/learning/getting_started.html +++ b/doc/learning/getting_started.html @@ -103,6 +103,57 @@

Example

+
+
+
+

Generating non-JSON output

+
+
+
+
+ + +
+
+
+

+ Sometimes it is useful to generate output that is not in JSON format. You can do this by + writing Jsonnet code which evaluates to a string containing whatever your desired format + is. When executed with jsonnet -S or jsonnet --string jsonnet will + manifest the string result as plain text rather than a JSON-formatted string. +

+ +
// ini_output.jsonnet
+std.manifestIni({
+  sections: {
+    main: {
+      host: "127.0.0.1",
+      port: "9000",
+    },
+    database: {
+      path: "/var/data",
+    },
+  },
+})
+ +

+ When executed using jsonnet -S ini_output.jsonnet, this will output the generated + INI formatted text directly. +

+ +
$ jsonnet -S ini_output.jsonnet
+[database]
+path = /var/data
+[main]
+host = 127.0.0.1
+port = 9000
+ +
+
+
+
+ +
@@ -148,12 +199,12 @@

Multiple File Output

$ jsonnet -m . multiple_output.jsonnet
 a.json
 b.json
-$ cat a.json 
+$ cat a.json
 {
    "x": 1,
    "y": 2
 }
-$ cat b.json 
+$ cat b.json
 {
    "x": 1,
    "y": 2
@@ -223,7 +274,7 @@ 

YAML Stream Output

-

C++ or Go?

+

C++, Go, or others?

@@ -233,59 +284,20 @@

C++ or Go?

- There are two feature-compatible implementations of the Jsonnet interpreter. The first one - we built was the C++ interpreter, and it is still the most mature / widely used. The new Go - implementation has the benefits of simpler code (due to leveraging goroutines and the GO - garbage collector). Our long term plan is to migrate everyone to the Go implementation - eventually. Both implementations are tested against the same test suite (which is quite - thorough). Please report any deviations. The performance of the C++ implementation is - currently a bit better, but for most people this should not be a factor and we're intending - to address it over time, anyway. + There are multiple implementations of the Jsonnet interpreter. The original interpreter was + written in C++. However, there is a newer implementation written in Go, and this generally + has better performance, as well as the benefits of being written in a memory safe language. + The Go implementation also includes a linter, which is not available in the C++ implementation. + Both the C++ and Go versions are tested against the same test suite.

- Another factor is that the formatter is currently only implemented in the C++ repo, and the - linter is only implemented in the Go repo. + Beyond the 'official' C++ and Go implementations, there are also various implementations written + independently by other people, such as Rust and Haskell implementations, along with language + bindings / wrappers for some other languages (such as PHP, and JavaScript). + These are listed on the Bindings page.

- -
-
-
-

JavaScript

-
-
-
-
- -
-
-
-

- The C++ implementation can be compiled with emscripten to produce a JavaScript - implementation of Jsonnet. This is how we implement the interactive demos on this site. A - native implementation of Jsonnet in JavaScript would probably be faster. In fact, a - GopherJs transpile of the Go Jsonnet implementation may work better as well. However, the - emscripten version is easy to build, and is sufficient for many purposes. -

- -

- To compile it, first install - emscripten and ensure em++ and emcc are in your path. Then make libjsonnet.js. -

- -

- An unofficial nodejs package - of Jsonnet is also available. -

- -
-
-
-
- diff --git a/doc/learning/tools.html b/doc/learning/tools.html index d8b59e86a..705b156b4 100644 --- a/doc/learning/tools.html +++ b/doc/learning/tools.html @@ -169,7 +169,7 @@

Formatter Demo

-

Linter

+

Linter

@@ -194,7 +194,7 @@

Linter

-

Bazel Jsonnet Rules

+

Bazel Jsonnet Rules

diff --git a/doc/learning/tutorial.html b/doc/learning/tutorial.html index 3ac5520bf..17b78cb1f 100644 --- a/doc/learning/tutorial.html +++ b/doc/learning/tutorial.html @@ -551,7 +551,7 @@

Parameterize Entire Config

-

External variables

+

External variables

@@ -631,7 +631,7 @@

External variables

-

Top-level arguments

+

Top-level arguments

@@ -714,7 +714,7 @@

Top-level arguments

-

Object-Orientation

+

Object-Orientation

diff --git a/doc/ref/bindings.html b/doc/ref/bindings.html index 48b5eb61e..7993aeab3 100644 --- a/doc/ref/bindings.html +++ b/doc/ref/bindings.html @@ -128,6 +128,7 @@

Python API

Keyword arguments to these functions are used to control the virtual machine. They are:

    +
  • jpathdir   (string or list of strings)
  • max_stack   (number)
  • gc_min_objects   (number)
  • gc_growth_trigger   (number)
  • @@ -210,7 +211,10 @@

    Unofficial Third Party APIs

    LuaJIT (FFI)
  • - Node.js + Node.js node-jsonnet: C++ version compiled to JS code +
  • +
  • + Node.js tplfa-jsonnet: Golang version compiled to WASM code
  • PHP @@ -219,8 +223,9 @@

    Unofficial Third Party APIs

    Ruby
  • - Rust but please first consider the - native port + Rust but please first consider + one of the native ports (jrsonnet + or rsjsonnet)
  • Haskell native port diff --git a/doc/ref/language.html.md b/doc/ref/language.html.md index 792e29b67..3a5ea96cc 100644 --- a/doc/ref/language.html.md +++ b/doc/ref/language.html.md @@ -133,7 +133,7 @@ Strings can be constructed as literals, slices of existing strings, concatenatio Jsonnet numbers are 64-bit floating point numbers as defined in IEEE754 excluding `nan` and `inf` values. Operations resulting in infinity or not a number are errors. -Integers can be precisely represented as a Jsonnet number in the range [-2^53,2^53]. This is [a direct consequence of IEEE754 spec](https://en.wikipedia.org/wiki/Double-precision_floating-point_format). +Integers can be safely represented as a Jsonnet number in the range [-2^53 + 1,2^53 - 1]. This is [a direct consequence of IEEE754 spec](https://en.wikipedia.org/wiki/Double-precision_floating-point_format), with the requirements that a safe integer is representable exactly, and cannot be produced by rounding any other integer to fit the IEEE-754 representation. See also, the JavaScript [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER), [`Number.MIN_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER), and [`Number.isSafeInteger`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger) definitions. ### Function @@ -159,7 +159,7 @@ and3(true, false, error "this one is never evaluated") The expression `error "message"` raises an error with the provided message string. Thus, in this example, the values for `a` and `b` are evaluated because they are required to compute `a && b`. However, since `a && b` is `false` - there is no need to evaluate the value for `c` and the error is never thrown. -Functions in Jsonnet are [referentially transparent](https://en.wikipedia.org/wiki/Referential_transparency), meaning that any function call can be replaced with its definition, without changing the meaning of the program. Therefore, in some sense, functions in Jsonnet are [hygienic macros](https://en.wikipedia.org/wiki/Hygienic_macro). For example consider the following snippet: +Functions in Jsonnet are [referentially transparent](https://en.wikipedia.org/wiki/Referential_transparency), meaning that any function call can be replaced with its definition, without changing the meaning of the program. For example consider the following snippet: ``` local pow2(n) = if n == 0 then 1 else 2 * pow2(n - 1); diff --git a/doc/ref/spec.html b/doc/ref/spec.html index f0221df4d..3491f0b52 100644 --- a/doc/ref/spec.html +++ b/doc/ref/spec.html @@ -168,15 +168,19 @@

    Lexing

    subsequent non-quoted '
  • - Text block, beginning with |||, followed by optional whitespace and a - new-line. The next non-empty line must be prefixed with some non-zero length - whitespace W. The block ends at the first subsequent line that is non-empty - and does not begin with W, and it is an error if this line does not contain - some optional whitespace followed by |||. The content of the string is - the concatenation of all the lines between the two |||, which either - begin with W (in which case that prefix is stripped) or they are empty lines - (in which case they remain as empty lines). The line ending style in the file is - preserved in the string. This form cannot be used in import statements. + Text block, beginning with ||| followed by an optional + -, then optional whitespace and a new-line. The next non-empty + line must be prefixed with some non-zero length whitespace W. The + block ends at the first subsequent line that is non-empty and does not begin + with W, and it is an error if this line does not contain some + optional whitespace followed by |||. The content of the string + is the concatenation of all the lines between the two |||, + which either begin with W (in which case that prefix is stripped) or + they are empty lines (in which case they remain as empty lines). The line + ending style in the file is preserved in the string. If the beginning + ||| was followed by - then the final new-line is + stripped from the resulting string. This form cannot be used in + import statements.

@@ -533,7 +537,7 @@

Abstract Syntax

::= - member { , member } [ , ] + { member , } [ member ] @@ -1125,7 +1129,7 @@

Desugaring

\[ - desugar(e) = desugar_{expr}(\local{\texttt{std} = e_{std}}{e}, false) + desugar(e) = desugar_{expr}(\local{\texttt{\$std} = e_{std}}{\local{\texttt{std} = \texttt{\$std}}{e}}, false) \]
@@ -1287,7 +1291,7 @@

Desugaring

\[ desugar_{expr}(e[e':e'':e'''], b) = - desugar_{expr}(\texttt{std.slice}(e, e', e'', e'''), b) + desugar_{expr}(\texttt{\$std.slice}(e, e', e'', e'''), b) \]
@@ -1318,27 +1322,27 @@

Desugaring

\[ - desugar_{expr}(e \mathop{==} e', b) = desugar_{expr}(\texttt{std.equals}(e, e'), b) + desugar_{expr}(e \mathop{==} e', b) = desugar_{expr}(\texttt{\$std.equals}(e, e'), b) \]
\[ - desugar_{expr}(e \mathop{\%} e', b) = desugar_{expr}(\texttt{std.mod}(e, e'), b) + desugar_{expr}(e \mathop{\%} e', b) = desugar_{expr}(\texttt{\$std.mod}(e, e'), b) \]
\[ desugar_{expr}(e \mathop{\texttt{in}} e', b) = - desugar_{expr}(\texttt{std.objectHasEx}(e', e, \texttt{true}), b) + desugar_{expr}(\texttt{\$std.objectHasEx}(e', e, \texttt{true}), b) \]
\[ desugar_{expr}(e \mathop{\texttt{in}} \texttt{super}, b) = - desugar_{expr}(\texttt{std.objectHasEx}(\texttt{super}, e, \texttt{true}), b) + desugar_{expr}(\texttt{\$std.objectHasEx}(\texttt{super}, e, \texttt{true}), b) \]
@@ -1484,8 +1488,8 @@

Desugaring

\hspace{10mm}\textrm{Let }arr, i\textrm{ fresh} \\ \hspace{10mm}desugar_{expr}( \local{arr = e'}{ - \texttt{std.join}(\\\hspace{20mm}[\ ], \texttt{std.makeArray}( - \texttt{std.length}(arr), + \texttt{\$std.join}(\\\hspace{20mm}[\ ], \texttt{\$std.makeArray}( + \texttt{\$std.length}(arr), \function{i}{\local{x = arr[i]}{desugar_{arrcomp}(e, compspec, b)}} )) }, @@ -1499,8 +1503,8 @@

Desugaring

\hspace{10mm}\textrm{Let }arr, i\textrm{ fresh} \\ \hspace{10mm}desugar_{expr}( \local{arr = e'}{ - \texttt{std.join}(\\\hspace{20mm}[\ ], \texttt{std.makeArray}( - \texttt{std.length}(arr), + \texttt{\$std.join}(\\\hspace{20mm}[\ ], \texttt{\$std.makeArray}( + \texttt{\$std.length}(arr), \function{i}{\local{x = arr[i]}{[e]}} )) }, @@ -2825,7 +2829,10 @@

Execution

std.asin(x), std.acos(x), std.atan(x), + std.atan2(y, x), std.log(x), + std.log2(x), + std.log10(x), std.exp(x), std.mantissa(x), std.exponent(x) and diff --git a/doc/ref/stdlib.html b/doc/ref/stdlib.html index dc18e227d..c7360fd0e 100644 --- a/doc/ref/stdlib.html +++ b/doc/ref/stdlib.html @@ -1,6 +1,6 @@ --- # AUTOGENERATED FILE. DO NOT EDIT BY HAND! -layout: default +layout: stdlib title: Standard Library --- @@ -53,7 +53,7 @@

-

+

std.extVar(x)

@@ -92,7 +92,7 @@

-

+

std.thisFile

@@ -119,7 +119,7 @@

-

+

std.type(x)

@@ -153,7 +153,7 @@

-

+

std.length(x)

@@ -183,7 +183,7 @@

-

+

std.prune(a)

@@ -234,6 +234,8 @@

    std.pow(x, n)
    std.exp(x)
    std.log(x)
+
    std.log2(x)
+
    std.log10(x)
    std.exponent(x)
    std.mantissa(x)
    std.floor(x)
@@ -245,12 +247,19 @@

    std.asin(x)
    std.acos(x)
    std.atan(x)
+
    std.atan2(y, x)
+
    std.deg2rad(x)
+
    std.rad2deg(x)
+
    std.hypot(a, b)
    std.round(x)
    std.isEven(x)
    std.isOdd(x)
    std.isInteger(x)
    std.isDecimal(x)
+

+ The constant std.pi is also available. +

The function std.mod(a, b) is what the % operator is desugared to. It performs modulo arithmetic if the left hand side is a number, or if the left hand side is a string, @@ -268,7 +277,7 @@

-

+

std.clamp(x, minVal, maxVal)

@@ -316,7 +325,7 @@

-

+

std.assertEqual(a, b)

@@ -355,7 +364,7 @@

-

+

std.toString(a)

@@ -382,7 +391,7 @@

-

+

std.codepoint(str)

@@ -410,7 +419,7 @@

-

+

std.char(n)

@@ -438,7 +447,7 @@

-

+

std.substr(str, from, len)

@@ -454,10 +463,15 @@

- Returns a string that is the part of s that starts at offset from - and is len codepoints long. If the string s is shorter than + Returns a string that is the part of str that starts at offset from + and is len codepoints long. If the string str is shorter than from+len, the suffix starting at position from will be returned.

+

+ The slice operator (e.g., str[from:to]) can also be used on strings, as an + alternative to this function. However, note that the slice operator takes a start and an + end index, but std.substr takes a start index and a length. +

@@ -467,7 +481,7 @@

-

+

std.findSubstr(pat, str)

@@ -495,7 +509,7 @@

-

+

std.startsWith(a, b)

@@ -522,7 +536,7 @@

-

+

std.endsWith(a, b)

@@ -549,7 +563,7 @@

-

+

std.stripChars(str, chars)

@@ -584,7 +598,7 @@

-

+

std.lstripChars(str, chars)

@@ -619,7 +633,7 @@

-

+

std.rstripChars(str, chars)

@@ -654,7 +668,7 @@

-

+

std.split(str, c)

@@ -690,7 +704,7 @@

-

+

std.splitLimit(str, c, maxsplits)

@@ -726,7 +740,7 @@

-

+

std.splitLimitR(str, c, maxsplits)

@@ -755,7 +769,7 @@

-

+

std.strReplace(str, from, to)

@@ -785,7 +799,7 @@

-

+

std.isEmpty(str)

@@ -812,7 +826,7 @@

-

+

std.trim(str)

@@ -824,7 +838,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -839,7 +853,7 @@

-

+

std.equalsIgnoreCase(str1, str2)

@@ -851,7 +865,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -866,7 +880,7 @@

-

+

std.asciiUpper(str)

@@ -895,7 +909,7 @@

-

+

std.asciiLower(str)

@@ -924,7 +938,7 @@

-

+

std.stringChars(str)

@@ -954,7 +968,7 @@

-

+

std.format(str, vals)

@@ -996,7 +1010,7 @@

-

+

std.escapeStringBash(str)

@@ -1025,7 +1039,7 @@

-

+

std.escapeStringDollars(str)

@@ -1053,7 +1067,7 @@

-

+

std.escapeStringJson(str)

@@ -1084,7 +1098,7 @@

-

+

std.escapeStringPython(str)

@@ -1112,7 +1126,7 @@

-

+

std.escapeStringXml(str)

@@ -1160,7 +1174,7 @@

-

+

std.parseInt(str)

@@ -1192,7 +1206,7 @@

-

+

std.parseOctal(str)

@@ -1221,7 +1235,7 @@

-

+

std.parseHex(str)

@@ -1250,7 +1264,7 @@

-

+

std.parseJson(str)

@@ -1279,7 +1293,7 @@

-

+

std.parseYaml(str)

@@ -1312,7 +1326,7 @@

-

+

std.encodeUTF8(str)

@@ -1340,7 +1354,7 @@

-

+

std.decodeUTF8(arr)

@@ -1380,7 +1394,7 @@

-

+

std.manifestIni(ini)

@@ -1432,7 +1446,7 @@

-

+

std.manifestPython(v)

@@ -1475,7 +1489,7 @@

-

+

std.manifestPythonVars(conf)

@@ -1517,7 +1531,7 @@

-

+

std.manifestJsonEx(value, indent, newline, key_val_sep)

@@ -1540,20 +1554,42 @@

of an object field:

- Example: std.manifestJsonEx( - { - x: [1, 2, 3, true, false, null, - "string\nstring"], - y: { a: 1, b: 2, c: [1, 2] }, - }, " ") yields "{\n \"x\": [\n 1,\n 2,\n 3,\n true,\n false,\n null,\n \"string\\nstring\"\n ],\n \"y\": {\n \"a\": 1,\n \"b\": 2,\n \"c\": [\n 1,\n 2\n ]\n }\n}". -

+ Example: +

std.manifestJsonEx(
+{
+    x: [1, 2, 3, true, false, null,
+        "string\nstring"],
+    y: { a: 1, b: 2, c: [1, 2] },
+}, "    ")

+ Yields a string containing this JSON: +

{
+    "x": [
+        1,
+        2,
+        3,
+        true,
+        false,
+        null,
+        "string\nstring"
+    ],
+    "y": {
+        "a": 1,
+        "b": 2,
+        "c": [
+            1,
+            2
+        ]
+    }
+}

- Example: std.manifestJsonEx( - { - x: [1, 2, "string\nstring"], - y: { a: 1, b: [1, 2] }, - }, "", " ", " : ") yields "{ \"x\" : [ 1, 2, \"string\\nstring\" ], \"y\" : { \"a\" : 1, \"b\" : [ 1, 2 ] } }". -

+ Example: +

std.manifestJsonEx(
+{
+  x: [1, 2, "string\nstring"],
+  y: { a: 1, b: [1, 2] },
+}, "", " ", " : ")

+ Yields a string containing this JSON: +

{ "x" : [ 1, 2, "string\nstring" ], "y" : { "a" : 1, "b" : [ 1, 2 ] } }

@@ -1562,7 +1598,7 @@

-

+

std.manifestJson(value)

@@ -1582,13 +1618,33 @@

it calls std.manifestJsonEx with a 4-space indent:

- Example: std.manifestJson( - { - x: [1, 2, 3, true, false, null, - "string\nstring"], - y: { a: 1, b: 2, c: [1, 2] }, - }) yields "{\n \"x\": [\n 1,\n 2,\n 3,\n true,\n false,\n null,\n \"string\\nstring\"\n ],\n \"y\": {\n \"a\": 1,\n \"b\": 2,\n \"c\": [\n 1,\n 2\n ]\n }\n}". -

+ Example: +

std.manifestJson(
+{
+    x: [1, 2, 3, true, false, null,
+        "string\nstring"],
+    y: { a: 1, b: 2, c: [1, 2] },
+})

+ Yields a string containing this JSON: +

{
+    "x": [
+        1,
+        2,
+        3,
+        true,
+        false,
+        null,
+        "string\nstring"
+    ],
+    "y": {
+        "a": 1,
+        "b": 2,
+        "c": [
+            1,
+            2
+        ]
+    }
+}

@@ -1597,7 +1653,7 @@

-

+

std.manifestJsonMinified(value)

@@ -1617,13 +1673,15 @@

it calls std.manifestJsonEx:

- Example: std.manifestJsonMinified( - { - x: [1, 2, 3, true, false, null, - "string\nstring"], - y: { a: 1, b: 2, c: [1, 2] }, - }) yields "{\"x\":[1,2,3,true,false,null,\"string\\nstring\"],\"y\":{\"a\":1,\"b\":2,\"c\":[1,2]}}". -

+ Example: +

std.manifestJsonMinified(
+{
+    x: [1, 2, 3, true, false, null,
+        "string\nstring"],
+    y: { a: 1, b: 2, c: [1, 2] },
+})

+ Yields a string containing this JSON: +

{"x":[1,2,3,true,false,null,"string\nstring"],"y":{"a":1,"b":2,"c":[1,2]}}

@@ -1632,7 +1690,7 @@

-

+

std.manifestYamlDoc(value, indent_array_in_object=false, quote_keys=true)

@@ -1695,7 +1753,7 @@

-

+

std.manifestYamlStream(value, indent_array_in_object=false, c_document_end=false, quote_keys=true)

@@ -1744,7 +1802,7 @@

-

+

std.manifestXmlJsonml(value)

@@ -1815,7 +1873,7 @@

-

+

std.manifestTomlEx(toml, indent)

@@ -1835,24 +1893,48 @@

one or more whitespaces that are used for indentation:

- Example: std.manifestTomlEx({ - key1: "value", - key2: 1, - section: { - a: 1, - b: "str", - c: false, - d: [1, "s", [2, 3]], - subsection: { - k: "v", - }, - }, - sectionArray: [ - { k: "v1", v: 123 }, - { k: "v2", c: "value2" }, - ], - }, " ") yields "key1 = \"value\"\nkey2 = 1\n\n[section]\n a = 1\n b = \"str\"\n c = false\n d = [\n 1,\n \"s\",\n [ 2, 3 ]\n ]\n\n [section.subsection]\n k = \"v\"\n\n[[sectionArray]]\n k = \"v1\"\n v = 123\n\n[[sectionArray]]\n c = \"value2\"\n k = \"v2\"". -

+ Example: +

std.manifestTomlEx({
+  key1: "value",
+  key2: 1,
+  section: {
+    a: 1,
+    b: "str",
+    c: false,
+    d: [1, "s", [2, 3]],
+    subsection: {
+      k: "v",
+    },
+  },
+  sectionArray: [
+    { k: "v1", v: 123 },
+    { k: "v2", c: "value2" },
+  ],
+}, "  ")

+ Yields a string containing this TOML file: +

key1 = "value"
+key2 = 1
+
+[section]
+  a = 1
+  b = "str"
+  c = false
+  d = [
+    1,
+    "s",
+    [ 2, 3 ]
+  ]
+
+  [section.subsection]
+    k = "v"
+
+[[sectionArray]]
+  k = "v1"
+  v = 123
+
+[[sectionArray]]
+  c = "value2"
+  k = "v2"

@@ -1873,7 +1955,7 @@

-

+

std.makeArray(sz, func)

@@ -1904,7 +1986,7 @@

-

+

std.member(arr, x)

@@ -1932,7 +2014,7 @@

-

+

std.count(arr, x)

@@ -1959,7 +2041,7 @@

-

+

std.find(value, arr)

@@ -1987,7 +2069,7 @@

-

+

std.map(func, arr)

@@ -2014,7 +2096,7 @@

-

+

std.mapWithIndex(func, arr)

@@ -2043,7 +2125,7 @@

-

+

std.filterMap(filter_func, map_func, arr)

@@ -2070,7 +2152,7 @@

-

+

std.flatMap(func, arr)

@@ -2114,7 +2196,7 @@

-

+

std.filter(func, arr)

@@ -2142,7 +2224,7 @@

-

+

std.foldl(func, arr, init)

@@ -2158,9 +2240,12 @@

- Classic foldl function. Calls the function on the result of the previous function call and - each array element, or init in the case of the initial element. Traverses the - array from left to right. + Classic foldl function. Calls the function for each array element, passing the result from + the previous call (or init for the first call), and the array element. Traverses + the array from left to right. +

+

+ For example: foldl(f, [1,2,3], 0) is equivalent to f(f(f(0, 1), 2), 3).

@@ -2171,7 +2256,7 @@

-

+

std.foldr(func, arr, init)

@@ -2187,9 +2272,12 @@

- Classic foldr function. Calls the function on the result of the previous function call and - each array element, or init in the case of the initial element. Traverses the - array from right to left. + Classic foldr function. Calls the function for each array element, passing the array element + and the result from the previous call (or init for the first call). Traverses + the array from right to left. +

+

+ For example: foldr(f, [1,2,3], 0) is equivalent to f(1, f(2, f(3, 0))).

@@ -2200,7 +2288,7 @@

-

+

std.range(from, to)

@@ -2227,7 +2315,7 @@

-

+

std.repeat(what, count)

@@ -2259,7 +2347,7 @@

-

+

std.slice(indexable, index, end, step)

@@ -2300,7 +2388,7 @@

-

+

std.join(sep, arr)

@@ -2335,7 +2423,41 @@

-

+

+ std.deepJoin(arr) +

+
+
+
+
+
+
+
+

+ + Available since version 0.10.0. + +

+

+ Concatenate an array containing strings and arrays to form a single string. If arr is + a string, it is returned unchanged. If it is an array, it is flattened and the string elements are + concatenated together with no separator. +

+

+ Example: std.deepJoin(["one ", ["two ", "three ", ["four "], []], "five ", ["six"]]) yields "one two three four five six". +

+

+ Example: std.deepJoin("hello") yields "hello". +

+
+
+
+
+ +
+
+
+

std.lines(arr)

@@ -2363,7 +2485,7 @@

-

+

std.flattenArrays(arr)

@@ -2392,7 +2514,7 @@

-

+

std.flattenDeepArray(value)

@@ -2404,7 +2526,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -2421,7 +2543,7 @@

-

+

std.reverse(arrs)

@@ -2448,7 +2570,7 @@

-

+

std.sort(arr, keyF=id)

@@ -2479,7 +2601,7 @@

-

+

std.uniq(arr, keyF=id)

@@ -2510,7 +2632,7 @@

-

+

std.all(arr)

@@ -2540,7 +2662,7 @@

-

+

std.any(arr)

@@ -2570,7 +2692,7 @@

-

+

std.sum(arr)

@@ -2597,7 +2719,7 @@

-

+

std.minArray(arr, keyF, onEmpty)

@@ -2609,11 +2731,15 @@

- Available in upcoming release. + Available since version 0.21.0.

- Return the min of all element in arr. + Return the minimum of all elements in arr. If keyF is provided, it is called on each element + of the array and should return a comparator value, and in this case minArray will return an element + with the minimum comparator value. If onEmpty is provided, and arr is empty, then + minArray will return the provided onEmpty value. If onEmpty is not provided, + then an empty arr will raise an error.

@@ -2624,7 +2750,7 @@

-

+

std.maxArray(arr, keyF, onEmpty)

@@ -2636,11 +2762,15 @@

- Available in upcoming release. + Available since version 0.21.0.

- Return the max of all element in arr. + Return the maximum of all elements in arr. If keyF is provided, it is called on each element + of the array and should return a comparator value, and in this case maxArray will return an element + with the maximum comparator value. If onEmpty is provided, and arr is empty, then + maxArray will return the provided onEmpty value. If onEmpty is not provided, + then an empty arr will raise an error.

@@ -2651,7 +2781,7 @@

-

+

std.contains(arr, elem)

@@ -2663,7 +2793,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -2678,7 +2808,7 @@

-

+

std.avg(arr)

@@ -2705,7 +2835,7 @@

-

+

std.remove(arr, elem)

@@ -2717,7 +2847,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -2732,7 +2862,7 @@

-

+

std.removeAt(arr, idx)

@@ -2744,7 +2874,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -2791,7 +2921,7 @@

-

+

std.set(arr, keyF=id)

@@ -2818,7 +2948,7 @@

-

+

std.setInter(a, b, keyF=id)

@@ -2845,7 +2975,7 @@

-

+

std.setUnion(a, b, keyF=id)

@@ -2880,7 +3010,7 @@

-

+

std.setDiff(a, b, keyF=id)

@@ -2907,7 +3037,7 @@

-

+

std.setMember(x, arr, keyF=id)

@@ -2946,7 +3076,7 @@

-

+

std.get(o, f, default=null, inc_hidden=true)

@@ -2974,7 +3104,7 @@

-

+

std.objectHas(o, f)

@@ -3003,7 +3133,7 @@

-

+

std.objectFields(o)

@@ -3031,7 +3161,7 @@

-

+

std.objectValues(o)

@@ -3058,7 +3188,7 @@

-

+

std.objectKeysValues(o)

@@ -3074,7 +3204,7 @@

- Returns an array of objects from the given object, each object having two fields: + Returns an array of objects from the given object, each object having two fields: key (string) and value (object). Does not include hidden fields.

@@ -3086,7 +3216,7 @@

-

+

std.objectHasAll(o, f)

@@ -3113,7 +3243,7 @@

-

+

std.objectFieldsAll(o)

@@ -3140,7 +3270,7 @@

-

+

std.objectValuesAll(o)

@@ -3167,7 +3297,7 @@

-

+

std.objectKeysValuesAll(o)

@@ -3194,7 +3324,7 @@

-

+

std.objectRemoveKey(obj, key)

@@ -3206,7 +3336,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -3221,7 +3351,7 @@

-

+

std.mapWithKey(func, obj)

@@ -3262,7 +3392,7 @@

-

+

std.base64(input)

@@ -3293,7 +3423,7 @@

-

+

std.base64DecodeBytes(str)

@@ -3322,7 +3452,7 @@

-

+

std.base64Decode(str)

@@ -3352,7 +3482,7 @@

-

+

std.md5(s)

@@ -3379,7 +3509,7 @@

-

+

std.sha1(s)

@@ -3391,7 +3521,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -3409,7 +3539,7 @@

-

+

std.sha256(s)

@@ -3421,7 +3551,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -3439,7 +3569,7 @@

-

+

std.sha512(s)

@@ -3451,7 +3581,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -3469,7 +3599,7 @@

-

+

std.sha3(s)

@@ -3481,7 +3611,7 @@

- Available in upcoming release. + Available since version 0.21.0.

@@ -3511,7 +3641,7 @@

-

+

std.xor(x, y)

@@ -3538,7 +3668,7 @@

-

+

std.xnor(x, y)

@@ -3577,7 +3707,7 @@

-

+

std.mergePatch(target, patch)

@@ -3617,7 +3747,7 @@

-

+

std.trace(str, rest)

diff --git a/doc/third_party/anchor.min.js b/doc/third_party/anchor.min.js new file mode 100644 index 000000000..5ac814d1e --- /dev/null +++ b/doc/third_party/anchor.min.js @@ -0,0 +1,9 @@ +// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat +// +// AnchorJS - v5.0.0 - 2023-01-18 +// https://www.bryanbraun.com/anchorjs/ +// Copyright (c) 2023 Bryan Braun; Licensed MIT +// +// @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat +!function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(globalThis,function(){"use strict";return function(A){function u(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function d(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],u(this.options),this.add=function(A){var e,t,o,i,n,s,a,r,l,c,h,p=[];if(u(this.options),0!==(e=d(A=A||"h2, h3, h4, h5, h6")).length){for(null===document.head.querySelector("style.anchorjs")&&((A=document.createElement("style")).className="anchorjs",A.appendChild(document.createTextNode("")),void 0===(h=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(A):document.head.insertBefore(A,h),A.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",A.sheet.cssRules.length),A.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); +// @license-end \ No newline at end of file diff --git a/examples/bazel/.bazelrc b/examples/bazel/.bazelrc new file mode 100644 index 000000000..011eb53a0 --- /dev/null +++ b/examples/bazel/.bazelrc @@ -0,0 +1 @@ +common --lockfile_mode=off diff --git a/examples/bazel/.gitignore b/examples/bazel/.gitignore new file mode 100644 index 000000000..648fc0ebc --- /dev/null +++ b/examples/bazel/.gitignore @@ -0,0 +1 @@ +MODULE.bazel.lock diff --git a/examples/bazel/BUILD b/examples/bazel/BUILD new file mode 100644 index 000000000..5be84632f --- /dev/null +++ b/examples/bazel/BUILD @@ -0,0 +1,27 @@ +load("@rules_python//python:defs.bzl", "py_binary") + +cc_binary( + name = "use_cpp_lib", + srcs = ["use_cpp_lib.cc"], + deps = ["@jsonnet//cpp:libjsonnet++"], +) + +cc_binary( + name = "use_c_lib", + srcs = ["use_c_lib.c"], + deps = ["@jsonnet//core:libjsonnet"], +) + +py_binary( + name = "use_py_module", + srcs = ["use_py_module.py"], + deps = ["@jsonnet//python:_jsonnet"], +) + +genrule( + name = "use_jsonnet_cmd", + srcs = ["example.jsonnet"], + outs = ["example.out"], + cmd = "$(location @jsonnet//cmd:jsonnet) $< > $@", + tools = ["@jsonnet//cmd:jsonnet"], +) diff --git a/examples/bazel/MODULE.bazel b/examples/bazel/MODULE.bazel new file mode 100644 index 000000000..1888e073f --- /dev/null +++ b/examples/bazel/MODULE.bazel @@ -0,0 +1,5 @@ +# Example of using jsonnet by depending on the Bazel module. + +bazel_dep(name = "rules_python", version = "1.2.0") +bazel_dep(name = "jsonnet") +local_path_override(module_name = "jsonnet", path = "../..") diff --git a/examples/bazel/example.jsonnet b/examples/bazel/example.jsonnet new file mode 100644 index 000000000..8c7488deb --- /dev/null +++ b/examples/bazel/example.jsonnet @@ -0,0 +1,8 @@ +local Person(name='Alice') = { + name: name, + welcome: 'Hello ' + name + '!', +}; +{ + person1: Person(), + person2: Person('Bob'), +} diff --git a/examples/bazel/expect.out b/examples/bazel/expect.out new file mode 100644 index 000000000..f762be2c2 --- /dev/null +++ b/examples/bazel/expect.out @@ -0,0 +1,10 @@ +{ + "person1": { + "name": "Alice", + "welcome": "Hello Alice!" + }, + "person2": { + "name": "Bob", + "welcome": "Hello Bob!" + } +} diff --git a/examples/bazel/use_c_lib.c b/examples/bazel/use_c_lib.c new file mode 100644 index 000000000..8423613ed --- /dev/null +++ b/examples/bazel/use_c_lib.c @@ -0,0 +1,22 @@ +#include +#include +#include + +int main(int argc, char **argv) { + int ret = 0; + fprintf(stderr, "Jsonnet version: %s\n", jsonnet_version()); + struct JsonnetVm *vm = jsonnet_make(); + if (!vm) { return 1; } + + int err = 0; + char *result = jsonnet_evaluate_file(vm, "example.jsonnet", &err); + if (!err) { + fprintf(stdout, "%s\n", result ? result : "-- no output --"); + } else { + fprintf(stderr, "%s\n", result ? result : "-- no output --"); + ret = 2; + } + + jsonnet_destroy(vm); + return ret; +} diff --git a/examples/bazel/use_cpp_lib.cc b/examples/bazel/use_cpp_lib.cc new file mode 100644 index 000000000..08341b86c --- /dev/null +++ b/examples/bazel/use_cpp_lib.cc @@ -0,0 +1,22 @@ +#include +#include + +int main(int argc, char **argv) { + int ret = 0; + std::cerr << "Jsonnet version: " << jsonnet::Jsonnet::version() << std::endl; + + jsonnet::Jsonnet vm; + if (!vm.init()) { + return 1; + } + + std::string result; + bool ok = vm.evaluateFile("example.jsonnet", &result); + if (ok) { + std::cout << result << std::endl; + } else { + std::cerr << vm.lastError() << std::endl; + ret = 2; + } + return ret; +} diff --git a/examples/bazel/use_py_module.py b/examples/bazel/use_py_module.py new file mode 100644 index 000000000..18532b679 --- /dev/null +++ b/examples/bazel/use_py_module.py @@ -0,0 +1,5 @@ +import sys +import _jsonnet + +result = _jsonnet.evaluate_file("example.jsonnet") +sys.stdout.write(result) diff --git a/include/BUILD b/include/BUILD index 7d24dbf69..3893ba462 100644 --- a/include/BUILD +++ b/include/BUILD @@ -1,19 +1,23 @@ -package(default_visibility = ["//visibility:public"]) +package(default_visibility = ["//visibility:private"]) cc_library( name = "libjsonnet", hdrs = ["libjsonnet.h"], includes = ["."], + visibility = ["//core:__pkg__"], ) cc_library( name = "libjsonnet_fmt", hdrs = ["libjsonnet_fmt.h"], includes = ["."], + visibility = ["//core:__pkg__"], ) cc_library( name = "libjsonnet++", hdrs = ["libjsonnet++.h"], includes = ["."], + visibility = ["//cpp:__pkg__"], + deps = ["//include:libjsonnet"], ) diff --git a/include/libjsonnet.h b/include/libjsonnet.h index e86f1662f..99cad5023 100644 --- a/include/libjsonnet.h +++ b/include/libjsonnet.h @@ -24,14 +24,14 @@ limitations under the License. * of using the library. */ -/** The version string of th Jsonnet interpreter. +/** The version string of the Jsonnet interpreter. * * This is currently grepped out of this file by setup.py, Makefile, and CMakeLists.txt so be aware * of that when making changes. * - * If this isn't the sae as jsonnet_version() then you've got a mismatched binary / header. + * If this isn't the same as jsonnet_version() then you've got a mismatched binary / header. */ -#define LIB_JSONNET_VERSION "v0.20.0" +#define LIB_JSONNET_VERSION "v0.21.0" /** Return the version string of the Jsonnet interpreter. Conforms to semantic versioning * https://semver.org/ If this does not match LIB_JSONNET_VERSION then there is a mismatch between diff --git a/platform_defs/BUILD b/platform_defs/BUILD index 930d7735d..43664ae82 100644 --- a/platform_defs/BUILD +++ b/platform_defs/BUILD @@ -1,10 +1,12 @@ -load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") +load("@rules_python//python:defs.bzl", "py_runtime", "py_runtime_pair") + +package(default_visibility = ["//visibility:private"]) py_runtime( name = "python3", interpreter_path = "/usr/bin/python3", - stub_shebang = "#!/usr/bin/env python3", python_version = "PY3", + stub_shebang = "#!/usr/bin/env python3", ) py_runtime_pair( @@ -16,6 +18,5 @@ py_runtime_pair( toolchain( name = "default_python3_toolchain", toolchain = ":just_python3", - toolchain_type = "@bazel_tools//tools/python:toolchain_type", + toolchain_type = "@rules_python//python:toolchain_type", ) - diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..f8483397b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = ["setuptools >= 72.2"] diff --git a/python/BUILD b/python/BUILD index 12936ad26..513f2dcf9 100644 --- a/python/BUILD +++ b/python/BUILD @@ -1,10 +1,14 @@ +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +package(default_visibility = ["//visibility:private"]) + cc_binary( name = "_jsonnet.so", srcs = ["_jsonnet.c"], linkshared = 1, deps = [ "//core:libjsonnet", - "@default_python3_headers//:headers", + "@rules_python//python/cc:current_py_cc_headers", ], ) @@ -18,11 +22,12 @@ py_library( py_test( name = "_jsonnet_test", + size = "small", srcs = ["_jsonnet_test.py"], data = [ "testdata/basic_check.jsonnet", - "testdata/binary1230123.bin", "testdata/binary123.bin", + "testdata/binary1230123.bin", "testdata/trivial.jsonnet", "testdata/trivial_no_eol.jsonnet", ], diff --git a/python/_jsonnet.c b/python/_jsonnet.c index 5acd4aa1a..6bca5c7e9 100644 --- a/python/_jsonnet.c +++ b/python/_jsonnet.c @@ -186,7 +186,7 @@ static struct JsonnetJsonValue *cpython_native_callback( } // Call python function. - result = PyEval_CallObject(ctx->callback, arglist); + result = PyObject_CallObject(ctx->callback, arglist); Py_DECREF(arglist); if (result == NULL) { @@ -226,7 +226,7 @@ static int cpython_import_callback(void *ctx_, const char *base, const char *rel PyEval_RestoreThread(*ctx->py_thread); arglist = Py_BuildValue("(s, s)", base, rel); - result = PyEval_CallObject(ctx->callback, arglist); + result = PyObject_CallObject(ctx->callback, arglist); Py_DECREF(arglist); if (result == NULL) { diff --git a/release_checklist.md b/release_checklist.md index 1876f055c..83d6229ea 100644 --- a/release_checklist.md +++ b/release_checklist.md @@ -4,110 +4,141 @@ Before doing the release, make sure that the project is in good state: -* Triage issues – make sure that all issues are labelled. -* Check for release-blocking bugs. All bugs which results in a wrong result of the evaluation are release-blocking. -* Go through the open PRs – consider merging any outstanding ones. Do not merge big changes right before the release. -* Sync google/go-jsonnet and google/jsonnet - 1) Check out master from both - 1) Check go-jsonnet/cpp-jsonnet submodule is HEAD of jsonnet tree, if not: - 1) Inside cpp-jsonnet: - 1) `git checkout master` - 1) `git pull` - 1) `cd ..` - 1) `git checkout -b release` - 1) Update the standard library: `go run cmd/dumpstdlibast/dumpstdlibast.go cpp-jsonnet/stdlib/std.jsonnet > astgen/stdast.go` - 1) `./tests.sh` - 1) Fix any failing tests. - 1) Send a PR with the updated version, so that all the CI tests are run -* Check that CI is green. -* Make sure that the project can be built and the tests pass using all build systems. - * C++: - 1) `make test` - 1) `bazel test ...:all` - 1) `mkdir build ; cd build ; cmake .. ; make ; make test` - * Go: - 1) `./tests.sh` - 2) `bazel test //:go_default_test` -* Make sure the Python bindings work (build and run tests locally). -* Go through the commits since the last release and prepare the release notes. - * The release notes should have separate sections for the language changes and - changes specific to each implementation. -* Make sure that the stdlib documentation is complete. Check the release notes for any -additions or changes to stdlib and make sure they are reflected in the documentation. -* Make sure that you can build the website locally. - * Download or build libjsonnet.wasm (see README.md for instructions) - * `jekyll serve -s doc/` (you need Jekyll 4.3.0 or later) to serve the site locally to check it. - * Check that it works in two different browsers. Make sure that live evaluation +- Triage issues – make sure that all issues are labelled. +- Check for release-blocking bugs. All bugs which results in a wrong result of the evaluation are release-blocking. +- Go through the open PRs – consider merging any outstanding ones. Do not merge big changes right before the release. +- Sync google/go-jsonnet and google/jsonnet + 1. Check out master from both + 1. Use the `update_cpp_jsonnet.sh` script in the go-jsonnet repository to sync it to jsonnet master. + 1. Run tests: `./tests.sh` + 1. Fix any failing tests. + 1. Send a PR with the updated version, so that all the CI tests are run. +- Check that CI is green in both C++ and Go jsonnet: Checks should run automatically on pushes to `master`, + so you can check the status on the latest master commit. +- Optionally, run tests locally to double-check. + - C++: + 1. `make test` + 1. `bazel test ...:all` + 1. `mkdir build ; cd build ; cmake .. ; make ; make test` + - Go: + 1. `./tests.sh` + 2. `bazel test //:go_default_test` +- Optionally, make sure the Python bindings build and work correctly locally. +- Go through the commits since the last release and prepare the release notes. + The release notes should have separate sections for the language changes and + changes specific to each implementation. +- Make sure that the stdlib documentation is complete. Check the git history for any + changes to stdlib (including builtins) and make sure they are reflected in the documentation. +- Make sure that you can build the website locally. + - Download or build libjsonnet.wasm (see README.md for instructions) + - `jekyll serve -s doc/` (you need Jekyll 4.3.0 or later) to serve the site locally to check it. + - Check that it works in two different browsers. Make sure that live evaluation in the tutorial works. All the above points apply to both google/jsonnet and google/go-jsonnet. ## Make a final decision to release -A this point you should be confident that the project is ready for the release. -Some of subsequent steps leave project are hard to reverse and/or leave the project in -an inconsistent state, so proceed only if you have time to complete the release process -in one sitting and fix any unexpected problems. +A this point you should be confident that the project is ready for the release, and know what +will be included in that release. ## Release the C++ version -* Modify `include/libjsonnet.h` to bump the version number but add `-pre1` suffix. -* Update `test_cmd` golden file version numbers: -``` -./tools/scripts/replace_test_cmd_version.sh -pre1 -``` -* Upload and test the pre-release Python package. - 1) `python setup.py build sdist` - 1) `twine upload dist/whatever.tar.gz` (Needs credentials on pypi) - 1) ON ANOTHER MACHINE AND CHECK THAT THE VERSION IS CORRECT AND IT ACTUALLY IS BUILDING THINGS IN THE LOG: `sudo pip install jsonnet --pre --upgrade` - 1) `python` - 1) `import _jsonnet` - 1) `_jsonnet.evaluate_snippet('foo', '1+1')` -* Remove -pre from version in `include/libjsonnet.h`. -* Update version in `cpp/CMakeLists.txt`. -* Update `test_cmd` golden file version numbers: -``` -./tools/scripts/replace_test_cmd_version.sh -``` -* In `doc/_stdlib_gen/stdlib-content.jsonnet` replace any `availableSince: "upcoming"` with NEW_VERSION". -* Send a PR and wait for CI to be green before merging. -* Create a release on Github. Put the previously prepared release notes there. -* Upload the Python package. - 1) `python setup.py build sdist` - 1) `twine upload dist/whatever.tar.gz` (the version without the -pre) +1. Checkout the `prepare-release` branch. +1. Fast-forward merge it to match `master` (it should fast-forward cleanly!): + `git merge --ff-only upstream/master` + (`upstream` might have a different name depending on your local git checkout) +1. Modify `include/libjsonnet.h` to the version number for the new release. If you are making a + release candidate and not a full release, include a suffix like `-rc1`. +1. Modify `MODULE.bazel` to match the new release version number. +1. Update `test_cmd` golden file version numbers: + + ``` + ./tools/scripts/replace_test_cmd_version.sh + ``` + +1. In `doc/_stdlib_gen/stdlib-content.jsonnet` replace any `availableSince: "upcoming"` with NEW_VERSION". + +1. Commit the version number changes. Typically I use a commit message like: + `git commit -m "release: prepare to release v0.21.0-rc2"` + +1. Push the `prepare-release` up to github. CI checks should automatically be triggered on the branch. + Wait for them to be green, in: https://github.com/google/jsonnet/actions + If CI checks don't pass, fix the problems. +1. Optionally: Perform a test Python build & publish to `testpypi`. This is important to do if the Python + build/publish process has changed, but less important otherwise. To do this, on the GitHub Actions page, + manually trigger the "Build and Publish Python Package" workflow. Set the options appropriately + (check the "Upload generate package files to PyPI" checkbox, select "testpypi" as the instance to + publish to). You will need to explicitly approve the publish step after the build step is completed. + This lets you check the whole workflow end to end and check that all the steps succeeded. + If you just want to verify that building the Python packages works (without checking the publishing + process) you can run the workflow but leave "Upload generate package files to PyPI" unchecked. +1. On the GitHub Actions page, manually trigger the "Release" workflow. + This will create a new _draft_ release in GitHub, and attach a tarball archive of the repository content. + The version number for the release is extracted directly from the `LIB_JSONNET_VERSION` in the jsonnet header. +1. On the GitHub Actions page, manually trigger the "Build and Publish Python Package" workflow. In the + workflow settings, check "Upload generate package files to PyPI" and select "pypi" as the instance to + publish to. + This will build Python packages for a variety of systems. It will then _pause_ and wait for an approval + before publishing them to PyPI. I generally wait until I'm really ready to hit the publish button on the + release in GitHub before approving the PyPI publish step (but I let PyPI publishing complete before hitting + the GitHub button so that I can confirm that the packages get uploaded successfully). +1. Do any last minute checks you want to do! + If you want to manually check any of the built Python packages before they're published, you can download + them GitHub Actions - they are available as "Artifacts" on the workflow. If you want to download and check + the source tarball you can download it from the draft release in GitHub. +1. Finalise the release notes in the GitHub release UI. +1. Approve PyPI publishing and let it complete. +1. Check that the new/proposed version tag specified in the GitHub release is correct and hit the Publish button + (you do not have to manually create the tag - GitHub creates tag when you publish the release). +1. Fast-forward merge the `prepare-release` branch to `master` and push `master` so that the repo master state + matches the release that was just published. +1. TO BE WRITTEN: Update the Bazel module at https://registry.bazel.build/modules/jsonnet. ## Release the Go version -* Sync with the (freshly-released) C++ version. -* At this point the C++ tests will not pass due to a different version in test_cmd tests. -* Modify `vm.go` to bump the version number, but add `-pre1` suffix. -* Upload and test the pre-release Python package. - 1) `python setup.py build sdist` - 1) `twine upload dist/whatever.tar.gz` (Needs credentials on pypi) - 1) ON ANOTHER MACHINE AND CHECK THAT THE VERSION IS CORRECT AND IT ACTUALLY IS BUILDING THINGS IN THE LOG: `sudo pip install gojsonnet --pre --upgrade` - 1) `python` - 1) `import _gojsonnet` - 1) `_gojsonnet.evaluate_snippet('foo', '1+1')` -* Remove the `-pre1` from version in `vm.go`. Now the tests should pass again. -* Send a PR and wait for CI to be green before merging. -* Create a release on Github. Link to the C++ release in the description. -* Upload the Python package. - 1) `python setup.py build sdist` - 1) `twine upload dist/whatever.tar.gz` (the version without the -pre) +This should be done _after_ the C++ version release, because the Go version depends on the C++ version: it uses +the standard library from the C++ version, and some header files. + +1. In `go-jsonnet`, switch to the `prepare-release` branch and bring it up to date with `master`: + Fast-forward merge with `git merge --ff-only`. +1. In `go-jsonnet` you can run the `update_cpp_jsonnet.sh` script and pass in the published version tag + for the C++ version; this will update go-jsonnet to pin it to that specific release (instead of pinning + to a commit hash). Pinning to the release is better, because it will use the stable jsonnet release + source tarball (which has a stable hash that can be used) instead of the unstable GitHub automatic + tarball for the commit. +1. Modify `vm.go` to update the version number. +1. Modify `MODULE.bazel` to update the version number. +1. Run tests locally, commit, and push to the `go-jsonnet` `prepare-release` branch. CI checks should run + automatically on this branch - check the results in https://github.com/google/go-jsonnet/actions +1. Optionally: Perform a preflight Python build & publish by manually triggering the workflow in GitHub actions. +1. Start a release Python build & publish by manually triggering the workflow in GitHub Actions. + It will wait for an approval before publishing (don't approve it yet). + Check that the Python packages are all built successfully. +1. Manually trigger the Release workflow in GitHub Actions to create a new _draft_ release with all the + built packages attached to it. +1. Fill in the release notes in the GitHub draft release. +1. Do any final release checks (including downloading built packages and checking them locally if you want). +1. Approve the Python publish step and wait for that to complete successfully. +1. Check that the new tag number is correct and click Publish in the GitHub draft release. +1. Fast-forward merge the `prepare-release` branch to `master` and push `master` so that the repo master state + matches the release that was just published. +1. TO BE WRITTEN: Update the Bazel module at https://registry.bazel.build/modules/jsonnet_go. ## Update the website In google/jsonnet: -* Build or download libjsonnet.wasm (see README.md) -* `jekyll serve -s docs/` -* Check that the local version works in two different browsers. Make sure that live evaluation in the tutorial works. -* `tools/scripts/push_docs.sh` -* Check that the public works in two different browsers. Make sure that you are getting the new version (and not an old cached version). Make sure that live evaluation in the tutorial works. + +- Build or download libjsonnet.wasm (see README.md) +- `jekyll serve -s docs/` +- Check that the local version works in two different browsers. Make sure that live evaluation in the tutorial works. +- `tools/scripts/push_docs.sh` +- Check that the public works in two different browsers. Make sure that you are getting the new version (and not an old cached version). Make sure that live evaluation in the tutorial works. ## Make the announcement -* Send an email to the mailing list. -* Announce the new release on Slack. +- Send an email to the mailing list. +- Announce the new release on Slack. ## After the release diff --git a/setup.py b/setup.py index 914b90a37..0c427fc57 100644 --- a/setup.py +++ b/setup.py @@ -41,7 +41,9 @@ def get_version(): """ Parses the version out of libjsonnet.h """ - rx = re.compile(r'^\s*#\s*define\s+LIB_JSONNET_VERSION\s+"v([0-9.]+)"\s*$') + rx = re.compile( + r'^\s*#\s*define\s+LIB_JSONNET_VERSION\s+"v([0-9.]+(?:-?[a-z][a-z0-9]*)?)"\s*$' + ) with open(os.path.join(DIR, "include/libjsonnet.h")) as f: for line in f: m = rx.match(line) @@ -61,20 +63,35 @@ def _pack_std_jsonnet(self): f.write(",".join(str(x) for x in stdlib)) f.write(",0\n\n") - def build_extension(self, ext): + def build_extensions(self): # At this point, the compiler has been chosen so we add compiler-specific flags. # There is unfortunately no built in support for this in setuptools. # Feature request: https://github.com/pypa/setuptools/issues/1819 - - print("Setting compile flags for compiler type " + self.compiler.compiler_type) + print("Adjusting compiler for compiler type " + self.compiler.compiler_type) # This is quite hacky as we're modifying the Extension object itself. if self.compiler.compiler_type == "msvc": - ext.extra_compile_args.append("/std:c++17") + for ext in self.extensions: + ext.extra_compile_args.append("/std:c++17") else: - ext.extra_compile_args.append("-std=c++17") - - # Actually build. - super().build_extension(ext) + # -std=c++17 should only be applied to C++ build, + # not when compiling C source code. Unfortunately, + # the extra_compile_args applies to both. Instead, + # patch the CC/CXX commands in the compiler object. + # + # Note that older versions of distutils/setuptools do not + # have the necessary separation between C and C++ compilers. + # This requires setuptools 72.2. + for v in ("compiler_cxx", "compiler_so_cxx"): + if not hasattr(self.compiler, v): + print( + f"WARNING: cannot adjust flag {v}, " + f"compiler type {self.compiler.compiler_type}, " + f"compiler class {type(self.compiler).__name__}" + ) + continue + current = getattr(self.compiler, v) + self.compiler.set_executable(v, current + ["-std=c++17"]) + super().build_extensions() def run(self): self._pack_std_jsonnet() diff --git a/stdlib/BUILD b/stdlib/BUILD index 06d4ad634..de1c31aa5 100644 --- a/stdlib/BUILD +++ b/stdlib/BUILD @@ -1,16 +1,17 @@ -package(default_visibility = ["//visibility:public"]) +package(default_visibility = ["//visibility:private"]) filegroup( name = "stdlib", srcs = ["std.jsonnet"], + visibility = ["//visibility:public"], ) cc_library( name = "std", - hdrs = ["std.jsonnet.h"], - srcs = [":gen-std-jsonnet-h"], includes = ["."], linkstatic = 1, + textual_hdrs = [":gen-std-jsonnet-h"], + visibility = ["//core:__pkg__"], ) genrule( diff --git a/stdlib/std.jsonnet b/stdlib/std.jsonnet index fccbe26d5..ec7ab8f4d 100644 --- a/stdlib/std.jsonnet +++ b/stdlib/std.jsonnet @@ -261,6 +261,15 @@ limitations under the License. else error 'Operator % cannot be used on types ' + std.type(a) + ' and ' + std.type(b) + '.', + // this is the most precision that will fit in a f64 + pi:: 3.14159265358979311600, + + deg2rad(x):: x * std.pi / 180, + rad2deg(x):: x * 180 / std.pi, + + log2(x):: std.log(x) / std.log(2), + log10(x):: std.log(x) / std.log(10), + map(func, arr):: if !std.isFunction(func) then error ('std.map first param must be function, got ' + std.type(func)) diff --git a/test_cmd/fmt_help.golden.stdout b/test_cmd/fmt_help.golden.stdout index 652f276bc..c9f99312d 100644 --- a/test_cmd/fmt_help.golden.stdout +++ b/test_cmd/fmt_help.golden.stdout @@ -1,4 +1,4 @@ -Jsonnet reformatter v0.20.0 +Jsonnet reformatter v0.21.0 jsonnetfmt {