From 71bec2274b2c8f2011934d32d6609fcbede8820f Mon Sep 17 00:00:00 2001 From: Honnix Date: Wed, 23 Oct 2024 01:49:16 +0200 Subject: [PATCH] feat: Set up ktfmt to format code (#247) * feat: Set up ktfmt to format code * Actually format code --- BUILD | 5 + MODULE.bazel | 4 + MODULE.bazel.lock | 1258 ++++++++++++++++- WORKSPACE | 14 + cli/BUILD | 16 +- cli/src/main/kotlin/com/bazel_diff/Main.kt | 14 +- .../com/bazel_diff/bazel/BazelClient.kt | 94 +- .../com/bazel_diff/bazel/BazelQueryService.kt | 230 +-- .../kotlin/com/bazel_diff/bazel/BazelRule.kt | 90 +- .../com/bazel_diff/bazel/BazelTarget.kt | 68 +- .../com/bazel_diff/bazel/BazelTargetType.kt | 7 +- .../kotlin/com/bazel_diff/cli/BazelDiff.kt | 44 +- .../bazel_diff/cli/GenerateHashesCommand.kt | 386 ++--- .../cli/GetImpactedTargetsCommand.kt | 172 ++- .../com/bazel_diff/cli/VersionProvider.kt | 18 +- .../converter/CommaSeparatedValueConverter.kt | 6 +- .../cli/converter/NormalisingPathConverter.kt | 4 +- .../cli/converter/OptionsConverter.kt | 6 +- .../main/kotlin/com/bazel_diff/di/Modules.kt | 108 +- .../com/bazel_diff/extensions/ByteArray.kt | 14 +- .../com/bazel_diff/extensions/ByteBuffer.kt | 5 +- .../extensions/HashingExtensions.kt | 30 +- .../com/bazel_diff/hash/BuildGraphHasher.kt | 255 ++-- .../bazel_diff/hash/ExternalRepoResolver.kt | 88 +- .../kotlin/com/bazel_diff/hash/RuleHasher.kt | 147 +- .../com/bazel_diff/hash/SourceFileHasher.kt | 213 +-- .../com/bazel_diff/hash/TargetDigest.kt | 68 +- .../kotlin/com/bazel_diff/hash/TargetHash.kt | 54 +- .../com/bazel_diff/hash/TargetHasher.kt | 111 +- .../CalculateImpactedTargetsInteractor.kt | 237 ++-- .../interactor/DeserialiseHashesInteractor.kt | 60 +- .../interactor/GenerateHashesInteractor.kt | 110 +- .../bazel_diff/interactor/TargetTypeFilter.kt | 27 +- .../bazel_diff/io/ByteBufferObjectFactory.kt | 32 +- .../com/bazel_diff/io/ByteBufferPool.kt | 20 +- .../com/bazel_diff/io/ContentHashProvider.kt | 12 +- .../kotlin/com/bazel_diff/log/StderrLogger.kt | 41 +- .../kotlin/com/bazel_diff/process/Process.kt | 110 +- .../kotlin/com/bazel_diff/process/Redirect.kt | 86 +- cli/src/test/kotlin/com/bazel_diff/Modules.kt | 39 +- .../com/bazel_diff/bazel/BazelRuleTest.kt | 71 +- .../CommaSeparatedValueConverterTest.kt | 10 +- .../converter/NormalisingPathConverterTest.kt | 12 +- .../cli/converter/OptionsConverterTest.kt | 10 +- .../test/kotlin/com/bazel_diff/e2e/E2ETest.kt | 1151 +++++++++------ .../bazel_diff/hash/BuildGraphHasherTest.kt | 598 ++++---- .../bazel_diff/hash/FakeSourceFileHasher.kt | 31 +- .../kotlin/com/bazel_diff/hash/HashDiffer.kt | 49 +- .../bazel_diff/hash/SourceFileHasherTest.kt | 369 ++--- .../com/bazel_diff/hash/TargetHashTest.kt | 55 +- .../CalculateImpactedTargetsInteractorTest.kt | 396 +++--- .../DeserialiseHashesInteractorTest.kt | 60 +- .../bazel_diff/io/ContentHashProviderTest.kt | 66 +- extensions.bzl | 6 + repositories.bzl | 16 + 55 files changed, 4430 insertions(+), 2773 deletions(-) create mode 100644 extensions.bzl diff --git a/BUILD b/BUILD index def9d414..8616f8d8 100644 --- a/BUILD +++ b/BUILD @@ -2,3 +2,8 @@ alias( name = "bazel-diff", actual = "//cli:bazel-diff", ) + +alias( + name = "format", + actual = "//cli:format", +) diff --git a/MODULE.bazel b/MODULE.bazel index 4bee70c9..b5907d06 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -4,6 +4,7 @@ module( compatibility_level = 0, ) +bazel_dep(name = "aspect_rules_lint", version = "1.0.2") bazel_dep(name = "bazel_skylib", version = "1.6.1") bazel_dep(name = "rules_proto", version = "6.0.0-rc2") bazel_dep(name = "rules_java", version = "7.6.5") @@ -31,3 +32,6 @@ use_repo( maven, bazel_diff_maven = "bazel_diff_maven", ) + +non_module_repositories = use_extension("//:extensions.bzl", "non_module_repositories") +use_repo(non_module_repositories, "ktfmt") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 60b83946..9af7e57b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -7,19 +7,39 @@ "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/source.json": "7e3a9adf473e9af076ae485ed649d5641ad50ec5c11718103f34de03170d94ad", "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/aspect_bazel_lib/1.31.2/MODULE.bazel": "7bee702b4862612f29333590f4b658a5832d433d6f8e4395f090e8f4e85d442f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.38.0/MODULE.bazel": "6307fec451ba9962c1c969eb516ebfe1e46528f7fa92e1c9ac8646bef4cdaa3f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.42.2/MODULE.bazel": "2e0d8ab25c57a14f56ace1c8e881b69050417ff91b2fb7718dc00d201f3c3478", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/source.json": "87f12b449cd1d27d3e83840a59a6966d557e7c3c5f19e7b2e0361da5edc6b397", + "https://bcr.bazel.build/modules/aspect_rules_js/1.33.1/MODULE.bazel": "db3e7f16e471cf6827059d03af7c21859e7a0d2bc65429a3a11f005d46fc501b", + "https://bcr.bazel.build/modules/aspect_rules_js/1.40.0/MODULE.bazel": "01a1014e95e6816b68ecee2584ae929c7d6a1b72e4333ab1ff2d2c6c30babdf1", + "https://bcr.bazel.build/modules/aspect_rules_js/1.40.0/source.json": "b6fd491369e9ef888fdef64b839023a2360caaea8eb370d2cfbfdd2a96721311", + "https://bcr.bazel.build/modules/aspect_rules_lint/0.12.0/MODULE.bazel": "e767c5dbfeb254ec03275a7701b5cfde2c4d2873676804bc7cb27ddff3728fed", + "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/MODULE.bazel": "40111d1065049288fa89a8dfb90b47cf157bf5de4636c44dd124f5a7f56626eb", + "https://bcr.bazel.build/modules/aspect_rules_lint/1.0.2/source.json": "30918b78facc191e69caf2584a8286f19943d09fc48606e7b1502113d8015799", + "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd", + "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.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015", "https://bcr.bazel.build/modules/bazel_features/1.2.0/MODULE.bazel": "122b2b606622afbaa498913d54f52d9bcd2d19a5edd1bd6d6c5aa17441c4d5f9", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", "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.6.1/source.json": "082ed5f9837901fada8c68c2f3ddc958bb22b6d654f71dd73f3df30d45d4b749", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.1.2/MODULE.bazel": "2ef4962c8b0b6d8d21928a89190755619254459bc67f870dc0ccb9ba9952d444", + "https://bcr.bazel.build/modules/buildifier_prebuilt/6.1.2/source.json": "19fb45ed3f0d55cbff94e402c39512940833ae3a68f9cbfd9518a1926b609c7c", "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/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", + "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.11.0/source.json": "c73d9ef4268c91bd0c1cd88f1f9dfa08e814b1dbe89b5f594a9f08ba0244d206", "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", @@ -32,13 +52,20 @@ "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", "https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b", "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/rules_buf/0.1.1/MODULE.bazel": "6189aec18a4f7caff599ad41b851ab7645d4f1e114aa6431acf9b0666eb92162", + "https://bcr.bazel.build/modules/rules_buf/0.1.1/source.json": "021363d254f7438f3f10725355969c974bb2c67e0c28667782ade31a9cdb747f", "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.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_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", + "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", + "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", @@ -55,21 +82,33 @@ "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_multirun/0.9.0/MODULE.bazel": "32d628ef586b5b23f67e55886b7bc38913ea4160420d66ae90521dda2ff37df0", + "https://bcr.bazel.build/modules/rules_multirun/0.9.0/source.json": "e882ba77962fa6c5fe68619e5c7d0374ec9a219fb8d03c42eadaf6d0243771bd", + "https://bcr.bazel.build/modules/rules_multitool/0.4.0/MODULE.bazel": "15517987d5c00c9e7faab41fbe22ee67a350b6eabcc1e08baded5c6d9025897f", + "https://bcr.bazel.build/modules/rules_multitool/0.4.0/source.json": "d73b450b7c6d9683e400d6cebc463fbc2b870cc5d8e2e75080d6278805aaab08", + "https://bcr.bazel.build/modules/rules_nodejs/5.8.2/MODULE.bazel": "6bc03c8f37f69401b888023bf511cb6ee4781433b0cb56236b2e55a21e3a026a", + "https://bcr.bazel.build/modules/rules_nodejs/5.8.2/source.json": "6e82cf5753d835ea18308200bc79b9c2e782efe2e2a4edc004a9162ca93382ca", "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-rc2/MODULE.bazel": "e17f94f8a347e2c808517b65d74988839d2d62daceb50073e44060193b785eb1", - "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc2/source.json": "0c0e473bc88cb9eab9e8dd98d2dae51b2190d2f8ab7d55c519b1439c4a7fa9a0", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/source.json": "de77e10ff0ab16acbf54e6b46eecd37a99c5b290468ea1aee6e95eb1affdaed7", "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.23.1/source.json": "a6d9965700e3bd75df4e19140c0e651851bb720d8b9eb280ecd1ee44b92d7646", + "https://bcr.bazel.build/modules/rules_python/0.27.1/MODULE.bazel": "65dc875cc1a06c30d5bbdba7ab021fd9e551a6579e408a3943a61303e2228a53", + "https://bcr.bazel.build/modules/rules_python/0.27.1/source.json": "88980dfdcf0651a11344cad2ab1f962ea1b0e51edc80ebbae274c8fa9cde78f4", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/stardoc/0.5.0/MODULE.bazel": "f9f1f46ba8d9c3362648eea571c6f9100680efc44913618811b58cc9c02cd678", "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", "https://bcr.bazel.build/modules/stardoc/0.5.6/source.json": "956954c9c45ef492ea4001ce579dc40431fbd75090151e8f9eadf9ed6377a108", + "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/MODULE.bazel": "2f08433ff5e659069b3a1abfee2377d68f510f2de1da50678ed992c455b4ff91", + "https://bcr.bazel.build/modules/toolchains_protoc/0.2.1/source.json": "4ee6b007b62e1b9e493b00ccc60e61a258633f304b74813b6e7f7234927be94c", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", @@ -79,6 +118,37 @@ }, "selectedYankedVersions": {}, "moduleExtensions": { + "//:extensions.bzl%non_module_repositories": { + "general": { + "bzlTransitiveDigest": "9kscpNTrmoEECh40kS6bqcncGbg5lZ8bpWLxD8wpc2Q=", + "usagesDigest": "ejjWPqMitcgyuDICIqqUvoCye7p0Q38k82XOu8kAoAQ=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "ktfmt": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_jar", + "attributes": { + "integrity": "sha256-l/x/vRlNAan6RdgUfAVSQDAD1VusSridhNe7TV4/SN4=", + "url": "https://repo1.maven.org/maven2/com/facebook/ktfmt/0.46/ktfmt-0.46-jar-with-dependencies.jar" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "", + "aspect_rules_lint", + "aspect_rules_lint~" + ], + [ + "aspect_rules_lint~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": { "general": { "bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=", @@ -100,7 +170,624 @@ }, "recordedRepoMappingEntries": [ [ - "apple_support~", + "apple_support~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@aspect_bazel_lib~//lib:extensions.bzl%toolchains": { + "general": { + "bzlTransitiveDigest": "3KydN9M+cGcn8Huu/umxX7Vk08sXz5lJeUxg/b0Gxjc=", + "usagesDigest": "etSUcoim8Uj/Ts6I8eFyHYfm61gZD3lHtiVtIuQ89v0=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "expand_template_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "copy_to_directory_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "jq_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_platform_repo", + "attributes": { + "platform": "darwin_amd64", + "version": "1.7" + } + }, + "copy_to_directory_freebsd_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "freebsd_amd64" + } + }, + "expand_template_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "jq_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_platform_repo", + "attributes": { + "platform": "linux_arm64", + "version": "1.7" + } + }, + "coreutils_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_platform_repo", + "attributes": { + "platform": "darwin_arm64", + "version": "0.0.26" + } + }, + "copy_to_directory_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "bsd_tar_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "bsdtar_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "copy_directory_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "coreutils_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_platform_repo", + "attributes": { + "platform": "darwin_amd64", + "version": "0.0.26" + } + }, + "coreutils_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_platform_repo", + "attributes": { + "platform": "linux_arm64", + "version": "0.0.26" + } + }, + "zstd_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:zstd_toolchain.bzl", + "ruleClassName": "zstd_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "yq_linux_s390x": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "linux_s390x", + "version": "4.25.2" + } + }, + "yq": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_host_alias_repo", + "attributes": {} + }, + "expand_template_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "copy_directory_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "jq_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_platform_repo", + "attributes": { + "platform": "darwin_arm64", + "version": "1.7" + } + }, + "yq_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "darwin_amd64", + "version": "4.25.2" + } + }, + "copy_directory_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "expand_template_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_toolchains_repo", + "attributes": { + "user_repository_name": "expand_template" + } + }, + "bats_assert": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "98ca3b685f8b8993e48ec057565e6e2abcc541034ed5b0e81f191505682037fd", + "urls": [ + "https://github.com/bats-core/bats-assert/archive/v2.1.0.tar.gz" + ], + "strip_prefix": "bats-assert-2.1.0", + "build_file_content": "load(\"@aspect_bazel_lib//lib:copy_to_directory.bzl\", \"copy_to_directory\")\n\ncopy_to_directory(\n name = \"assert\",\n hardlink = \"on\",\n srcs = glob([\n \"src/**\",\n \"load.bash\",\n ]),\n out = \"bats-assert\",\n visibility = [\"//visibility:public\"]\n)\n" + } + }, + "copy_to_directory_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "zstd_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:zstd_toolchain.bzl", + "ruleClassName": "zstd_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "bsdtar_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "yq_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_toolchains_repo", + "attributes": { + "user_repository_name": "yq" + } + }, + "zstd_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:zstd_toolchain.bzl", + "ruleClassName": "zstd_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "bats_support": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "7815237aafeb42ddcc1b8c698fc5808026d33317d8701d5ec2396e9634e2918f", + "urls": [ + "https://github.com/bats-core/bats-support/archive/v0.3.0.tar.gz" + ], + "strip_prefix": "bats-support-0.3.0", + "build_file_content": "load(\"@aspect_bazel_lib//lib:copy_to_directory.bzl\", \"copy_to_directory\")\n\ncopy_to_directory(\n name = \"support\",\n hardlink = \"on\",\n srcs = glob([\n \"src/**\",\n \"load.bash\",\n ]),\n out = \"bats-support\",\n visibility = [\"//visibility:public\"]\n)\n" + } + }, + "bsd_tar_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "bsdtar_binary_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "jq": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_host_alias_repo", + "attributes": {} + }, + "expand_template_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "bsdtar_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "copy_to_directory_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "coreutils_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_platform_repo", + "attributes": { + "platform": "linux_amd64", + "version": "0.0.26" + } + }, + "copy_directory_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_toolchains_repo", + "attributes": { + "user_repository_name": "copy_directory" + } + }, + "yq_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "linux_amd64", + "version": "4.25.2" + } + }, + "copy_to_directory_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_platform_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "coreutils_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_toolchains_repo", + "attributes": { + "user_repository_name": "coreutils" + } + }, + "copy_directory_freebsd_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "freebsd_amd64" + } + }, + "zstd_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:zstd_toolchain.bzl", + "ruleClassName": "zstd_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "zstd_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:zstd_toolchain.bzl", + "ruleClassName": "zstd_toolchains_repo", + "attributes": { + "user_repository_name": "zstd" + } + }, + "bats_file": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "9b69043241f3af1c2d251f89b4fcafa5df3f05e97b89db18d7c9bdf5731bb27a", + "urls": [ + "https://github.com/bats-core/bats-file/archive/v0.4.0.tar.gz" + ], + "strip_prefix": "bats-file-0.4.0", + "build_file_content": "load(\"@aspect_bazel_lib//lib:copy_to_directory.bzl\", \"copy_to_directory\")\n\ncopy_to_directory(\n name = \"file\",\n hardlink = \"on\",\n srcs = glob([\n \"src/**\",\n \"load.bash\",\n ]),\n out = \"bats-file\",\n visibility = [\"//visibility:public\"]\n)\n" + } + }, + "expand_template_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "jq_linux_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_platform_repo", + "attributes": { + "platform": "linux_amd64", + "version": "1.7" + } + }, + "bsd_tar_darwin_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "bsdtar_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "bsd_tar_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:tar_toolchain.bzl", + "ruleClassName": "tar_toolchains_repo", + "attributes": { + "user_repository_name": "bsd_tar" + } + }, + "bats_toolchains": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "sha256": "a1a9f7875aa4b6a9480ca384d5865f1ccf1b0b1faead6b47aa47d79709a5c5fd", + "urls": [ + "https://github.com/bats-core/bats-core/archive/v1.10.0.tar.gz" + ], + "strip_prefix": "bats-core-1.10.0", + "build_file_content": "load(\"@local_config_platform//:constraints.bzl\", \"HOST_CONSTRAINTS\")\nload(\"@aspect_bazel_lib//lib/private:bats_toolchain.bzl\", \"bats_toolchain\")\nload(\"@aspect_bazel_lib//lib:copy_to_directory.bzl\", \"copy_to_directory\")\n\ncopy_to_directory(\n name = \"core\",\n hardlink = \"on\",\n srcs = glob([\n \"lib/**\",\n \"libexec/**\"\n ]) + [\"bin/bats\"],\n out = \"bats-core\",\n)\n\nbats_toolchain(\n name = \"toolchain\",\n core = \":core\",\n libraries = [\"@bats_support//:support\", \"@bats_assert//:assert\", \"@bats_file//:file\"]\n)\n\ntoolchain(\n name = \"bats_toolchain\",\n exec_compatible_with = HOST_CONSTRAINTS,\n toolchain = \":toolchain\",\n toolchain_type = \"@aspect_bazel_lib//lib:bats_toolchain_type\",\n)\n" + } + }, + "yq_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "windows_amd64", + "version": "4.25.2" + } + }, + "jq_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_platform_repo", + "attributes": { + "platform": "windows_amd64", + "version": "1.7" + } + }, + "expand_template_freebsd_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:expand_template_toolchain.bzl", + "ruleClassName": "expand_template_platform_repo", + "attributes": { + "platform": "freebsd_amd64" + } + }, + "yq_linux_ppc64le": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "linux_ppc64le", + "version": "4.25.2" + } + }, + "copy_to_directory_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_to_directory_toolchain.bzl", + "ruleClassName": "copy_to_directory_toolchains_repo", + "attributes": { + "user_repository_name": "copy_to_directory" + } + }, + "jq_toolchains": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:jq_toolchain.bzl", + "ruleClassName": "jq_toolchains_repo", + "attributes": { + "user_repository_name": "jq" + } + }, + "copy_directory_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "copy_directory_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:copy_directory_toolchain.bzl", + "ruleClassName": "copy_directory_platform_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "yq_darwin_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "darwin_arm64", + "version": "4.25.2" + } + }, + "coreutils_windows_amd64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:coreutils_toolchain.bzl", + "ruleClassName": "coreutils_platform_repo", + "attributes": { + "platform": "windows_amd64", + "version": "0.0.26" + } + }, + "yq_linux_arm64": { + "bzlFile": "@@aspect_bazel_lib~//lib/private:yq_toolchain.bzl", + "ruleClassName": "yq_platform_repo", + "attributes": { + "platform": "linux_arm64", + "version": "4.25.2" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib~", + "aspect_bazel_lib", + "aspect_bazel_lib~" + ], + [ + "aspect_bazel_lib~", + "bazel_skylib", + "bazel_skylib~" + ], + [ + "aspect_bazel_lib~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@buildifier_prebuilt~//:defs.bzl%buildifier_prebuilt_deps_extension": { + "general": { + "bzlTransitiveDigest": "cnU/K9IY/VeHcxnGaL5eLuX+z8qIjt0yUjs2dZfB3Rc=", + "usagesDigest": "dJKWOSZZDy7RHc2XG1O6ezkxcNMSeKBpUqAz2pk8cbY=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "buildozer_darwin_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-darwin-amd64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "4014751a4cc5e91a7dc4b64be7b30c565bd9014ae6d1879818dc624562a1d431" + } + }, + "buildifier_linux_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-linux-amd64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "51bc947dabb7b14ec6fb1224464fbcf7a7cb138f1a10a3b328f00835f72852ce" + } + }, + "buildozer_darwin_arm64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-darwin-arm64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "e78bd5357f2356067d4b0d49ec4e4143dd9b1308746afc6ff11b55b952f462d7" + } + }, + "buildozer_linux_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-linux-amd64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "2aef0f1ef80a0140b8fe6e6a8eb822e14827d8855bfc6681532c7530339ea23b" + } + }, + "buildozer_windows_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-windows-amd64.exe" + ], + "downloaded_file_path": "buildozer.exe", + "executable": true, + "sha256": "07664d5d08ee099f069cd654070cabf2708efaae9f52dc83921fa400c67a868b" + } + }, + "buildozer_linux_arm64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildozer-linux-arm64" + ], + "downloaded_file_path": "buildozer", + "executable": true, + "sha256": "586e27630cbc242e8bd6fe8e24485eca8dcadea6410cc13cbe059202655980ac" + } + }, + "buildifier_windows_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-windows-amd64.exe" + ], + "downloaded_file_path": "buildifier.exe", + "executable": true, + "sha256": "92bdd284fbc6766fc3e300b434ff9e68ac4d76a06cb29d1bdefe79a102a8d135" + } + }, + "buildifier_prebuilt_toolchains": { + "bzlFile": "@@buildifier_prebuilt~//:defs.bzl", + "ruleClassName": "_buildifier_toolchain_setup", + "attributes": { + "assets_json": "[{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"e2f4a67691c5f55634fbfb3850eb97dd91be0edd059d947b6c83d120682e0216\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"7549b5f535219ac957aa2a6069d46fbfc9ea3f74abd85fd3d460af4b1a2099a6\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"51bc947dabb7b14ec6fb1224464fbcf7a7cb138f1a10a3b328f00835f72852ce\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"0ba6e8e3208b5a029164e542ddb5509e618f87b639ffe8cc2f54770022853080\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"windows\",\"sha256\":\"92bdd284fbc6766fc3e300b434ff9e68ac4d76a06cb29d1bdefe79a102a8d135\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"4014751a4cc5e91a7dc4b64be7b30c565bd9014ae6d1879818dc624562a1d431\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"e78bd5357f2356067d4b0d49ec4e4143dd9b1308746afc6ff11b55b952f462d7\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"2aef0f1ef80a0140b8fe6e6a8eb822e14827d8855bfc6681532c7530339ea23b\",\"version\":\"v6.1.2\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"586e27630cbc242e8bd6fe8e24485eca8dcadea6410cc13cbe059202655980ac\",\"version\":\"v6.1.2\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"windows\",\"sha256\":\"07664d5d08ee099f069cd654070cabf2708efaae9f52dc83921fa400c67a868b\",\"version\":\"v6.1.2\"}]" + } + }, + "buildifier_darwin_amd64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-darwin-amd64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "e2f4a67691c5f55634fbfb3850eb97dd91be0edd059d947b6c83d120682e0216" + } + }, + "buildifier_darwin_arm64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-darwin-arm64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "7549b5f535219ac957aa2a6069d46fbfc9ea3f74abd85fd3d460af4b1a2099a6" + } + }, + "buildifier_linux_arm64": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_file", + "attributes": { + "urls": [ + "https://github.com/bazelbuild/buildtools/releases/download/v6.1.2/buildifier-linux-arm64" + ], + "downloaded_file_path": "buildifier", + "executable": true, + "sha256": "0ba6e8e3208b5a029164e542ddb5509e618f87b639ffe8cc2f54770022853080" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "buildifier_prebuilt~", + "bazel_skylib", + "bazel_skylib~" + ], + [ + "buildifier_prebuilt~", "bazel_tools", "bazel_tools" ] @@ -124,10 +811,35 @@ "recordedRepoMappingEntries": [] } }, + "@@rules_buf~//buf:extensions.bzl%ext": { + "general": { + "bzlTransitiveDigest": "gmPmM7QT5Jez2VVFcwbbMf/QWSRag+nJ1elFJFFTcn0=", + "usagesDigest": "h/C6mQFlmGdKnhVtzeaMHQFgfJmI8JO3uDmuBWGy5PA=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "rules_buf_toolchains": { + "bzlFile": "@@rules_buf~//buf/internal:toolchain.bzl", + "ruleClassName": "buf_download_releases", + "attributes": { + "version": "v1.27.0" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_buf~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, "@@rules_jvm_external~//:extensions.bzl%maven": { "general": { "bzlTransitiveDigest": "aME0tyUxYd+PGhICmzT9zEnIgZNf05hZhsfDD5v0JXM=", - "usagesDigest": "RiESu1RzypJ/tRsAUBEwT8uAvAL02bjB08j6rSK2pT8=", + "usagesDigest": "geYwYc8WoHCKRf1SyKGOPa0WlCCzxl3cSi/qy3CJRB8=", "recordedFileInputs": { "@@rules_jvm_external~//rules_jvm_external_deps_install.json": "cafb5d2d8119391eb2b322ce3840d3352ea82d496bdb8cbd4b6779ec4d044dda", "@@//maven_install.json": "8ab3e635bbd52fcff5900e530933fbdc41c45d1d5b2a2aef8af1becf7a7d0784" @@ -1972,45 +2684,234 @@ ] } }, + "@@rules_multitool~//multitool:extension.bzl%multitool": { + "general": { + "bzlTransitiveDigest": "AtvPzG/SAawYMKVVHcMoJq4EXkVPTIhS3AeNwENXp9E=", + "usagesDigest": "ntSFE9kgfM8zeXNZCDVEmJVNI5vnwPelcaddTjO5Tps=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "multitool.linux_x86_64": { + "bzlFile": "@@rules_multitool~//multitool/private:multitool.bzl", + "ruleClassName": "_env_specific_tools", + "attributes": { + "lockfiles": [ + "@@aspect_rules_lint~//format:multitool.lock.json", + "@@aspect_rules_lint~//lint:multitool.lock.json" + ], + "os": "linux", + "cpu": "x86_64" + } + }, + "multitool.linux_arm64": { + "bzlFile": "@@rules_multitool~//multitool/private:multitool.bzl", + "ruleClassName": "_env_specific_tools", + "attributes": { + "lockfiles": [ + "@@aspect_rules_lint~//format:multitool.lock.json", + "@@aspect_rules_lint~//lint:multitool.lock.json" + ], + "os": "linux", + "cpu": "arm64" + } + }, + "multitool.macos_x86_64": { + "bzlFile": "@@rules_multitool~//multitool/private:multitool.bzl", + "ruleClassName": "_env_specific_tools", + "attributes": { + "lockfiles": [ + "@@aspect_rules_lint~//format:multitool.lock.json", + "@@aspect_rules_lint~//lint:multitool.lock.json" + ], + "os": "macos", + "cpu": "x86_64" + } + }, + "multitool.macos_arm64": { + "bzlFile": "@@rules_multitool~//multitool/private:multitool.bzl", + "ruleClassName": "_env_specific_tools", + "attributes": { + "lockfiles": [ + "@@aspect_rules_lint~//format:multitool.lock.json", + "@@aspect_rules_lint~//lint:multitool.lock.json" + ], + "os": "macos", + "cpu": "arm64" + } + }, + "multitool": { + "bzlFile": "@@rules_multitool~//multitool/private:multitool.bzl", + "ruleClassName": "_multitool_hub", + "attributes": { + "lockfiles": [ + "@@aspect_rules_lint~//format:multitool.lock.json", + "@@aspect_rules_lint~//lint:multitool.lock.json" + ] + } + } + }, + "recordedRepoMappingEntries": [] + } + }, + "@@rules_nodejs~//nodejs:extensions.bzl%node": { + "general": { + "bzlTransitiveDigest": "liNCpme8abwnUcdsL6FZlbuEqQRiO4GmDTZyX6QuOH4=", + "usagesDigest": "PK17kgVNa/ZEIu96GAPHuB82/W4Xn4BTFA07oJviqKE=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "nodejs_host": { + "bzlFile": "@@rules_nodejs~//nodejs/private:nodejs_repo_host_os_alias.bzl", + "ruleClassName": "nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_linux_s390x": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "linux_s390x", + "node_version": "16.19.0" + } + }, + "nodejs_windows_amd64": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "windows_amd64", + "node_version": "16.19.0" + } + }, + "nodejs_toolchains": { + "bzlFile": "@@rules_nodejs~//nodejs/private:toolchains_repo.bzl", + "ruleClassName": "toolchains_repo", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_linux_amd64": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "linux_amd64", + "node_version": "16.19.0" + } + }, + "nodejs_linux_ppc64le": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "linux_ppc64le", + "node_version": "16.19.0" + } + }, + "nodejs_darwin_amd64": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "darwin_amd64", + "node_version": "16.19.0" + } + }, + "nodejs_linux_arm64": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "linux_arm64", + "node_version": "16.19.0" + } + }, + "nodejs": { + "bzlFile": "@@rules_nodejs~//nodejs/private:nodejs_repo_host_os_alias.bzl", + "ruleClassName": "nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_darwin_arm64": { + "bzlFile": "@@rules_nodejs~//nodejs:repositories.bzl", + "ruleClassName": "node_repositories", + "attributes": { + "platform": "darwin_arm64", + "node_version": "16.19.0" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_nodejs~", + "bazel_skylib", + "bazel_skylib~" + ], + [ + "rules_nodejs~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, "@@rules_python~//python/extensions:python.bzl%python": { "general": { - "bzlTransitiveDigest": "XaaZIw4dO4l6naftU5IBdrfCE1mOmelaT/Sq9uyBnhs=", - "usagesDigest": "9rlrm2M/kJEEPWIo3UEIjkAFxHjzsbMIAFR9yrYnKsQ=", + "bzlTransitiveDigest": "/yOJamf205SazTZcWeVppJIMp+ft3hLNKXSwoDADZNo=", + "usagesDigest": "ZE2I3XMaBI3a/ZeZaclrZU48gDCvEch5L5cq9Ek70e8=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, "generatedRepoSpecs": { - "python_aliases": { - "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", - "ruleClassName": "multi_toolchain_aliases", + "python_3_11_s390x-unknown-linux-gnu": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", "attributes": { - "python_versions": { - "3.11": "python_3_11" - } + "sha256": "f9f19823dba3209cedc4647b00f46ed0177242917db20fb7fb539970e384531c", + "patches": [], + "platform": "s390x-unknown-linux-gnu", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-s390x-unknown-linux-gnu-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-s390x-unknown-linux-gnu-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false } }, "python_3_11": { "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", "ruleClassName": "toolchain_aliases", "attributes": { - "python_version": "3.11.1", - "user_repository_name": "python_3_11" + "python_version": "3.11.6", + "user_repository_name": "python_3_11", + "platforms": [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "ppc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu" + ] } }, "python_3_11_aarch64-unknown-linux-gnu": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "debf15783bdcb5530504f533d33fda75a7b905cec5361ae8f33da5ba6599f8b4", + "sha256": "3e26a672df17708c4dc928475a5974c3fb3a34a9b45c65fb4bd1e50504cc84ec", "patches": [], "platform": "aarch64-unknown-linux-gnu", - "python_version": "3.11.1", - "release_filename": "20230116/cpython-3.11.1+20230116-aarch64-unknown-linux-gnu-install_only.tar.gz", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-aarch64-unknown-linux-gnu-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-aarch64-unknown-linux-gnu-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-aarch64-unknown-linux-gnu-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", + "coverage_tool": "", "ignore_root_user_error": false } }, @@ -2018,16 +2919,35 @@ "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "4918cdf1cab742a90f85318f88b8122aeaa2d04705803c7b6e78e81a3dd40f80", + "sha256": "916c35125b5d8323a21526d7a9154ca626453f63d0878e95b9f613a95006c990", "patches": [], "platform": "aarch64-apple-darwin", - "python_version": "3.11.1", - "release_filename": "20230116/cpython-3.11.1+20230116-aarch64-apple-darwin-install_only.tar.gz", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-aarch64-apple-darwin-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-aarch64-apple-darwin-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_11_ppc64le-unknown-linux-gnu": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "7937035f690a624dba4d014ffd20c342e843dd46f89b0b0a1e5726b85deb8eaf", + "patches": [], + "platform": "ppc64le-unknown-linux-gnu", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-ppc64le-unknown-linux-gnu-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-aarch64-apple-darwin-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-ppc64le-unknown-linux-gnu-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", + "coverage_tool": "", "ignore_root_user_error": false } }, @@ -2035,23 +2955,25 @@ "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "20a4203d069dc9b710f70b09e7da2ce6f473d6b1110f9535fb6f4c469ed54733", + "sha256": "178cb1716c2abc25cb56ae915096c1a083e60abeba57af001996e8bc6ce1a371", "patches": [], "platform": "x86_64-apple-darwin", - "python_version": "3.11.1", - "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-apple-darwin-install_only.tar.gz", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-x86_64-apple-darwin-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-apple-darwin-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-x86_64-apple-darwin-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", + "coverage_tool": "", "ignore_root_user_error": false } }, "pythons_hub": { - "bzlFile": "@@rules_python~//python/extensions/private:pythons_hub.bzl", + "bzlFile": "@@rules_python~//python/private/bzlmod:pythons_hub.bzl", "ruleClassName": "hub_repo", "attributes": { + "default_python_version": "3.11", "toolchain_prefixes": [ "_0000_python_3_11_" ], @@ -2066,20 +2988,30 @@ ] } }, + "python_versions": { + "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", + "ruleClassName": "multi_toolchain_aliases", + "attributes": { + "python_versions": { + "3.11": "python_3_11" + } + } + }, "python_3_11_x86_64-pc-windows-msvc": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "edc08979cb0666a597466176511529c049a6f0bba8adf70df441708f766de5bf", + "sha256": "3933545e6d41462dd6a47e44133ea40995bc6efeed8c2e4cbdf1a699303e95ea", "patches": [], "platform": "x86_64-pc-windows-msvc", - "python_version": "3.11.1", - "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-pc-windows-msvc-shared-install_only.tar.gz", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-x86_64-pc-windows-msvc-shared-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-pc-windows-msvc-shared-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-x86_64-pc-windows-msvc-shared-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", + "coverage_tool": "", "ignore_root_user_error": false } }, @@ -2087,16 +3019,17 @@ "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "02a551fefab3750effd0e156c25446547c238688a32fabde2995c941c03a6423", + "sha256": "ee37a7eae6e80148c7e3abc56e48a397c1664f044920463ad0df0fc706eacea8", "patches": [], "platform": "x86_64-unknown-linux-gnu", - "python_version": "3.11.1", - "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-unknown-linux-gnu-install_only.tar.gz", + "python_version": "3.11.6", + "release_filename": "20231002/cpython-3.11.6+20231002-x86_64-unknown-linux-gnu-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-unknown-linux-gnu-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20231002/cpython-3.11.6+20231002-x86_64-unknown-linux-gnu-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", + "coverage_tool": "", "ignore_root_user_error": false } } @@ -2109,6 +3042,261 @@ ] ] } + }, + "@@rules_python~//python/private/bzlmod:internal_deps.bzl%internal_deps": { + "general": { + "bzlTransitiveDigest": "BBwtJlGgWcMoGDUgN/9oMYPkMEig0gnViMArGuYOgvw=", + "usagesDigest": "0KtJR32xTfnnwt2hOSAdBgKoWuOMjlmHn+Po/xBs5Aw=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "pypi__wheel": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/b8/8b/31273bf66016be6ad22bb7345c37ff350276cfd46e389a0c2ac5da9d9073/wheel-0.41.2-py3-none-any.whl", + "sha256": "75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/cc/37/db7ba97e676af155f5fcb1a35466f446eadc9104e25b83366e8088c9c926/importlib_metadata-6.8.0-py3-none-any.whl", + "sha256": "3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d5/ea/9ae603de7fbb3df820b23a70f6aff92bf8c7770043254ad8d2dc9d6bcba4/pyproject_hooks-1.0.0-py3-none-any.whl", + "sha256": "283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ee/2f/ef63e64e9429111e73d3d6cbee80591672d16f2725e648ebc52096f3d323/pep517-0.13.0-py3-none-any.whl", + "sha256": "4ba4446d80aed5b5eac6509ade100bff3e7943a8489de249654a5ae9b33ee35b", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ab/c3/57f0601a2d4fe15de7a553c00adbc901425661bf048f2a22dfc500caf121/packaging-23.1-py3-none-any.whl", + "sha256": "994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e8/df/47e6267c6b5cdae867adbdd84b437393e6202ce4322de0a5e0b92960e1d6/pip_tools-7.3.0-py3-none-any.whl", + "sha256": "8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/4f/ab/0bcfebdfc3bfa8554b2b2c97a555569c4c1ebc74ea288741ea8326c51906/setuptools-68.1.2-py3-none-any.whl", + "sha256": "3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8c/08/d3006317aefe25ea79d3b76c9650afabaf6d63d1c8443b236e7405447503/zipp-3.16.2-py3-none-any.whl", + "sha256": "679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__build": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/58/91/17b00d5fac63d3dca605f1b8269ba3c65e98059e1fd99d00283e42a454f0/build-0.10.0-py3-none-any.whl", + "sha256": "af266720050a66c893a6096a2f410989eeac74ff9a68ba194b3f6473e8e26171", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "rules_python_internal": { + "bzlFile": "@@rules_python~//python/private:internal_config_repo.bzl", + "ruleClassName": "internal_config_repo", + "attributes": {} + }, + "pypi__pip": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/c2/e06851e8cc28dcad7c155f4753da8833ac06a5c704c109313b8d5a62968a/pip-23.2.1-py3-none-any.whl", + "sha256": "7ccf472345f20d35bdc9d1841ff5f313260c2c33fe417f48c30ac46cccabf5be", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/5a/cb/6dce742ea14e47d6f565589e859ad225f2a5de576d7696e0623b784e226b/more_itertools-10.1.0-py3-none-any.whl", + "sha256": "64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", + "ruleClassName": "http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:defs.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude in /python/pip_install/tools/bazel.py\n # to avoid non-determinism following pip install's behavior.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/* *\",\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_python~", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@toolchains_protoc~//protoc:extensions.bzl%protoc": { + "general": { + "bzlTransitiveDigest": "HnmcD4ia7/1ZuQnymt4OGHXrW62MmIgwCtHByGQ7LQs=", + "usagesDigest": "OdpHUCO7Z6eHXrRPxbBX7o1+hQ8T8fCv2SeY/cbjo88=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "toolchains_protoc_hub.linux_aarch_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "linux-aarch_64", + "version": "v25.3" + } + }, + "toolchains_protoc_hub": { + "bzlFile": "@@toolchains_protoc~//protoc/private:protoc_toolchains.bzl", + "ruleClassName": "protoc_toolchains_repo", + "attributes": { + "user_repository_name": "toolchains_protoc_hub" + } + }, + "toolchains_protoc_hub.osx_x86_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "osx-x86_64", + "version": "v25.3" + } + }, + "toolchains_protoc_hub.linux_s390_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "linux-s390_64", + "version": "v25.3" + } + }, + "toolchains_protoc_hub.osx_aarch_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "osx-aarch_64", + "version": "v25.3" + } + }, + "com_google_protobuf": { + "bzlFile": "@@toolchains_protoc~//protoc:toolchain.bzl", + "ruleClassName": "_google_protobuf_alias_repo", + "attributes": { + "alias_to": "toolchains_protoc_hub.osx_aarch_64" + } + }, + "toolchains_protoc_hub.win64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "win64", + "version": "v25.3" + } + }, + "toolchains_protoc_hub.linux_x86_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "linux-x86_64", + "version": "v25.3" + } + }, + "toolchains_protoc_hub.linux_ppcle_64": { + "bzlFile": "@@toolchains_protoc~//protoc/private:prebuilt_protoc_toolchain.bzl", + "ruleClassName": "prebuilt_protoc_repo", + "attributes": { + "platform": "linux-ppcle_64", + "version": "v25.3" + } + } + }, + "recordedRepoMappingEntries": [] + } } } } diff --git a/WORKSPACE b/WORKSPACE index ae7f5bba..70f90b92 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -64,3 +64,17 @@ maven_install( load("@bazel_diff_maven//:defs.bzl", "pinned_maven_install") pinned_maven_install() + +load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies") + +aspect_bazel_lib_dependencies() + +load( + "@aspect_rules_lint//format:repositories.bzl", + "fetch_ktfmt", + "rules_lint_dependencies", +) + +rules_lint_dependencies() + +fetch_ktfmt() diff --git a/cli/BUILD b/cli/BUILD index 6a84140e..b32336df 100644 --- a/cli/BUILD +++ b/cli/BUILD @@ -1,3 +1,4 @@ +load("@aspect_rules_lint//format:defs.bzl", "format_multirun") load("@rules_java//java:defs.bzl", "java_binary") load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library", "kt_jvm_test") @@ -58,7 +59,6 @@ kt_jvm_test( runtime_deps = [":cli-test-lib"], ) - kt_jvm_test( name = "SourceFileHasherTest", data = [ @@ -106,10 +106,10 @@ kt_jvm_test( kt_jvm_test( name = "E2ETest", + data = [":workspaces"], jvm_flags = ["-Djava.security.manager=allow"], test_class = "com.bazel_diff.e2e.E2ETest", runtime_deps = [":cli-test-lib"], - data = [":workspaces"], ) kt_jvm_test( @@ -146,3 +146,15 @@ filegroup( "src/test/resources/workspaces", ], ) + +java_binary( + name = "ktfmt", + main_class = "com.facebook.ktfmt.cli.Main", + runtime_deps = ["@ktfmt//jar"], +) + +format_multirun( + name = "format", + kotlin = ":ktfmt", + visibility = ["//visibility:public"], +) diff --git a/cli/src/main/kotlin/com/bazel_diff/Main.kt b/cli/src/main/kotlin/com/bazel_diff/Main.kt index 0809e17b..2ed37ad6 100644 --- a/cli/src/main/kotlin/com/bazel_diff/Main.kt +++ b/cli/src/main/kotlin/com/bazel_diff/Main.kt @@ -1,15 +1,15 @@ package com.bazel_diff import com.bazel_diff.cli.BazelDiff -import picocli.CommandLine import kotlin.system.exitProcess +import picocli.CommandLine class Main { - companion object { - @JvmStatic - fun main(args: Array) { - val exitCode = CommandLine(BazelDiff()).execute(*args) - exitProcess(exitCode) - } + companion object { + @JvmStatic + fun main(args: Array) { + val exitCode = CommandLine(BazelDiff()).execute(*args) + exitProcess(exitCode) } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelClient.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelClient.kt index 5ad900a5..1a67572f 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelClient.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelClient.kt @@ -2,59 +2,65 @@ package com.bazel_diff.bazel import com.bazel_diff.log.Logger import com.google.devtools.build.lib.query2.proto.proto2api.Build +import java.util.Calendar import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import java.util.Calendar class BazelClient( - private val useCquery: Boolean, - private val fineGrainedHashExternalRepos: Set, - private val excludeExternalTargets: Boolean + private val useCquery: Boolean, + private val fineGrainedHashExternalRepos: Set, + private val excludeExternalTargets: Boolean ) : KoinComponent { - private val logger: Logger by inject() - private val queryService: BazelQueryService by inject() + private val logger: Logger by inject() + private val queryService: BazelQueryService by inject() - suspend fun queryAllTargets(): List { - val queryEpoch = Calendar.getInstance().getTimeInMillis() + suspend fun queryAllTargets(): List { + val queryEpoch = Calendar.getInstance().getTimeInMillis() - val repoTargetsQuery = if (excludeExternalTargets) emptyList() else listOf("//external:all-targets") - val targets = if (useCquery) { - // Explicitly listing external repos here sometimes causes issues mentioned at - // https://bazel.build/query/cquery#recursive-target-patterns. Hence, we query all dependencies with `deps` - // instead. However, we still need to append all "//external:*" targets because fine-grained hash - // computation depends on hashing of source files in external repos as well, which is limited to repos - // explicitly mentioned in `fineGrainedHashExternalRepos` flag. Therefore, for any repos not mentioned there - // we are still relying on the repo-generation target under `//external` to compute the hash. - // - // In addition, we must include all source dependencies in this query in order for them to show up in - // `configuredRuleInput`. Hence, one must not filter them out with `kind(rule, deps(..))`. However, these - // source targets are omitted inside BazelQueryService with the custom starlark function used to print - // labels. - (queryService.query("deps(//...:all-targets)", useCquery = true) + - queryService.query(repoTargetsQuery.joinToString(" + ") { "'$it'" })) - .distinctBy { it.rule.name } + val repoTargetsQuery = + if (excludeExternalTargets) emptyList() else listOf("//external:all-targets") + val targets = + if (useCquery) { + // Explicitly listing external repos here sometimes causes issues mentioned at + // https://bazel.build/query/cquery#recursive-target-patterns. Hence, we query all + // dependencies with `deps` + // instead. However, we still need to append all "//external:*" targets because + // fine-grained hash + // computation depends on hashing of source files in external repos as well, which is + // limited to repos + // explicitly mentioned in `fineGrainedHashExternalRepos` flag. Therefore, for any repos + // not mentioned there + // we are still relying on the repo-generation target under `//external` to compute the + // hash. + // + // In addition, we must include all source dependencies in this query in order for them to + // show up in + // `configuredRuleInput`. Hence, one must not filter them out with `kind(rule, deps(..))`. + // However, these + // source targets are omitted inside BazelQueryService with the custom starlark function + // used to print + // labels. + (queryService.query("deps(//...:all-targets)", useCquery = true) + + queryService.query(repoTargetsQuery.joinToString(" + ") { "'$it'" })) + .distinctBy { it.rule.name } } else { - val buildTargetsQuery = listOf("//...:all-targets") + fineGrainedHashExternalRepos.map { "@$it//...:all-targets" } - queryService.query((repoTargetsQuery + buildTargetsQuery).joinToString(" + ") { "'$it'" }) + val buildTargetsQuery = + listOf("//...:all-targets") + + fineGrainedHashExternalRepos.map { "@$it//...:all-targets" } + queryService.query((repoTargetsQuery + buildTargetsQuery).joinToString(" + ") { "'$it'" }) } - val queryDuration = Calendar.getInstance().getTimeInMillis() - queryEpoch - logger.i { "All targets queried in $queryDuration" } - return targets.mapNotNull { target: Build.Target -> - when (target.type) { - Build.Target.Discriminator.RULE -> BazelTarget.Rule(target) - Build.Target.Discriminator.SOURCE_FILE -> BazelTarget.SourceFile( - target - ) - - Build.Target.Discriminator.GENERATED_FILE -> BazelTarget.GeneratedFile( - target - ) - - else -> { - logger.w { "Unsupported target type in the build graph: ${target.type.name}" } - null - } - } + val queryDuration = Calendar.getInstance().getTimeInMillis() - queryEpoch + logger.i { "All targets queried in $queryDuration" } + return targets.mapNotNull { target: Build.Target -> + when (target.type) { + Build.Target.Discriminator.RULE -> BazelTarget.Rule(target) + Build.Target.Discriminator.SOURCE_FILE -> BazelTarget.SourceFile(target) + Build.Target.Discriminator.GENERATED_FILE -> BazelTarget.GeneratedFile(target) + else -> { + logger.w { "Unsupported target type in the build graph: ${target.type.name}" } + null } + } } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelQueryService.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelQueryService.kt index 39bf49d4..599bc5b6 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelQueryService.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelQueryService.kt @@ -5,97 +5,101 @@ import com.bazel_diff.process.Redirect import com.bazel_diff.process.process import com.google.devtools.build.lib.analysis.AnalysisProtosV2 import com.google.devtools.build.lib.query2.proto.proto2api.Build +import java.io.File +import java.nio.file.Files +import java.nio.file.Path import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import java.io.File -import java.nio.file.Files -import java.nio.file.Path class BazelQueryService( - private val workingDirectory: Path, - private val bazelPath: Path, - private val startupOptions: List, - private val commandOptions: List, - private val cqueryOptions: List, - private val keepGoing: Boolean, - private val noBazelrc: Boolean, + private val workingDirectory: Path, + private val bazelPath: Path, + private val startupOptions: List, + private val commandOptions: List, + private val cqueryOptions: List, + private val keepGoing: Boolean, + private val noBazelrc: Boolean, ) : KoinComponent { - private val logger: Logger by inject() + private val logger: Logger by inject() - suspend fun query( - query: String, - useCquery: Boolean = false) - : List { - // Unfortunately, there is still no direct way to tell if a target is compatible or not with the proto output - // by itself. So we do an extra cquery with the trick at - // https://bazel.build/extending/platforms#cquery-incompatible-target-detection to first find all compatible - // targets. - val compatibleTargetSet = - if (useCquery) { - runQuery(query, useCquery = true, outputCompatibleTargets = true).useLines { - it.filter { it.isNotBlank() }.toSet() - } - } else { - emptySet() - } - val outputFile = runQuery(query, useCquery) + suspend fun query(query: String, useCquery: Boolean = false): List { + // Unfortunately, there is still no direct way to tell if a target is compatible or not with the + // proto output + // by itself. So we do an extra cquery with the trick at + // https://bazel.build/extending/platforms#cquery-incompatible-target-detection to first find + // all compatible + // targets. + val compatibleTargetSet = + if (useCquery) { + runQuery(query, useCquery = true, outputCompatibleTargets = true).useLines { + it.filter { it.isNotBlank() }.toSet() + } + } else { + emptySet() + } + val outputFile = runQuery(query, useCquery) - val targets = outputFile.inputStream().buffered().use { proto -> - if (useCquery) { - val cqueryResult = AnalysisProtosV2.CqueryResult.parseFrom(proto) - cqueryResult.resultsList.filter { it.target.rule.name in compatibleTargetSet }.map { it.target } - } else { - mutableListOf().apply { - while (true) { - val target = Build.Target.parseDelimitedFrom(proto) ?: break - // EOF - add(target) - } - } + val targets = + outputFile.inputStream().buffered().use { proto -> + if (useCquery) { + val cqueryResult = AnalysisProtosV2.CqueryResult.parseFrom(proto) + cqueryResult.resultsList + .filter { it.target.rule.name in compatibleTargetSet } + .map { it.target } + } else { + mutableListOf().apply { + while (true) { + val target = Build.Target.parseDelimitedFrom(proto) ?: break + // EOF + add(target) + } } + } } - return targets - } + return targets + } - @OptIn(ExperimentalCoroutinesApi::class) - private suspend fun runQuery( - query: String, - useCquery: Boolean, - outputCompatibleTargets: Boolean = false - ): File { - val queryFile = Files.createTempFile(null, ".txt").toFile() - queryFile.deleteOnExit() - val outputFile = Files.createTempFile(null, ".bin").toFile() - outputFile.deleteOnExit() + @OptIn(ExperimentalCoroutinesApi::class) + private suspend fun runQuery( + query: String, + useCquery: Boolean, + outputCompatibleTargets: Boolean = false + ): File { + val queryFile = Files.createTempFile(null, ".txt").toFile() + queryFile.deleteOnExit() + val outputFile = Files.createTempFile(null, ".bin").toFile() + outputFile.deleteOnExit() - queryFile.writeText(query) + queryFile.writeText(query) - val cmd: MutableList = ArrayList().apply { - add(bazelPath.toString()) - if (noBazelrc) { - add("--bazelrc=/dev/null") + val cmd: MutableList = + ArrayList().apply { + add(bazelPath.toString()) + if (noBazelrc) { + add("--bazelrc=/dev/null") + } + addAll(startupOptions) + if (useCquery) { + add("cquery") + if (!outputCompatibleTargets) { + // There is no need to query the transitions when querying for compatible targets. + add("--transitions=lite") } - addAll(startupOptions) - if (useCquery) { - add("cquery") - if (!outputCompatibleTargets) { - // There is no need to query the transitions when querying for compatible targets. - add("--transitions=lite") - } - } else { - add("query") - } - add("--output") - if (useCquery) { - if (outputCompatibleTargets) { - add("starlark") - add("--starlark:file") - val cqueryOutputFile = Files.createTempFile(null, ".cquery").toFile() - cqueryOutputFile.deleteOnExit() - cqueryOutputFile.writeText(""" + } else { + add("query") + } + add("--output") + if (useCquery) { + if (outputCompatibleTargets) { + add("starlark") + add("--starlark:file") + val cqueryOutputFile = Files.createTempFile(null, ".cquery").toFile() + cqueryOutputFile.deleteOnExit() + cqueryOutputFile.writeText( + """ def format(target): if providers(target) == None: # skip printing non-target results. That is, source files and generated files won't be @@ -104,46 +108,48 @@ class BazelQueryService( if "IncompatiblePlatformProvider" not in providers(target): return str(target.label) return "" - """.trimIndent()) - add(cqueryOutputFile.toString()) - } else { - // Unfortunately, cquery does not support streamed_proto yet. - // See https://github.com/bazelbuild/bazel/issues/17743. This poses an issue for large monorepos. - add("proto") - } + """ + .trimIndent()) + add(cqueryOutputFile.toString()) } else { - add("streamed_proto") - } - if (!useCquery) { - add("--order_output=no") + // Unfortunately, cquery does not support streamed_proto yet. + // See https://github.com/bazelbuild/bazel/issues/17743. This poses an issue for large + // monorepos. + add("proto") } - if (keepGoing) { - add("--keep_going") - } - if (useCquery) { - addAll(cqueryOptions) - add("--consistent_labels") - } else { - addAll(commandOptions) - } - add("--query_file") - add(queryFile.toString()) - } - - logger.i { "Executing Query: $query" } - logger.i { "Command: ${cmd.toTypedArray().joinToString()}" } - val result = runBlocking { - process( - *cmd.toTypedArray(), - stdout = Redirect.ToFile(outputFile), - workingDirectory = workingDirectory.toFile(), - stderr = Redirect.PRINT, - destroyForcibly = true, - ) + } else { + add("streamed_proto") + } + if (!useCquery) { + add("--order_output=no") + } + if (keepGoing) { + add("--keep_going") + } + if (useCquery) { + addAll(cqueryOptions) + add("--consistent_labels") + } else { + addAll(commandOptions) + } + add("--query_file") + add(queryFile.toString()) } - if (result.resultCode != 0) - throw RuntimeException("Bazel query failed, exit code ${result.resultCode}") - return outputFile + logger.i { "Executing Query: $query" } + logger.i { "Command: ${cmd.toTypedArray().joinToString()}" } + val result = runBlocking { + process( + *cmd.toTypedArray(), + stdout = Redirect.ToFile(outputFile), + workingDirectory = workingDirectory.toFile(), + stderr = Redirect.PRINT, + destroyForcibly = true, + ) } + + if (result.resultCode != 0) + throw RuntimeException("Bazel query failed, exit code ${result.resultCode}") + return outputFile + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelRule.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelRule.kt index 6ed2ccc8..0c58bdf7 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelRule.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelRule.kt @@ -4,51 +4,69 @@ import com.bazel_diff.hash.safePutBytes import com.bazel_diff.hash.sha256 import com.google.devtools.build.lib.query2.proto.proto2api.Build -// Ignore generator_location when computing a target's hash since it is likely to change and does not -// affect a target's generated actions. Internally, Bazel also does this when computing a target's hash: +// Ignore generator_location when computing a target's hash since it is likely to change and does +// not +// affect a target's generated actions. Internally, Bazel also does this when computing a target's +// hash: // https://github.com/bazelbuild/bazel/blob/6971b016f1e258e3bb567a0f9fe7a88ad565d8f2/src/main/java/com/google/devtools/build/lib/query2/query/output/SyntheticAttributeHashCalculator.java#L78-L81 private val DEFAULT_IGNORED_ATTRS = arrayOf("generator_location") class BazelRule(private val rule: Build.Rule) { - fun digest(ignoredAttrs: Set): ByteArray { - return sha256 { - safePutBytes(rule.ruleClassBytes.toByteArray()) - safePutBytes(rule.nameBytes.toByteArray()) - safePutBytes(rule.skylarkEnvironmentHashCodeBytes.toByteArray()) - for (attribute in rule.attributeList) { - if (!DEFAULT_IGNORED_ATTRS.contains(attribute.name) && !ignoredAttrs.contains(attribute.name)) - safePutBytes(attribute.toByteArray()) - } - } + fun digest(ignoredAttrs: Set): ByteArray { + return sha256 { + safePutBytes(rule.ruleClassBytes.toByteArray()) + safePutBytes(rule.nameBytes.toByteArray()) + safePutBytes(rule.skylarkEnvironmentHashCodeBytes.toByteArray()) + for (attribute in rule.attributeList) { + if (!DEFAULT_IGNORED_ATTRS.contains(attribute.name) && + !ignoredAttrs.contains(attribute.name)) + safePutBytes(attribute.toByteArray()) + } } + } - fun ruleInputList(useCquery: Boolean, fineGrainedHashExternalRepos: Set): List { - return if (useCquery) { - rule.configuredRuleInputList.map { it.label } + - rule.ruleInputList.map { ruleInput: String -> transformRuleInput(fineGrainedHashExternalRepos, ruleInput) } - // Only keep the non-fine-grained ones because the others are already covered by configuredRuleInputList - .filter { it.startsWith("//external:") } - .distinct() - } else { - rule.ruleInputList.map { ruleInput: String -> transformRuleInput(fineGrainedHashExternalRepos, ruleInput) } - } + fun ruleInputList(useCquery: Boolean, fineGrainedHashExternalRepos: Set): List { + return if (useCquery) { + rule.configuredRuleInputList.map { it.label } + + rule.ruleInputList + .map { ruleInput: String -> + transformRuleInput(fineGrainedHashExternalRepos, ruleInput) + } + // Only keep the non-fine-grained ones because the others are already covered by + // configuredRuleInputList + .filter { it.startsWith("//external:") } + .distinct() + } else { + rule.ruleInputList.map { ruleInput: String -> + transformRuleInput(fineGrainedHashExternalRepos, ruleInput) + } } + } - val name: String = rule.name + val name: String = rule.name - private fun transformRuleInput(fineGrainedHashExternalRepos: Set, ruleInput: String): String { - if (isNotMainRepo(ruleInput) && ruleInput.startsWith("@") && fineGrainedHashExternalRepos.none { ruleInput.startsWith("@$it") || ruleInput.startsWith("@@${it}") }) { - val splitRule = ruleInput.split("//".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() - if (splitRule.size == 2) { - var externalRule = splitRule[0] - externalRule = externalRule.replaceFirst("@+".toRegex(), "") - return String.format("//external:%s", externalRule) - } - } - return ruleInput + private fun transformRuleInput( + fineGrainedHashExternalRepos: Set, + ruleInput: String + ): String { + if (isNotMainRepo(ruleInput) && + ruleInput.startsWith("@") && + fineGrainedHashExternalRepos.none { + ruleInput.startsWith("@$it") || ruleInput.startsWith("@@${it}") + }) { + val splitRule = ruleInput.split("//".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + if (splitRule.size == 2) { + var externalRule = splitRule[0] + externalRule = externalRule.replaceFirst("@+".toRegex(), "") + return String.format("//external:%s", externalRule) + } } + return ruleInput + } - private fun isNotMainRepo(ruleInput: String): Boolean { - return !ruleInput.startsWith("//") && !ruleInput.startsWith("@//") && !ruleInput.startsWith("@@//") - } + private fun isNotMainRepo(ruleInput: String): Boolean { + return !ruleInput.startsWith("//") && + !ruleInput.startsWith("@//") && + !ruleInput.startsWith("@@//") + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTarget.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTarget.kt index 946056e4..efa9a38c 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTarget.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTarget.kt @@ -3,48 +3,48 @@ package com.bazel_diff.bazel import com.google.devtools.build.lib.query2.proto.proto2api.Build sealed class BazelTarget(private val target: Build.Target) { - class SourceFile(target: Build.Target) : BazelTarget(target) { - init { - assert(target.hasSourceFile()) - } - - val sourceFileName: String = target.sourceFile.name - val subincludeList: List = target.sourceFile.subincludeList - override val name: String - get() = sourceFileName + class SourceFile(target: Build.Target) : BazelTarget(target) { + init { + assert(target.hasSourceFile()) } - class Rule(target: Build.Target) : BazelTarget(target) { - init { - assert(target.hasRule()) - } + val sourceFileName: String = target.sourceFile.name + val subincludeList: List = target.sourceFile.subincludeList + override val name: String + get() = sourceFileName + } - val rule: BazelRule = BazelRule(target.rule) - override val name: String - get() = rule.name + class Rule(target: Build.Target) : BazelTarget(target) { + init { + assert(target.hasRule()) } - class GeneratedFile(target: Build.Target) : BazelTarget(target) { - init { - assert(target.hasGeneratedFile()) - } + val rule: BazelRule = BazelRule(target.rule) + override val name: String + get() = rule.name + } - val generatedFileName: String = target.generatedFile.name - val generatingRuleName: String = target.generatedFile.generatingRule - override val name: String - get() = generatedFileName + class GeneratedFile(target: Build.Target) : BazelTarget(target) { + init { + assert(target.hasGeneratedFile()) } - val type: BazelTargetType - get() = when (target.type) { - Build.Target.Discriminator.RULE -> BazelTargetType.RULE - Build.Target.Discriminator.SOURCE_FILE -> BazelTargetType.SOURCE_FILE - Build.Target.Discriminator.GENERATED_FILE -> BazelTargetType.GENERATED_FILE - Build.Target.Discriminator.PACKAGE_GROUP -> BazelTargetType.PACKAGE_GROUP - Build.Target.Discriminator.ENVIRONMENT_GROUP -> BazelTargetType.ENVIRONMENT_GROUP - else -> BazelTargetType.UNKNOWN + val generatedFileName: String = target.generatedFile.name + val generatingRuleName: String = target.generatedFile.generatingRule + override val name: String + get() = generatedFileName + } + + val type: BazelTargetType + get() = + when (target.type) { + Build.Target.Discriminator.RULE -> BazelTargetType.RULE + Build.Target.Discriminator.SOURCE_FILE -> BazelTargetType.SOURCE_FILE + Build.Target.Discriminator.GENERATED_FILE -> BazelTargetType.GENERATED_FILE + Build.Target.Discriminator.PACKAGE_GROUP -> BazelTargetType.PACKAGE_GROUP + Build.Target.Discriminator.ENVIRONMENT_GROUP -> BazelTargetType.ENVIRONMENT_GROUP + else -> BazelTargetType.UNKNOWN } - abstract val name: String + abstract val name: String } - diff --git a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTargetType.kt b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTargetType.kt index ac9f0d9a..88a0e8d4 100644 --- a/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTargetType.kt +++ b/cli/src/main/kotlin/com/bazel_diff/bazel/BazelTargetType.kt @@ -1,5 +1,10 @@ package com.bazel_diff.bazel enum class BazelTargetType { - RULE, SOURCE_FILE, GENERATED_FILE, PACKAGE_GROUP, ENVIRONMENT_GROUP, UNKNOWN + RULE, + SOURCE_FILE, + GENERATED_FILE, + PACKAGE_GROUP, + ENVIRONMENT_GROUP, + UNKNOWN } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/BazelDiff.kt b/cli/src/main/kotlin/com/bazel_diff/cli/BazelDiff.kt index acf95d47..8f7e9928 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/BazelDiff.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/BazelDiff.kt @@ -1,12 +1,8 @@ package com.bazel_diff.cli -import com.bazel_diff.cli.converter.NormalisingPathConverter -import com.bazel_diff.cli.converter.OptionsConverter import picocli.CommandLine import picocli.CommandLine.Model.CommandSpec import picocli.CommandLine.Spec -import java.nio.file.Path - @CommandLine.Command( name = "bazel-diff", @@ -16,29 +12,27 @@ import java.nio.file.Path versionProvider = VersionProvider::class, ) class BazelDiff : Runnable { - @CommandLine.Option( - names = ["-v", "--verbose"], - description = ["Display query string, missing files and elapsed time"], - scope = CommandLine.ScopeType.INHERIT, - ) - var verbose = false + @CommandLine.Option( + names = ["-v", "--verbose"], + description = ["Display query string, missing files and elapsed time"], + scope = CommandLine.ScopeType.INHERIT, + ) + var verbose = false - @CommandLine.Option( - names = ["--debug"], - hidden = true, - scope = CommandLine.ScopeType.INHERIT, - defaultValue = "\${sys:DEBUG:-false}" - ) - var debug = false + @CommandLine.Option( + names = ["--debug"], + hidden = true, + scope = CommandLine.ScopeType.INHERIT, + defaultValue = "\${sys:DEBUG:-false}") + var debug = false - @Spec - lateinit var spec: CommandSpec + @Spec lateinit var spec: CommandSpec - override fun run() { - throw CommandLine.ParameterException(spec.commandLine(), "Missing required subcommand") - } + override fun run() { + throw CommandLine.ParameterException(spec.commandLine(), "Missing required subcommand") + } - fun isVerbose(): Boolean { - return verbose || debug - } + fun isVerbose(): Boolean { + return verbose || debug + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/GenerateHashesCommand.kt b/cli/src/main/kotlin/com/bazel_diff/cli/GenerateHashesCommand.kt index d0824a65..17046ae0 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/GenerateHashesCommand.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/GenerateHashesCommand.kt @@ -7,197 +7,219 @@ import com.bazel_diff.di.hasherModule import com.bazel_diff.di.loggingModule import com.bazel_diff.di.serialisationModule import com.bazel_diff.interactor.GenerateHashesInteractor -import org.koin.core.context.startKoin -import org.koin.core.context.stopKoin -import picocli.CommandLine import java.io.File import java.nio.file.Path import java.util.concurrent.Callable +import org.koin.core.context.startKoin +import org.koin.core.context.stopKoin +import picocli.CommandLine @CommandLine.Command( name = "generate-hashes", mixinStandardHelpOptions = true, - description = ["Writes to a file the SHA256 hashes for each Bazel Target in the provided workspace."], - versionProvider = VersionProvider::class -) + description = + ["Writes to a file the SHA256 hashes for each Bazel Target in the provided workspace."], + versionProvider = VersionProvider::class) class GenerateHashesCommand : Callable { - @CommandLine.ParentCommand - private lateinit var parent: BazelDiff - - @CommandLine.Option( - names = ["-w", "--workspacePath"], - description = ["Path to Bazel workspace directory."], - scope = CommandLine.ScopeType.INHERIT, - required = true, - converter = [NormalisingPathConverter::class] - ) - lateinit var workspacePath: Path - - @CommandLine.Option( - names = ["-b", "--bazelPath"], - description = ["Path to Bazel binary. If not specified, the Bazel binary available in PATH will be used."], - scope = CommandLine.ScopeType.INHERIT, - defaultValue = "bazel", - ) - lateinit var bazelPath: Path - - @CommandLine.Option( - names = ["--contentHashPath"], - description = ["Path to content hash json file. It's a map which maps relative file path from workspace path to its content hash. Files in this map will skip content hashing and use provided value"], - scope = CommandLine.ScopeType.INHERIT, - required = false - ) - var contentHashPath: File? = null - - @CommandLine.Option( - names = ["-so", "--bazelStartupOptions"], - description = ["Additional space separated Bazel client startup options used when invoking Bazel"], - scope = CommandLine.ScopeType.INHERIT, - converter = [OptionsConverter::class], - ) - var bazelStartupOptions: List = emptyList() - - @CommandLine.Option( - names = ["-co", "--bazelCommandOptions"], - description = ["Additional space separated Bazel command options used when invoking `bazel query`"], - scope = CommandLine.ScopeType.INHERIT, - converter = [OptionsConverter::class], - ) - var bazelCommandOptions: List = emptyList() - - @CommandLine.Option( - names = ["--fineGrainedHashExternalRepos"], - description = ["Comma separate list of external repos in which fine-grained hashes are computed for the targets. By default, external repos are treated as an opaque blob. If an external repo is specified here, bazel-diff instead computes the hash for individual targets. For example, one wants to specify `maven` here if they user rules_jvm_external so that individual third party dependency change won't invalidate all targets in the mono repo."], - scope = CommandLine.ScopeType.INHERIT, - converter = [CommaSeparatedValueConverter::class], - ) - var fineGrainedHashExternalRepos: Set = emptySet() - - @CommandLine.Option( - names = ["--useCquery"], - negatable = true, - description = ["If true, use cquery instead of query when generating dependency graphs. Using cquery would yield more accurate build graph at the cost of slower query execution. When this is set, one usually also wants to set `--cqueryCommandOptions` to specify a targeting platform. Note that this flag only works with Bazel 6.2.0 or above because lower versions does not support `--query_file` flag."], - scope = CommandLine.ScopeType.INHERIT - ) - var useCquery = false - - @CommandLine.Option( - names = ["--includeTargetType"], - negatable = true, - description = ["Whether include target type in the generated JSON or not.\n" - + "If false, the generate JSON schema is: {\"\": \"\"}\n" - + "If true, the generate JSON schema is: {\"\": \"#\" }"], - scope = CommandLine.ScopeType.INHERIT - ) - var includeTargetType = false - - @CommandLine.Option( - names = ["-tt", "--targetType"], - split = ",", - scope = CommandLine.ScopeType.LOCAL, - description = ["The types of targets to filter. Use comma (,) to separate multiple values, e.g. '--targetType=SourceFile,Rule,GeneratedFile'."] - ) - var targetType: Set? = null - - @CommandLine.Option( - names = ["--cqueryCommandOptions"], - description = ["Additional space separated Bazel command options used when invoking `bazel cquery`. This flag is has no effect if `--useCquery`is false."], - scope = CommandLine.ScopeType.INHERIT, - converter = [OptionsConverter::class], - ) - var cqueryCommandOptions: List = emptyList() - - @CommandLine.Option( - names = ["-k", "--keep_going"], - negatable = true, - description = ["This flag controls if `bazel query` will be executed with the `--keep_going` flag or not. Disabling this flag allows you to catch configuration issues in your Bazel graph, but may not work for some Bazel setups. Defaults to `true`"], - scope = CommandLine.ScopeType.INHERIT - ) - var keepGoing = true - - @CommandLine.Option( - names = ["-s", "--seed-filepaths"], - description = ["A text file containing a newline separated list of filepaths, each of these filepaths will be read and used as a seed for all targets."] - ) - var seedFilepaths: File? = null - - @CommandLine.Parameters( - index = "0", - description = ["The filepath to write the resulting JSON of dictionary target => SHA-256 values. If not specified, the JSON will be written to STDOUT."], - defaultValue = CommandLine.Parameters.NULL_VALUE - ) - var outputPath: File? = null - - @CommandLine.Option( - names = ["--ignoredRuleHashingAttributes"], - description = ["Attributes that should be ignored when hashing rule targets."], - scope = CommandLine.ScopeType.INHERIT, - converter = [CommaSeparatedValueConverter::class], - ) - var ignoredRuleHashingAttributes: Set = emptySet() - - @CommandLine.Option( - names = ["-d", "--depEdgesFile"], - description = ["Path to the file where dependency edges are written to. If not specified, the dependency edges will not be written to a file. Needed for computing build graph distance metrics. See bazel-diff docs for more details about build graph distance metrics."], - scope = CommandLine.ScopeType.INHERIT, - defaultValue = CommandLine.Parameters.NULL_VALUE - ) - var depsMappingJSONPath: File? = null - - @CommandLine.Option( - names = ["-m", "--modified-filepaths"], - description = ["Experimental: A text file containing a newline separated list of filepaths (relative to the workspace) these filepaths should represent the modified files between the specified revisions and will be used to scope what files are hashed during hash generation."] - ) - var modifiedFilepaths: File? = null - - @CommandLine.Option( - names = ["--excludeExternalTargets"], - negatable = true, - description = ["If true, exclude external targets. This must be switched on when using `--noenable_workspace` Bazel command line option. Defaults to `false`."], - scope = CommandLine.ScopeType.INHERIT - ) - var excludeExternalTargets = false - - @CommandLine.Spec - lateinit var spec: CommandLine.Model.CommandSpec - - override fun call(): Int { - validate(contentHashPath = contentHashPath) - - startKoin { - modules( - hasherModule( - workspacePath, - bazelPath, - contentHashPath, - bazelStartupOptions, - bazelCommandOptions, - cqueryCommandOptions, - useCquery, - keepGoing, - depsMappingJSONPath != null, - fineGrainedHashExternalRepos, - excludeExternalTargets, - ), - loggingModule(parent.verbose), - serialisationModule(), - ) - } - - return when (GenerateHashesInteractor().execute(seedFilepaths, outputPath, depsMappingJSONPath, ignoredRuleHashingAttributes, targetType, includeTargetType, modifiedFilepaths)) { - true -> CommandLine.ExitCode.OK - false -> CommandLine.ExitCode.SOFTWARE - }.also { stopKoin() } + @CommandLine.ParentCommand private lateinit var parent: BazelDiff + + @CommandLine.Option( + names = ["-w", "--workspacePath"], + description = ["Path to Bazel workspace directory."], + scope = CommandLine.ScopeType.INHERIT, + required = true, + converter = [NormalisingPathConverter::class]) + lateinit var workspacePath: Path + + @CommandLine.Option( + names = ["-b", "--bazelPath"], + description = + [ + "Path to Bazel binary. If not specified, the Bazel binary available in PATH will be used."], + scope = CommandLine.ScopeType.INHERIT, + defaultValue = "bazel", + ) + lateinit var bazelPath: Path + + @CommandLine.Option( + names = ["--contentHashPath"], + description = + [ + "Path to content hash json file. It's a map which maps relative file path from workspace path to its content hash. Files in this map will skip content hashing and use provided value"], + scope = CommandLine.ScopeType.INHERIT, + required = false) + var contentHashPath: File? = null + + @CommandLine.Option( + names = ["-so", "--bazelStartupOptions"], + description = + ["Additional space separated Bazel client startup options used when invoking Bazel"], + scope = CommandLine.ScopeType.INHERIT, + converter = [OptionsConverter::class], + ) + var bazelStartupOptions: List = emptyList() + + @CommandLine.Option( + names = ["-co", "--bazelCommandOptions"], + description = + ["Additional space separated Bazel command options used when invoking `bazel query`"], + scope = CommandLine.ScopeType.INHERIT, + converter = [OptionsConverter::class], + ) + var bazelCommandOptions: List = emptyList() + + @CommandLine.Option( + names = ["--fineGrainedHashExternalRepos"], + description = + [ + "Comma separate list of external repos in which fine-grained hashes are computed for the targets. By default, external repos are treated as an opaque blob. If an external repo is specified here, bazel-diff instead computes the hash for individual targets. For example, one wants to specify `maven` here if they user rules_jvm_external so that individual third party dependency change won't invalidate all targets in the mono repo."], + scope = CommandLine.ScopeType.INHERIT, + converter = [CommaSeparatedValueConverter::class], + ) + var fineGrainedHashExternalRepos: Set = emptySet() + + @CommandLine.Option( + names = ["--useCquery"], + negatable = true, + description = + [ + "If true, use cquery instead of query when generating dependency graphs. Using cquery would yield more accurate build graph at the cost of slower query execution. When this is set, one usually also wants to set `--cqueryCommandOptions` to specify a targeting platform. Note that this flag only works with Bazel 6.2.0 or above because lower versions does not support `--query_file` flag."], + scope = CommandLine.ScopeType.INHERIT) + var useCquery = false + + @CommandLine.Option( + names = ["--includeTargetType"], + negatable = true, + description = + [ + "Whether include target type in the generated JSON or not.\n" + + "If false, the generate JSON schema is: {\"\": \"\"}\n" + + "If true, the generate JSON schema is: {\"\": \"#\" }"], + scope = CommandLine.ScopeType.INHERIT) + var includeTargetType = false + + @CommandLine.Option( + names = ["-tt", "--targetType"], + split = ",", + scope = CommandLine.ScopeType.LOCAL, + description = + [ + "The types of targets to filter. Use comma (,) to separate multiple values, e.g. '--targetType=SourceFile,Rule,GeneratedFile'."]) + var targetType: Set? = null + + @CommandLine.Option( + names = ["--cqueryCommandOptions"], + description = + [ + "Additional space separated Bazel command options used when invoking `bazel cquery`. This flag is has no effect if `--useCquery`is false."], + scope = CommandLine.ScopeType.INHERIT, + converter = [OptionsConverter::class], + ) + var cqueryCommandOptions: List = emptyList() + + @CommandLine.Option( + names = ["-k", "--keep_going"], + negatable = true, + description = + [ + "This flag controls if `bazel query` will be executed with the `--keep_going` flag or not. Disabling this flag allows you to catch configuration issues in your Bazel graph, but may not work for some Bazel setups. Defaults to `true`"], + scope = CommandLine.ScopeType.INHERIT) + var keepGoing = true + + @CommandLine.Option( + names = ["-s", "--seed-filepaths"], + description = + [ + "A text file containing a newline separated list of filepaths, each of these filepaths will be read and used as a seed for all targets."]) + var seedFilepaths: File? = null + + @CommandLine.Parameters( + index = "0", + description = + [ + "The filepath to write the resulting JSON of dictionary target => SHA-256 values. If not specified, the JSON will be written to STDOUT."], + defaultValue = CommandLine.Parameters.NULL_VALUE) + var outputPath: File? = null + + @CommandLine.Option( + names = ["--ignoredRuleHashingAttributes"], + description = ["Attributes that should be ignored when hashing rule targets."], + scope = CommandLine.ScopeType.INHERIT, + converter = [CommaSeparatedValueConverter::class], + ) + var ignoredRuleHashingAttributes: Set = emptySet() + + @CommandLine.Option( + names = ["-d", "--depEdgesFile"], + description = + [ + "Path to the file where dependency edges are written to. If not specified, the dependency edges will not be written to a file. Needed for computing build graph distance metrics. See bazel-diff docs for more details about build graph distance metrics."], + scope = CommandLine.ScopeType.INHERIT, + defaultValue = CommandLine.Parameters.NULL_VALUE) + var depsMappingJSONPath: File? = null + + @CommandLine.Option( + names = ["-m", "--modified-filepaths"], + description = + [ + "Experimental: A text file containing a newline separated list of filepaths (relative to the workspace) these filepaths should represent the modified files between the specified revisions and will be used to scope what files are hashed during hash generation."]) + var modifiedFilepaths: File? = null + + @CommandLine.Option( + names = ["--excludeExternalTargets"], + negatable = true, + description = + [ + "If true, exclude external targets. This must be switched on when using `--noenable_workspace` Bazel command line option. Defaults to `false`."], + scope = CommandLine.ScopeType.INHERIT) + var excludeExternalTargets = false + + @CommandLine.Spec lateinit var spec: CommandLine.Model.CommandSpec + + override fun call(): Int { + validate(contentHashPath = contentHashPath) + + startKoin { + modules( + hasherModule( + workspacePath, + bazelPath, + contentHashPath, + bazelStartupOptions, + bazelCommandOptions, + cqueryCommandOptions, + useCquery, + keepGoing, + depsMappingJSONPath != null, + fineGrainedHashExternalRepos, + excludeExternalTargets, + ), + loggingModule(parent.verbose), + serialisationModule(), + ) } - private fun validate(contentHashPath: File?) { - contentHashPath?.let { - if (!it.canRead()) { - throw CommandLine.ParameterException( - spec.commandLine(), - "Incorrect contentHashFilePath: file doesn't exist or can't be read." - ) - } - } + return when (GenerateHashesInteractor() + .execute( + seedFilepaths, + outputPath, + depsMappingJSONPath, + ignoredRuleHashingAttributes, + targetType, + includeTargetType, + modifiedFilepaths)) { + true -> CommandLine.ExitCode.OK + false -> CommandLine.ExitCode.SOFTWARE + }.also { stopKoin() } + } + + private fun validate(contentHashPath: File?) { + contentHashPath?.let { + if (!it.canRead()) { + throw CommandLine.ParameterException( + spec.commandLine(), + "Incorrect contentHashFilePath: file doesn't exist or can't be read.") + } } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/GetImpactedTargetsCommand.kt b/cli/src/main/kotlin/com/bazel_diff/cli/GetImpactedTargetsCommand.kt index dd0fe8f2..cc2ad251 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/GetImpactedTargetsCommand.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/GetImpactedTargetsCommand.kt @@ -4,116 +4,114 @@ import com.bazel_diff.di.loggingModule import com.bazel_diff.di.serialisationModule import com.bazel_diff.interactor.CalculateImpactedTargetsInteractor import com.bazel_diff.interactor.DeserialiseHashesInteractor -import com.bazel_diff.interactor.TargetTypeFilter -import org.koin.core.context.startKoin -import org.koin.core.context.stopKoin -import picocli.CommandLine import java.io.BufferedWriter import java.io.File import java.io.FileDescriptor import java.io.FileWriter import java.io.IOException import java.util.concurrent.Callable +import org.koin.core.context.startKoin +import org.koin.core.context.stopKoin +import picocli.CommandLine @CommandLine.Command( name = "get-impacted-targets", description = ["Command-line utility to analyze the state of the bazel build graph"], ) class GetImpactedTargetsCommand : Callable { - @CommandLine.ParentCommand - private lateinit var parent: BazelDiff + @CommandLine.ParentCommand private lateinit var parent: BazelDiff - @CommandLine.Option( - names = ["-sh", "--startingHashes"], - scope = CommandLine.ScopeType.LOCAL, - description = ["The path to the JSON file of target hashes for the initial revision. Run 'generate-hashes' to get this value."], - required = true, - ) - lateinit var startingHashesJSONPath: File + @CommandLine.Option( + names = ["-sh", "--startingHashes"], + scope = CommandLine.ScopeType.LOCAL, + description = + [ + "The path to the JSON file of target hashes for the initial revision. Run 'generate-hashes' to get this value."], + required = true, + ) + lateinit var startingHashesJSONPath: File - @CommandLine.Option( - names = ["-fh", "--finalHashes"], - scope = CommandLine.ScopeType.LOCAL, - description = ["The path to the JSON file of target hashes for the final revision. Run 'generate-hashes' to get this value."], - required = true, - ) - lateinit var finalHashesJSONPath: File + @CommandLine.Option( + names = ["-fh", "--finalHashes"], + scope = CommandLine.ScopeType.LOCAL, + description = + [ + "The path to the JSON file of target hashes for the final revision. Run 'generate-hashes' to get this value."], + required = true, + ) + lateinit var finalHashesJSONPath: File - @CommandLine.Option( - names = ["-d", "--depEdgesFile"], - description = ["Path to the file where dependency edges are. If specified, build graph distance metrics will be computed from the given hash data."], - scope = CommandLine.ScopeType.INHERIT, - defaultValue = CommandLine.Parameters.NULL_VALUE - ) - var depsMappingJSONPath: File? = null + @CommandLine.Option( + names = ["-d", "--depEdgesFile"], + description = + [ + "Path to the file where dependency edges are. If specified, build graph distance metrics will be computed from the given hash data."], + scope = CommandLine.ScopeType.INHERIT, + defaultValue = CommandLine.Parameters.NULL_VALUE) + var depsMappingJSONPath: File? = null - @CommandLine.Option( - names = ["-tt", "--targetType"], - split = ",", - scope = CommandLine.ScopeType.LOCAL, - description = ["The types of targets to filter. Use comma (,) to separate multiple values, e.g. '--targetType=SourceFile,Rule,GeneratedFile'."] - ) - var targetType: Set? = null + @CommandLine.Option( + names = ["-tt", "--targetType"], + split = ",", + scope = CommandLine.ScopeType.LOCAL, + description = + [ + "The types of targets to filter. Use comma (,) to separate multiple values, e.g. '--targetType=SourceFile,Rule,GeneratedFile'."]) + var targetType: Set? = null - @CommandLine.Option( - names = ["-o", "--output"], - scope = CommandLine.ScopeType.LOCAL, - description = ["Filepath to write the impacted Bazel targets to. If using depEdgesFile: formatted in json, otherwise: newline separated. If not specified, the output will be written to STDOUT."], - ) - var outputPath: File? = null + @CommandLine.Option( + names = ["-o", "--output"], + scope = CommandLine.ScopeType.LOCAL, + description = + [ + "Filepath to write the impacted Bazel targets to. If using depEdgesFile: formatted in json, otherwise: newline separated. If not specified, the output will be written to STDOUT."], + ) + var outputPath: File? = null - @CommandLine.Spec - lateinit var spec: CommandLine.Model.CommandSpec + @CommandLine.Spec lateinit var spec: CommandLine.Model.CommandSpec - override fun call(): Int { - startKoin { - modules( - serialisationModule(), - loggingModule(parent.verbose) - ) - } + override fun call(): Int { + startKoin { modules(serialisationModule(), loggingModule(parent.verbose)) } - validate() - val deserialiser = DeserialiseHashesInteractor() - val from = deserialiser.executeTargetHash(startingHashesJSONPath) - val to = deserialiser.executeTargetHash(finalHashesJSONPath) + validate() + val deserialiser = DeserialiseHashesInteractor() + val from = deserialiser.executeTargetHash(startingHashesJSONPath) + val to = deserialiser.executeTargetHash(finalHashesJSONPath) - val outputWriter = BufferedWriter(when (val path = outputPath) { - null -> FileWriter(FileDescriptor.out) - else -> FileWriter(path) - }) + val outputWriter = + BufferedWriter( + when (val path = outputPath) { + null -> FileWriter(FileDescriptor.out) + else -> FileWriter(path) + }) - return try { - if (depsMappingJSONPath != null) { - val depsMapping = deserialiser.deserializeDeps(depsMappingJSONPath!!) - CalculateImpactedTargetsInteractor().executeWithDistances(from, to, depsMapping, outputWriter, targetType) - } else { - CalculateImpactedTargetsInteractor().execute(from, to, outputWriter, targetType) - } - CommandLine.ExitCode.OK + return try { + if (depsMappingJSONPath != null) { + val depsMapping = deserialiser.deserializeDeps(depsMappingJSONPath!!) + CalculateImpactedTargetsInteractor() + .executeWithDistances(from, to, depsMapping, outputWriter, targetType) + } else { + CalculateImpactedTargetsInteractor().execute(from, to, outputWriter, targetType) + } + CommandLine.ExitCode.OK } catch (e: IOException) { - CommandLine.ExitCode.SOFTWARE - }.also { stopKoin() } - } - - private fun validate() { - if (!startingHashesJSONPath.canRead()) { - throw CommandLine.ParameterException( - spec.commandLine(), - "Incorrect starting hashes: file doesn't exist or can't be read." - ) - } - if (!finalHashesJSONPath.canRead()) { - throw CommandLine.ParameterException( - spec.commandLine(), - "Incorrect final hashes: file doesn't exist or can't be read." - ) - } - if (depsMappingJSONPath != null && !depsMappingJSONPath!!.canRead()) { - throw CommandLine.ParameterException( - spec.commandLine(), - "Incorrect dep edges file: file doesn't exist or can't be read." - ) + CommandLine.ExitCode.SOFTWARE } + .also { stopKoin() } + } + + private fun validate() { + if (!startingHashesJSONPath.canRead()) { + throw CommandLine.ParameterException( + spec.commandLine(), "Incorrect starting hashes: file doesn't exist or can't be read.") + } + if (!finalHashesJSONPath.canRead()) { + throw CommandLine.ParameterException( + spec.commandLine(), "Incorrect final hashes: file doesn't exist or can't be read.") + } + if (depsMappingJSONPath != null && !depsMappingJSONPath!!.canRead()) { + throw CommandLine.ParameterException( + spec.commandLine(), "Incorrect dep edges file: file doesn't exist or can't be read.") } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/VersionProvider.kt b/cli/src/main/kotlin/com/bazel_diff/cli/VersionProvider.kt index d57ba82e..c588b113 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/VersionProvider.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/VersionProvider.kt @@ -1,16 +1,18 @@ package com.bazel_diff.cli -import picocli.CommandLine.IVersionProvider import java.io.BufferedReader import java.io.InputStreamReader +import picocli.CommandLine.IVersionProvider class VersionProvider : IVersionProvider { - override fun getVersion(): Array { - val classLoader = this::class.java.classLoader - val inputStream = classLoader.getResourceAsStream("cli/version") - ?: throw IllegalArgumentException("unknown version as version file not found in resources") + override fun getVersion(): Array { + val classLoader = this::class.java.classLoader + val inputStream = + classLoader.getResourceAsStream("cli/version") + ?: throw IllegalArgumentException( + "unknown version as version file not found in resources") - val version = BufferedReader(InputStreamReader(inputStream)).use { it.readText().trim() } - return arrayOf(version) - } + val version = BufferedReader(InputStreamReader(inputStream)).use { it.readText().trim() } + return arrayOf(version) + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/converter/CommaSeparatedValueConverter.kt b/cli/src/main/kotlin/com/bazel_diff/cli/converter/CommaSeparatedValueConverter.kt index a4db71d5..b81bff8b 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/converter/CommaSeparatedValueConverter.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/converter/CommaSeparatedValueConverter.kt @@ -3,7 +3,7 @@ package com.bazel_diff.cli.converter import picocli.CommandLine.ITypeConverter class CommaSeparatedValueConverter : ITypeConverter> { - override fun convert(value: String): Set { - return value.split(",").dropLastWhile { it.isEmpty() }.toSet() - } + override fun convert(value: String): Set { + return value.split(",").dropLastWhile { it.isEmpty() }.toSet() + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/converter/NormalisingPathConverter.kt b/cli/src/main/kotlin/com/bazel_diff/cli/converter/NormalisingPathConverter.kt index 8e6faf17..2626cb9b 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/converter/NormalisingPathConverter.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/converter/NormalisingPathConverter.kt @@ -1,9 +1,9 @@ package com.bazel_diff.cli.converter -import picocli.CommandLine.ITypeConverter import java.io.File import java.nio.file.Path +import picocli.CommandLine.ITypeConverter class NormalisingPathConverter : ITypeConverter { - override fun convert(value: String): Path = File(value).toPath().normalize() + override fun convert(value: String): Path = File(value).toPath().normalize() } diff --git a/cli/src/main/kotlin/com/bazel_diff/cli/converter/OptionsConverter.kt b/cli/src/main/kotlin/com/bazel_diff/cli/converter/OptionsConverter.kt index 2bc1c7f7..b151b3bf 100644 --- a/cli/src/main/kotlin/com/bazel_diff/cli/converter/OptionsConverter.kt +++ b/cli/src/main/kotlin/com/bazel_diff/cli/converter/OptionsConverter.kt @@ -3,7 +3,7 @@ package com.bazel_diff.cli.converter import picocli.CommandLine.ITypeConverter class OptionsConverter : ITypeConverter> { - override fun convert(value: String): List { - return value.split(" ").dropLastWhile { it.isEmpty() } - } + override fun convert(value: String): List { + return value.split(" ").dropLastWhile { it.isEmpty() } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt b/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt index 1bd0b035..7efb826c 100644 --- a/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt +++ b/cli/src/main/kotlin/com/bazel_diff/di/Modules.kt @@ -9,72 +9,70 @@ import com.bazel_diff.log.StderrLogger import com.bazel_diff.process.Redirect import com.bazel_diff.process.process import com.google.gson.GsonBuilder +import java.io.File +import java.nio.file.Path +import java.nio.file.Paths import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.runBlocking import org.koin.core.module.Module import org.koin.core.qualifier.named import org.koin.dsl.module -import java.io.File -import java.nio.file.Path -import java.nio.file.Paths @OptIn(ExperimentalCoroutinesApi::class) fun hasherModule( - workingDirectory: Path, - bazelPath: Path, - contentHashPath: File?, - startupOptions: List, - commandOptions: List, - cqueryOptions: List, - useCquery: Boolean, - keepGoing: Boolean, - trackDeps: Boolean, - fineGrainedHashExternalRepos: Set, - excludeExternalTargets: Boolean, + workingDirectory: Path, + bazelPath: Path, + contentHashPath: File?, + startupOptions: List, + commandOptions: List, + cqueryOptions: List, + useCquery: Boolean, + keepGoing: Boolean, + trackDeps: Boolean, + fineGrainedHashExternalRepos: Set, + excludeExternalTargets: Boolean, ): Module = module { - val cmd: MutableList = ArrayList().apply { - add(bazelPath.toString()) - addAll(startupOptions) - add("info") - add("output_base") - } - val result = runBlocking { - process( - *cmd.toTypedArray(), - stdout = Redirect.CAPTURE, - workingDirectory = workingDirectory.toFile(), - stderr = Redirect.PRINT, - destroyForcibly = true, - ) - } - val outputPath = Paths.get(result.output.single()) - val debug = System.getProperty("DEBUG", "false").equals("true") - single { - BazelQueryService( - workingDirectory, - bazelPath, - startupOptions, - commandOptions, - cqueryOptions, - keepGoing, - debug - ) - } - single { BazelClient(useCquery, fineGrainedHashExternalRepos, excludeExternalTargets) } - single { BuildGraphHasher(get()) } - single { TargetHasher() } - single { RuleHasher(useCquery, trackDeps, fineGrainedHashExternalRepos) } - single { SourceFileHasherImpl(fineGrainedHashExternalRepos) } - single { ExternalRepoResolver(workingDirectory, bazelPath, outputPath) } - single(named("working-directory")) { workingDirectory } - single(named("output-base")) { outputPath } - single { ContentHashProvider(contentHashPath) } + val cmd: MutableList = + ArrayList().apply { + add(bazelPath.toString()) + addAll(startupOptions) + add("info") + add("output_base") + } + val result = runBlocking { + process( + *cmd.toTypedArray(), + stdout = Redirect.CAPTURE, + workingDirectory = workingDirectory.toFile(), + stderr = Redirect.PRINT, + destroyForcibly = true, + ) + } + val outputPath = Paths.get(result.output.single()) + val debug = System.getProperty("DEBUG", "false").equals("true") + single { + BazelQueryService( + workingDirectory, + bazelPath, + startupOptions, + commandOptions, + cqueryOptions, + keepGoing, + debug) + } + single { BazelClient(useCquery, fineGrainedHashExternalRepos, excludeExternalTargets) } + single { BuildGraphHasher(get()) } + single { TargetHasher() } + single { RuleHasher(useCquery, trackDeps, fineGrainedHashExternalRepos) } + single { SourceFileHasherImpl(fineGrainedHashExternalRepos) } + single { ExternalRepoResolver(workingDirectory, bazelPath, outputPath) } + single(named("working-directory")) { workingDirectory } + single(named("output-base")) { outputPath } + single { ContentHashProvider(contentHashPath) } } -fun loggingModule(verbose: Boolean) = module { - single { StderrLogger(verbose) } -} +fun loggingModule(verbose: Boolean) = module { single { StderrLogger(verbose) } } fun serialisationModule() = module { - single { GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create() } + single { GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create() } } diff --git a/cli/src/main/kotlin/com/bazel_diff/extensions/ByteArray.kt b/cli/src/main/kotlin/com/bazel_diff/extensions/ByteArray.kt index 88c4f252..0ec32589 100644 --- a/cli/src/main/kotlin/com/bazel_diff/extensions/ByteArray.kt +++ b/cli/src/main/kotlin/com/bazel_diff/extensions/ByteArray.kt @@ -3,13 +3,13 @@ package com.bazel_diff.extensions import java.nio.charset.StandardCharsets fun ByteArray.toHexString(): String { - val hexChars = ByteArray(size * 2) - for (j in indices) { - val v = get(j).toInt() and 0xFF - hexChars[j * 2] = HEX_ARRAY[v ushr 4] - hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F] - } - return String(hexChars, StandardCharsets.UTF_8) + val hexChars = ByteArray(size * 2) + for (j in indices) { + val v = get(j).toInt() and 0xFF + hexChars[j * 2] = HEX_ARRAY[v ushr 4] + hexChars[j * 2 + 1] = HEX_ARRAY[v and 0x0F] + } + return String(hexChars, StandardCharsets.UTF_8) } private val HEX_ARRAY = "0123456789abcdef".toByteArray(StandardCharsets.US_ASCII) diff --git a/cli/src/main/kotlin/com/bazel_diff/extensions/ByteBuffer.kt b/cli/src/main/kotlin/com/bazel_diff/extensions/ByteBuffer.kt index 136e7e17..98effeda 100644 --- a/cli/src/main/kotlin/com/bazel_diff/extensions/ByteBuffer.kt +++ b/cli/src/main/kotlin/com/bazel_diff/extensions/ByteBuffer.kt @@ -3,8 +3,7 @@ package com.bazel_diff.extensions import java.nio.Buffer import java.nio.ByteBuffer -/** - * Fix for NoSuchMethodError for JRE8 - */ +/** Fix for NoSuchMethodError for JRE8 */ fun ByteBuffer.compatClear() = ((this as Buffer).clear() as ByteBuffer) + fun ByteBuffer.compatFlip() = ((this as Buffer).flip() as ByteBuffer) diff --git a/cli/src/main/kotlin/com/bazel_diff/extensions/HashingExtensions.kt b/cli/src/main/kotlin/com/bazel_diff/extensions/HashingExtensions.kt index 60a2db69..6a7ddfdb 100644 --- a/cli/src/main/kotlin/com/bazel_diff/extensions/HashingExtensions.kt +++ b/cli/src/main/kotlin/com/bazel_diff/extensions/HashingExtensions.kt @@ -10,26 +10,26 @@ import java.io.File import java.io.FileInputStream fun sha256(block: Hasher.() -> Unit): ByteArray { - val hasher = Hashing.sha256().newHasher() - hasher.apply(block) - return hasher.hash().asBytes().clone() + val hasher = Hashing.sha256().newHasher() + hasher.apply(block) + return hasher.hash().asBytes().clone() } fun Hasher.safePutBytes(block: ByteArray?) = block?.let { putBytes(it) } fun Hasher.putFile(file: File) { - BufferedInputStream(FileInputStream(file.absolutePath.toString())).use { stream -> - val buffer = pool.borrow() - val array = buffer!!.array() //Available for non-direct buffers - while (true) { - var length: Int - if (stream.read(array).also { length = it } == -1) break - buffer.compatFlip() - putBytes(array, 0, length) - buffer.compatClear() - } - pool.recycle(buffer) + BufferedInputStream(FileInputStream(file.absolutePath.toString())).use { stream -> + val buffer = pool.borrow() + val array = buffer!!.array() // Available for non-direct buffers + while (true) { + var length: Int + if (stream.read(array).also { length = it } == -1) break + buffer.compatFlip() + putBytes(array, 0, length) + buffer.compatClear() } + pool.recycle(buffer) + } } -private val pool = ByteBufferPool(1024, 10240) //10kb +private val pool = ByteBufferPool(1024, 10240) // 10kb diff --git a/cli/src/main/kotlin/com/bazel_diff/hash/BuildGraphHasher.kt b/cli/src/main/kotlin/com/bazel_diff/hash/BuildGraphHasher.kt index bc3cc77e..2cdbad4c 100644 --- a/cli/src/main/kotlin/com/bazel_diff/hash/BuildGraphHasher.kt +++ b/cli/src/main/kotlin/com/bazel_diff/hash/BuildGraphHasher.kt @@ -7,168 +7,167 @@ import com.bazel_diff.bazel.BazelTarget import com.bazel_diff.extensions.toHexString import com.bazel_diff.log.Logger import com.google.common.collect.Sets -import com.google.devtools.build.lib.query2.proto.proto2api.Build -import java.io.File import java.nio.file.Path import java.util.Calendar -import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap +import java.util.concurrent.atomic.AtomicReference import java.util.stream.Collectors import kotlin.io.path.readBytes -import kotlinx.coroutines.async import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking -import org.koin.core.component.inject import org.koin.core.component.KoinComponent +import org.koin.core.component.inject class BuildGraphHasher(private val bazelClient: BazelClient) : KoinComponent { - private val targetHasher: TargetHasher by inject() - private val sourceFileHasher: SourceFileHasher by inject() - private val logger: Logger by inject() + private val targetHasher: TargetHasher by inject() + private val sourceFileHasher: SourceFileHasher by inject() + private val logger: Logger by inject() - fun hashAllBazelTargetsAndSourcefiles( - seedFilepaths: Set = emptySet(), - ignoredAttrs: Set = emptySet(), - modifiedFilepaths: Set = emptySet() - ): Map { - val (sourceDigests, allTargets) = runBlocking { - val targetsTask = async(Dispatchers.IO) { - bazelClient.queryAllTargets() - } - val allTargets = targetsTask.await() - val sourceTargets = allTargets.filter { it is BazelTarget.SourceFile }.map { it as BazelTarget.SourceFile } + fun hashAllBazelTargetsAndSourcefiles( + seedFilepaths: Set = emptySet(), + ignoredAttrs: Set = emptySet(), + modifiedFilepaths: Set = emptySet() + ): Map { + val (sourceDigests, allTargets) = + runBlocking { + val targetsTask = async(Dispatchers.IO) { bazelClient.queryAllTargets() } + val allTargets = targetsTask.await() + val sourceTargets = + allTargets + .filter { it is BazelTarget.SourceFile } + .map { it as BazelTarget.SourceFile } - val sourceDigestsFuture = async(Dispatchers.IO) { + val sourceDigestsFuture = + async(Dispatchers.IO) { val sourceHashDurationEpoch = Calendar.getInstance().getTimeInMillis() val sourceFileTargets = hashSourcefiles(sourceTargets, modifiedFilepaths) - val sourceHashDuration = Calendar.getInstance().getTimeInMillis() - sourceHashDurationEpoch + val sourceHashDuration = + Calendar.getInstance().getTimeInMillis() - sourceHashDurationEpoch logger.i { "Source file hashes calculated in $sourceHashDuration" } sourceFileTargets - } + } - Pair(sourceDigestsFuture.await(), allTargets) + Pair(sourceDigestsFuture.await(), allTargets) } - val seedForFilepaths = createSeedForFilepaths(seedFilepaths) - return hashAllTargets( - seedForFilepaths, - sourceDigests, - allTargets, - ignoredAttrs, - modifiedFilepaths - ) - } + val seedForFilepaths = createSeedForFilepaths(seedFilepaths) + return hashAllTargets( + seedForFilepaths, sourceDigests, allTargets, ignoredAttrs, modifiedFilepaths) + } - private fun hashSourcefiles( - targets: List, - modifiedFilepaths: Set - ): ConcurrentMap { - val exception = AtomicReference(null) - val result: ConcurrentMap = targets.parallelStream() + private fun hashSourcefiles( + targets: List, + modifiedFilepaths: Set + ): ConcurrentMap { + val exception = AtomicReference(null) + val result: ConcurrentMap = + targets + .parallelStream() .map { sourceFile: BazelTarget.SourceFile -> - val seed = sha256 { - safePutBytes(sourceFile.name.toByteArray()) - for (subinclude in sourceFile.subincludeList) { - safePutBytes(subinclude.toByteArray()) - } - } - try { - val sourceFileTarget = BazelSourceFileTarget(sourceFile.name, seed) - Pair(sourceFileTarget.name, sourceFileHasher.digest(sourceFileTarget, modifiedFilepaths)) - } catch (e: Exception) { - exception.set(e) - null + val seed = sha256 { + safePutBytes(sourceFile.name.toByteArray()) + for (subinclude in sourceFile.subincludeList) { + safePutBytes(subinclude.toByteArray()) } + } + try { + val sourceFileTarget = BazelSourceFileTarget(sourceFile.name, seed) + Pair( + sourceFileTarget.name, + sourceFileHasher.digest(sourceFileTarget, modifiedFilepaths)) + } catch (e: Exception) { + exception.set(e) + null + } } .filter { pair -> pair != null } .collect( Collectors.toConcurrentMap( { pair -> pair!!.first }, { pair -> pair!!.second }, - ) - ) + )) - exception.get()?.let { throw it } - return result - } + exception.get()?.let { throw it } + return result + } - private fun hashAllTargets( - seedHash: ByteArray, - sourceDigests: ConcurrentMap, - allTargets: List, - ignoredAttrs: Set, - modifiedFilepaths: Set - ): Map { - val ruleHashes: ConcurrentMap = ConcurrentHashMap() - val targetToRule: MutableMap = HashMap() - traverseGraph(allTargets, targetToRule) + private fun hashAllTargets( + seedHash: ByteArray, + sourceDigests: ConcurrentMap, + allTargets: List, + ignoredAttrs: Set, + modifiedFilepaths: Set + ): Map { + val ruleHashes: ConcurrentMap = ConcurrentHashMap() + val targetToRule: MutableMap = HashMap() + traverseGraph(allTargets, targetToRule) - return allTargets.parallelStream() - .map { target: BazelTarget -> - val targetDigest = targetHasher.digest( - target, - targetToRule, - sourceDigests, - ruleHashes, - seedHash, - ignoredAttrs, - modifiedFilepaths - ) - Pair(target.name, TargetHash( - target.javaClass.name.substringAfterLast('$'), - targetDigest.overallDigest.toHexString(), - targetDigest.directDigest.toHexString(), - targetDigest.deps, - )) - } - .filter { targetEntry: Pair? -> targetEntry != null } - .collect( - Collectors.toMap( - { obj: Pair -> obj.first }, - { obj: Pair -> obj.second }, - ) - ) - } + return allTargets + .parallelStream() + .map { target: BazelTarget -> + val targetDigest = + targetHasher.digest( + target, + targetToRule, + sourceDigests, + ruleHashes, + seedHash, + ignoredAttrs, + modifiedFilepaths) + Pair( + target.name, + TargetHash( + target.javaClass.name.substringAfterLast('$'), + targetDigest.overallDigest.toHexString(), + targetDigest.directDigest.toHexString(), + targetDigest.deps, + )) + } + .filter { targetEntry: Pair? -> targetEntry != null } + .collect( + Collectors.toMap( + { obj: Pair -> obj.first }, + { obj: Pair -> obj.second }, + )) + } - /** - * Traverses the list of targets and revisits the targets with yet-unknown generating rule - */ - private fun traverseGraph( - allTargets: List, - targetToRule: MutableMap - ) { - var targetsToAnalyse: Set = Sets.newHashSet(allTargets) - while (!targetsToAnalyse.isEmpty()) { - val initialSize = targetsToAnalyse.size - val nextTargets: MutableSet = Sets.newHashSet() - for (target in targetsToAnalyse) { - val targetName = target.name - when (target) { - is BazelTarget.GeneratedFile -> { - targetToRule[target.generatingRuleName]?.let { - targetToRule[targetName] = it - } ?: nextTargets.add(target) - } - is BazelTarget.Rule -> targetToRule[targetName] = target.rule - is BazelTarget.SourceFile -> continue - } - } - val newSize = nextTargets.size - if (newSize >= initialSize) { - throw RuntimeException("Not possible to traverse the build graph") - } - targetsToAnalyse = nextTargets + /** Traverses the list of targets and revisits the targets with yet-unknown generating rule */ + private fun traverseGraph( + allTargets: List, + targetToRule: MutableMap + ) { + var targetsToAnalyse: Set = Sets.newHashSet(allTargets) + while (!targetsToAnalyse.isEmpty()) { + val initialSize = targetsToAnalyse.size + val nextTargets: MutableSet = Sets.newHashSet() + for (target in targetsToAnalyse) { + val targetName = target.name + when (target) { + is BazelTarget.GeneratedFile -> { + targetToRule[target.generatingRuleName]?.let { targetToRule[targetName] = it } + ?: nextTargets.add(target) + } + is BazelTarget.Rule -> targetToRule[targetName] = target.rule + is BazelTarget.SourceFile -> continue } + } + val newSize = nextTargets.size + if (newSize >= initialSize) { + throw RuntimeException("Not possible to traverse the build graph") + } + targetsToAnalyse = nextTargets } + } - private fun createSeedForFilepaths(seedFilepaths: Set): ByteArray { - if (seedFilepaths.isEmpty()) { - return ByteArray(0) - } - return sha256 { - for (path in seedFilepaths) { - putBytes(path.readBytes()) - } - } + private fun createSeedForFilepaths(seedFilepaths: Set): ByteArray { + if (seedFilepaths.isEmpty()) { + return ByteArray(0) + } + return sha256 { + for (path in seedFilepaths) { + putBytes(path.readBytes()) + } } + } } diff --git a/cli/src/main/kotlin/com/bazel_diff/hash/ExternalRepoResolver.kt b/cli/src/main/kotlin/com/bazel_diff/hash/ExternalRepoResolver.kt index 91077544..79f34e4f 100644 --- a/cli/src/main/kotlin/com/bazel_diff/hash/ExternalRepoResolver.kt +++ b/cli/src/main/kotlin/com/bazel_diff/hash/ExternalRepoResolver.kt @@ -3,68 +3,70 @@ package com.bazel_diff.hash import com.bazel_diff.log.Logger import com.google.common.cache.CacheBuilder import com.google.common.cache.CacheLoader -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject class ExternalRepoResolver( private val workingDirectory: Path, private val bazelPath: Path, private val outputBase: Path, ) : KoinComponent { - private val logger: Logger by inject() + private val logger: Logger by inject() - private val externalRoot: Path by lazy { - outputBase.resolve("external") - } + private val externalRoot: Path by lazy { outputBase.resolve("external") } - private val cache = CacheBuilder.newBuilder().build(CacheLoader.from { repoName: String -> - val externalRepoRoot = externalRoot.resolve(repoName) - if (Files.exists(externalRepoRoot)) { - return@from externalRepoRoot - } - resolveBzlModPath(repoName) - }) + private val cache = + CacheBuilder.newBuilder() + .build( + CacheLoader.from { repoName: String -> + val externalRepoRoot = externalRoot.resolve(repoName) + if (Files.exists(externalRepoRoot)) { + return@from externalRepoRoot + } + resolveBzlModPath(repoName) + }) - fun resolveExternalRepoRoot(repoName: String): Path { - return cache.get(repoName) - } + fun resolveExternalRepoRoot(repoName: String): Path { + return cache.get(repoName) + } - private fun resolveBzlModPath(repoName: String): Path { - // Query result line should look something like "/external//some/bazel/target: