diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000..eec55ce --- /dev/null +++ b/.bazelrc @@ -0,0 +1,23 @@ +try-import user.bazelrc +try-import .buildbuddy-auth.rc + +test --test_output=errors + +# Build Buddy Cache Setup +build:build_buddy --bes_results_url=https://app.buildbuddy.io/invocation/ +build:build_buddy --bes_backend=grpcs://remote.buildbuddy.io +build:build_buddy --remote_cache=grpcs://remote.buildbuddy.io +build:build_buddy --remote_timeout=3600 + +# Additional suggestions from buildbuddy for speed +build:build_buddy --experimental_remote_cache_compression +build:build_buddy --experimental_remote_cache_compression_threshold=100 +build:build_buddy --noslim_profile +build:build_buddy --experimental_profile_include_target_label +build:build_buddy --experimental_profile_include_primary_output +build:build_buddy --nolegacy_important_outputs + +build:ci --config=build_buddy +build:ci --remote_download_minimal +build:ci --build_metadata=ROLE=CI +build:ci --build_metadata=VISIBILITY=PUBLIC \ No newline at end of file diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000..296f75c --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +7.2.0 diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml new file mode 100644 index 0000000..6966929 --- /dev/null +++ b/.github/workflows/bazel.yml @@ -0,0 +1,35 @@ +# This workflow runs the JSON checker on each vendordep JSON file. + +name: Bazel CI + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the main branch +on: + push: + pull_request: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "run-json-checker" + run-json-checker: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history so we can use git diff + + - name: Maybe setup BuildBuddy key + env: + API_KEY: ${{ secrets.API_KEY }} + if: ${{ env.API_KEY != '' }} + shell: bash + run: | + echo "API Key detected!" + echo "build:build_buddy --remote_header=x-buildbuddy-api-key=${{ env.API_KEY }}" > .buildbuddy-auth.rc + + - name: Run check + run: | + bazel test //... -k --config=ci diff --git a/.gitignore b/.gitignore index 45d62d8..994cc30 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ *.sw? + +bazel-* +user.bazelrc \ No newline at end of file diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000..03293a9 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,39 @@ +load("@rules_python//python:defs.bzl", "py_binary") +load("@rules_python//python:pip.bzl", "compile_pip_requirements") +load("@vendor-json-repo-pip//:requirements.bzl", "requirement") +load("//:test_utils.bzl", "vendordep_check_test") + +# bazel run //:requirements.update +compile_pip_requirements( + name = "requirements", + extra_args = ["--allow-unsafe"], + requirements_in = "requirements.txt", + requirements_txt = "requirements_lock.txt", +) + +py_binary( + name = "check", + srcs = ["check.py"], + visibility = ["//visibility:public"], + deps = [ + requirement("pyelftools"), + requirement("pefile"), + ], +) + +# Change this for local testing only. +cache_directory = None + +[vendordep_check_test( + allowable_errors = 1, + allowable_warnings = None, + cache_directory = cache_directory, + vendor_file = f, +) for f in glob(["2024/*.json"])] + +[vendordep_check_test( + allowable_errors = 0, + allowable_warnings = None, + cache_directory = cache_directory, + vendor_file = f, +) for f in glob(["2025/*.json"])] diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..da785eb --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,25 @@ +module( + name = "vendor-json-repo", + version = "", + compatibility_level = 1, +) + +bazel_dep(name = "rules_python", version = "0.37.0") + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + python_version = "3.10", +) +use_repo(python, "python_versions") + +register_toolchains( + "@python_versions//:all", +) + +pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") +pip.parse( + hub_name = "vendor-json-repo-pip", + python_version = "3.10", + requirements_lock = "//:requirements_lock.txt", +) +use_repo(pip, "vendor-json-repo-pip") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 0000000..09f26d5 --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,131 @@ +{ + "lockFileVersion": 11, + "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.bcr.1/source.json": "14892cc698e02ffedf4967546e6bedb7245015906888d3465fcf27c90a26da10", + "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef", + "https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015", + "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.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.6.1/source.json": "082ed5f9837901fada8c68c2f3ddc958bb22b6d654f71dd73f3df30d45d4b749", + "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/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.14.0/source.json": "2478949479000fdd7de9a3d0107ba2c85bb5f961c3ecb1aa448f52549ce310b5", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/0.0.9/source.json": "cd74d854bf16a9e002fb2ca7b1a421f4403cda29f824a765acd3a8c56f8d43e6", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/24.4/source.json": "ace4b8c65d4cfe64efe544f09fc5e5df77faf3a67fbb29c5341e0d755d9b15d6", + "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/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1", + "https://bcr.bazel.build/modules/rules_java/7.6.5/source.json": "a805b889531d1690e3c72a7a7e47a870d00323186a9904b36af83aa3d053ee8d", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/source.json": "10572111995bc349ce31c78f74b3c147f6b3233975c7fa5eff9211f6db0d34d9", + "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/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/source.json": "8d8448e71706df7450ced227ca6b3812407ff5e2ccad74a43a9fbe79c84e34e0", + "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.37.0/MODULE.bazel": "bd90c62e4c789ea94ed61ab21a5a538dd4145548d1de994192049652d433816e", + "https://bcr.bazel.build/modules/rules_python/0.37.0/source.json": "c17b8ca7a2348fd8fa96ad5b414223dd1ce5d6e8265c3134a88d337b0554d53c", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "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.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.6.2/source.json": "d2ff8063b63b4a85e65fe595c4290f99717434fa9f95b4748a79a7d04dfed349", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/source.json": "b2150404947339e8b947c6b16baa39fa75657f4ddec5e37272c7b11c7ab533bc", + "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" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": { + "general": { + "bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=", + "usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_apple_cc": { + "bzlFile": "@@apple_support~//crosstool:setup.bzl", + "ruleClassName": "_apple_cc_autoconf", + "attributes": {} + }, + "local_config_apple_cc_toolchains": { + "bzlFile": "@@apple_support~//crosstool:setup.bzl", + "ruleClassName": "_apple_cc_autoconf_toolchains", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [ + [ + "apple_support~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@platforms//host:extension.bzl%host_platform": { + "general": { + "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", + "usagesDigest": "meSzxn3DUCcYEhq4HQwExWkWtU4EjriRBQLsZN+Q0SU=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "host_platform": { + "bzlFile": "@@platforms//host:extension.bzl", + "ruleClassName": "host_platform_repo", + "attributes": {} + } + }, + "recordedRepoMappingEntries": [] + } + } + } +} diff --git a/README.md b/README.md index dd8d8bc..01b4f14 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,11 @@ Currently only one option is supported: `no_debug_suffix`. Normally debug libra The check.py script requires the `pyelftools` and `pefile` dependencies be installed; use `pip3 install` to install these. +## Bazel Testing +Pyunit tests are automatically auto generated run using the checker tool against all of the vendordep json files in the repository by bazel. + +### Prerequisites +- Install [Bazelisk](https://github.com/bazelbuild/bazelisk/releases) and add it to your path. Bazelisk is a wrapper that will download the correct version of bazel specified in the repository. Note: You can alias/rename the binary to `bazel` if you want to keep the familiar `bazel build` vs `bazelisk build` syntax. + +### Running the tests +To run the tests, simply run `bazel test //...`. Alternatively, you can run the `checker.py` tool in a standalone mode by running `bazel run //:checker -- ` diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 0000000..e69de29 diff --git a/check.py b/check.py index 1ad1358..6d9d79e 100755 --- a/check.py +++ b/check.py @@ -9,6 +9,7 @@ import sys import urllib.request import uuid +import pathlib from zipfile import ZipFile, BadZipFile try: @@ -38,6 +39,7 @@ got_error = 0 got_warn = 0 message_context = [] +cache_directory = None def msg(t, s): ctx = ': '.join(message_context) + ': ' if message_context else '' @@ -64,19 +66,21 @@ def info(s): local_maven = None year = "2025" -def parse_args(): +def parse_args(argv): """Parse command line arguments. Returns list of filenames.""" parser = argparse.ArgumentParser(description='Checks a vendor json file') parser.add_argument('--verbose', '-v', action='count', help='increase the verbosity of output') parser.add_argument('--local-maven', help='directory to use for artifacts instead of fetching from mavenUrls') parser.add_argument('--year', '-y', help='FRC competition season year (used to set known libraries)') + parser.add_argument('--cache_directory', type=pathlib.Path, help='Optional. If present will set up a download cache in this directory to prevent re-downloading artifacts. Should be used for debugging purposes only.') parser.add_argument('file', nargs='+', help='json file to parse') - args = parser.parse_args() + args = parser.parse_args(argv) - global verbose, local_maven, year + global verbose, local_maven, year, cache_directory verbose = args.verbose or 0 local_maven = args.local_maven year = args.year or "2025" + cache_directory = args.cache_directory return args.file @@ -208,11 +212,22 @@ def fetch(self, classifier, failok=False): else: for baseurl in self.urls: url = baseurl + self.path + fn + maybe_cached_file = None + if cache_directory: + maybe_cached_file = cache_directory / (self.path + fn) + if maybe_cached_file.exists(): + if verbose >= 2: + print(f"Found a cache hit for {maybe_cached_file}") + return fn, maybe_cached_file.read_bytes() + if verbose >= 1: print('downloading "{0}"'.format(url)) try: with urlopener.open(url) as f: result = f.read() + if maybe_cached_file: + maybe_cached_file.parent.mkdir(parents=True, exist_ok=True) + maybe_cached_file.write_bytes(result) except urllib.error.HTTPError as e: if not failok: warn('could not fetch url "{0}": {1}'.format(url, e)) @@ -629,7 +644,7 @@ def check_file(filename): def main(): had_errors = False - for fn in parse_args(): + for fn in parse_args(sys.argv[1:]): global json_filename, got_error, got_warn json_filename = fn got_error = 0 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fe5960d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pyelftools +pefile \ No newline at end of file diff --git a/requirements_lock.txt b/requirements_lock.txt new file mode 100644 index 0000000..04fb3cc --- /dev/null +++ b/requirements_lock.txt @@ -0,0 +1,14 @@ +# +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: +# +# bazel run //:requirements.update +# +pefile==2024.8.26 \ + --hash=sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632 \ + --hash=sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f + # via -r requirements.txt +pyelftools==0.31 \ + --hash=sha256:c774416b10310156879443b81187d182d8d9ee499660380e645918b50bc88f99 \ + --hash=sha256:f52de7b3c7e8c64c8abc04a79a1cf37ac5fb0b8a49809827130b858944840607 + # via -r requirements.txt diff --git a/test_utils.bzl b/test_utils.bzl new file mode 100644 index 0000000..c8e94c6 --- /dev/null +++ b/test_utils.bzl @@ -0,0 +1,72 @@ +load("@rules_python//python:defs.bzl", "py_test") + +def vendordep_check_test(vendor_file, allowable_warnings = 0, allowable_errors = 0, verbosity_level = "-v", cache_directory = None): + file_no_extension = vendor_file[:-5] + gen_name = file_no_extension + ".gen" + test_file_base = file_no_extension + "_test" + test_file_name = test_file_base + ".py" + + cache_replacement = "" + if cache_directory: + cache_replacement = 'args.append("--cache_directory=' + cache_directory + '")' + + verbosity_replacement = "" + if verbosity_level: + verbosity_replacement = 'args.append("' + verbosity_level + '")' + + test_contents = """ + +import unittest +from check import check_file, parse_args, file_config + +class VendordepCheck(unittest.TestCase): + def test_check(self): + vendor_file = "{vendor_file}" + warnings_allowed = {allowable_warnings} + errors_allowed = {allowable_errors} + + args = [vendor_file] + + {verbosity_replacement} + {cache_replacement} + + parse_args(args) + file_config.load(vendor_file) + check_file(vendor_file) + + from check import got_error, got_warn + + print(f"Errors: {{got_error}}") + print(f"Warnings: {{got_warn}}") + + if errors_allowed is not None: + self.assertEqual(errors_allowed, got_error) + + if warnings_allowed is not None: + self.assertEqual(warnings_allowed, got_warn) + + +if __name__ == "__main__": + unittest.main() # run all tests + + + +""".format( + vendor_file = vendor_file, + allowable_warnings = allowable_warnings, + allowable_errors = allowable_errors, + cache_replacement = cache_replacement, + verbosity_replacement = verbosity_replacement, + ) + + native.genrule( + name = gen_name, + outs = [test_file_name], + cmd = "echo '{}' >> $@".format(test_contents), + ) + py_test( + name = test_file_base, + srcs = [test_file_name], + deps = ["//:check"], + data = [vendor_file], + )