From 04c0b7c5b894061671fd2ae3bc35b643040f3692 Mon Sep 17 00:00:00 2001 From: Ben Linsay Date: Mon, 7 Jul 2025 17:39:30 -0400 Subject: [PATCH] move codegen back to an xtask generating sources in tests was causing circular dependency problems, so we're back to generating sources in an xtask that is completely separate from the rest of the crate. --- .github/workflows/test.yml | 37 +- .protoc-version | 2 +- Cargo.lock | 326 ++++++++++++------ Cargo.toml | 38 +- src/generated/google.protobuf.rs | 12 +- src/xds-descriptors.bin | Bin 1342906 -> 1342939 bytes xtask/Cargo.toml | 24 ++ .../generate_sources.rs => xtask/src/main.rs | 28 +- 8 files changed, 316 insertions(+), 151 deletions(-) create mode 100644 xtask/Cargo.toml rename tests/generate_sources.rs => xtask/src/main.rs (94%) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 699cac6..fc4b32e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,12 +1,12 @@ name: Regression Build and Test -on: +on: push: - branches: [ "main" ] - + branches: ["main"] + pull_request: - branches: [ "main" ] - + branches: ["main"] + env: CARGO_TERM_COLOR: always @@ -15,15 +15,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - - name: Install Protoc - uses: arduino/setup-protoc@v3 - with: - version: "27.3" - - - name: Build - run: cargo build --verbose - - - name: Run tests - run: cargo test --verbose + - uses: actions/checkout@v4 + + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + version: "29.5" + + - name: Build + run: cargo build --verbose + + - name: Regenerate sources and check for uncommitted changes + run: cargo xtask generate check-dirty + + - name: Run tests + run: cargo test --verbose diff --git a/.protoc-version b/.protoc-version index 383283e..6fbdc91 100644 --- a/.protoc-version +++ b/.protoc-version @@ -1 +1 @@ -27.3 +29.5 diff --git a/Cargo.lock b/Cargo.lock index 977dd3b..f76cd0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,56 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +dependencies = [ + "windows-sys 0.60.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.60.2", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -76,12 +126,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.7.1" @@ -103,6 +147,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + [[package]] name = "either" version = "1.13.0" @@ -169,17 +259,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "gimli" version = "0.29.0" @@ -248,6 +327,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.13.0" @@ -317,6 +402,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "pbjson" version = "0.7.0" @@ -381,15 +472,6 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "prettyplease" version = "0.2.22" @@ -470,36 +552,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "regex" version = "1.10.6" @@ -550,9 +602,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" @@ -576,9 +628,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" dependencies = [ "itoa", "memchr", @@ -601,6 +653,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" version = "2.0.76" @@ -765,10 +823,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-sys" @@ -776,7 +840,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -785,7 +849,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", ] [[package]] @@ -794,14 +867,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -810,48 +900,96 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.6.18" @@ -865,21 +1003,11 @@ dependencies = [ name = "xds-api" version = "0.2.0" dependencies = [ - "anyhow", "enum-map", - "glob", "pbjson", - "pbjson-build", "prost", - "prost-build", - "prost-types", - "rand", "serde", - "serde_json", - "toml", "tonic", - "tonic-build", - "xshell", ] [[package]] @@ -898,22 +1026,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547" [[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +name = "xtask" +version = "0.1.0" dependencies = [ - "proc-macro2", - "quote", - "syn", + "anyhow", + "clap", + "glob", + "pbjson-build", + "prost", + "prost-build", + "prost-types", + "serde", + "serde_json", + "toml", + "tonic", + "tonic-build", + "xshell", ] diff --git a/Cargo.toml b/Cargo.toml index 3d2cdf1..4f290a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,38 +11,36 @@ description = """ Protocol buffer types for working with Envoy's xDS APIs. """ keywords = ["grpc", "xds", "envoy"] - # we use std::sync::LazyLock rust-version = "1.81" +[workspace] +members = [".", "xtask"] + +[workspace.dependencies] +pbjson = "0.7" +pbjson-build = "0.7" +prost = "0.13" +prost-build = "0.13" +prost-types = "0.13" +serde = "1.0" +tonic = { version = "0.12", default-features = false } +tonic-build = { version = "0.12", default-features = false } + [lib] doctest = false + [dependencies] enum-map = "2.7" -prost = "0.13" -tonic = { version = "0.12", default-features = false, features = [ +prost.workspace = true +tonic = { workspace = true, default-features = false, features = [ "prost", "codegen", ] } -pbjson = { version = "0.7", optional = true } -serde = { version = "1.0", optional = true } +pbjson = { workspace = true, optional = true } +serde = { workspace = true, optional = true } [features] pbjson = ["dep:pbjson", "dep:serde"] descriptor = [] - -[dev-dependencies] -anyhow = "1" -glob = "0.3" -pbjson-build = "0.7" -prost-build = "0.13" -prost-types = "0.13" -rand = "0.8" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -toml = "0.8" -tonic-build = { version = "0.12", default-features = false, features = [ - "prost", -] } -xshell = "0.2" diff --git a/src/generated/google.protobuf.rs b/src/generated/google.protobuf.rs index 561d297..fbb6752 100644 --- a/src/generated/google.protobuf.rs +++ b/src/generated/google.protobuf.rs @@ -981,12 +981,13 @@ impl ::prost::Name for MessageOptions { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct FieldOptions { + /// NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. /// The ctype option instructs the C++ code generator to use a different /// representation of the field than it normally would. See the specific /// options below. This option is only implemented to support use of /// \[ctype=CORD\] and \[ctype=STRING\] (the default) on non-repeated fields of - /// type "bytes" in the open source release -- sorry, we'll try to include - /// other types in a future version! + /// type "bytes" in the open source release. + /// TODO: make ctype actually deprecated. #[prost( enumeration = "field_options::CType", optional, @@ -1224,8 +1225,6 @@ pub mod field_options { } } /// If set to RETENTION_SOURCE, the option will be omitted from the binary. - /// Note: as of January 2023, support for this is in progress and does not yet - /// have an effect (b/264593489). #[derive( Clone, Copy, @@ -1267,8 +1266,7 @@ pub mod field_options { } /// This indicates the types of entities that the field may apply to when used /// as an option. If it is unset, then the field may be freely used as an - /// option on any kind of entity. Note: as of January 2023, support for this is - /// in progress and does not yet have an effect (b/264593489). + /// option on any kind of entity. #[derive( Clone, Copy, @@ -2207,7 +2205,7 @@ pub enum Edition { Edition2023 = 1000, Edition2024 = 1001, /// Placeholder editions for testing feature resolution. These should not be - /// used or relyed on outside of tests. + /// used or relied on outside of tests. Edition1TestOnly = 1, Edition2TestOnly = 2, Edition99997TestOnly = 99997, diff --git a/src/xds-descriptors.bin b/src/xds-descriptors.bin index 90d8151d9ff7a8488572cc6925b61b774a77cc55..be62276145d5ff24ff4d177fcc7e3e41fe11ceea 100644 GIT binary patch delta 20666 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 IbmDLSA1$nI4gdfE delta 20788 zcmb81d6ZSvweD-L-JP?mq3Tp2P;^DnDUD(qP>45*N$fS6n5aoaEfj}>4>4Eo%k@}7 zXoN_!H6(b+B1#lB2#8S#(&hc;YR*1+W4tlm`=c1=n|rNq z%{Av--CTRqvH$$%_MiVmMF>{MPlhHctSAH{D}J1=J!@#q$gnCoF$uy7RZ;N2nZ{?2?Dx+m+BvGmmJcX#PF-h96&Cz+)nWEg2-Ufzf*}RZrQm<- zHlu=nLHfhz z9+fZe(K9(tS4Ojzbn*o!3~wn_R#a{&RaR7PDfF;fDJr-0Zc5JAl>t|!UtDm(@T*Fd zeJWp7siTj!Bz~@{)1D9{<@*mz{!3RTe6C4 zU0nC_uuSaJoP0&#VirRDru69_>=|)Wsdhr`n<`!8NZ8-hILNk>Q2VB#M<$C*ZNmPR zbn8V6W%NK+i59n%cq;MNEv1mEgy)t*SIbig&n?}1CP!)|stQ4Cy84I1Mzx|)QmwhF zB7|OL!9h=8eWQcEz@EL6BN$z(5dFfdSd*oFKJ;J$IwlWAr+fHJsuq=E;DMX^yV6ii_YM~) zic+c&%&{9zrrWqdow}oMv;Sm6a2{hAFgY82fCScJ~`B2UD7#XH6 zV-nbXfP=d75#m)*in_Br28Ssd80eS+m}Yql5Bn6RSsvrVLYQWGgNGzF!sPd_C`5O7 zD)oHx+!w>%;U!&@9!bP=SAx=SHF~xeR3)8~*hq25Y_GbI38**QtM8f#XlS0&)23tMm>F7A2;KWXK@%$5i+&3&1F z5YWtU2USPpY z4oWfk0-O60CW^H!df2Pz@I00UKadgnu$SwZ$n5Tm4IlN=WpAHx1;5eqQP%_zEgy9Q z5=g~Iz23)aErB%gsCU8$Js^Fb@%WghR@w0gru1W8(m6Sk=m$zeOVcwhJA3p}XICwy z8%v#CwSam{z4~rCu_k;K{V(vY(&!WI2&I=t-}-zEn>f^rY9&GZR4c zq}S9ZdC;>=49I8Fd&m6x%xB7(*r5c^lru?SJmWQ(DMD0|LHLYB&TEbd!SB4FcjNP3 zdfyd2(}yo#dK%b_Y^lMnLtzY?3LW^IB~`w()m}+I`t3bOzdKU zKa?}EkwH+#gufBM)Q@$7#)+O6(yOl=aLfx{b&YE;FaG&=0oKrhCne~7>GaF#AFph` z(cBX4ZrO5Hv^xi41t%ufv4&DPhg$k!$&8hG(XL)NndL@ z`Q$Yjzf6E@yvoj&P;^-19cESpUz>f6*QamtA3_iiaj$yn&Gf9XC)d5|#a)wA#jSyk zwAa&n$DVfa>t4{wbXcS`__|l9H|ijO{0%R#0VCK5tcgTGjW@iyLc+Qt7GWH1@YFlr zNsYIp=Z)>1UVPOx;}DoZ&100`;8pgp%8Q3LcsXZWG`4`}ukKy=;Yb?%xR%YY9G(PppW z&*_S*j~TYv%k|JhG!TQm@2P*;Aqs}#eJ`#|F2Ha=8KQqnyN&z)g@1E~(^9Da<_sqS zs(t7Tr?C+j!)XCEJ`}_KrzHk|oX)=H^tAGtVHbYv1zAzqr+h3$Ws#J+nCTNQXwYuc z7;*&0k6J*DPedI@&N$fy`OU>`<-}~(f^Fr*81XYN=v*R}-1EmPE{^qE$Q~LX7 zWlh9@{)#G%PphU2$6Ph^%9d-#T{mu0OM7(f@m@1eGV5~6q-b3|$9`koq!8>*e|+6h z&AZF{!5K5y?bUZq`r2ZZgc)`&3h7pI2++;aW^uQwa8ZL6?#RYp8<2Or;VKHB{N}H5^t_t5YF3 zP+p@GH4tPqI#J_*)EH>{TU!VYdg<@SAKv$1x%#z~J1FYAa*WDDQm)?_b#NXkFIz|1 zL#C_5F_UuCs?-c+wx?jqx2m{`Q?+=4-A5sqtb#6$jcKoO-O@P|YQ7J2fx~0yCacb_ zQ+jhUh4R)6U+EshZi7Yb*8dAoar~C~52#Dmb#V}? zS*o$SRSM02nJFdvWS~<@7KvYGOw#TzRh?OrIAg%{OHt}xnY7tL76NZ>`p5rq->A76 zg-q3RRb?mJx=ht`Rc(WV)S0WgbWK)})`EiO?{2?m;s|f#-5G_f!*^$eV~BMKe(L-n4eot)uSE2tpBN1Tr1nt60X3ePnljuVN9OYji;2huUAARPT*? zD5Hp=cqpTg`RO5L_ke+lpm<0%_f4i4OE5PrPJ8}r>ZrvTLkz>>%$71;Emn2Thq4=A ztVqc0GYrgCOVSU1cA&TtZ`up zLVaLT)ZGEo_8MmiAa&Qc!2+c1HEytk611;4OMsvP8cP7N#4FAcKwa2c0tnM9Vu^wD zA}U0|>#E}KX_s3D6kk{5{6y7ARDHv#3W6VK_Mm3_4diage(``o-retdEQc_k|e}IPyrp44C}X)-COb$rneN? zBwHA!w-o85WilQjId1$_srQxNc%N$e-k9-MwKPp=KdIQqEBsX@-Sr8PLSlyZ)VxbN zpQQl}zNhT2Tnn(nd&(vQw17t6Q#Ki(1vLAfvdI7uP+)WV`mMcA-CRy2liTKUBC*3} zWs?EA9z>hPsK1q=6v?#oQ97)3$;gi~3&^bWk+K^|ioo%a>S+=$K&hgRJSw?X6VR7W z)2_FTAN6TQAal~EnO|j2`qa$_k)D%2mAE;YxQPqVc2)63`ls856}PLL8KAM)YljOP z5RCwhhk(%UaP&avcetKH}3aCf66g zQaMRn20>12u-n-HL~}sX91zWSI~xFLZnv`mkmhzf8{|ZnJ<8?)KrjIvlMJ0bs_7xRm)eu+W+-|E|a1x2Kc&ozLIbs!9_KFf~Lg|6S`b30-liu-|17dfoomN7|d zxA}#ht}slu`5gISIv-}>6knN)DF`Z{qmtn_#kWZroxoaO8?Jswx2Gag=zhEY4Anh;rnV`Rr2|5u+tZbh@=LT=o z%8Ww%zA~c_zpwNQCSgDoC|3F;ix>Nv0>{75e)_yeyo+DRD8%6}I4dMN)?e^z&3Few z@q$0V%oRYa@PdDYIb{Q}!VCU!BS_|pij;jZJ@d}Nm%fVwdEIn?AbF#G-JNfGKYk-?L89c1tObdZH~d;>1BsG1 z{3Fbyujee_kWsclrfuLiMkZ%T2joD%-dFF=Ydf=Uy&u;nquKZ)74N;3UfTBU=C}MH zuTKnGiap=*tE!Xl*kZK2A$_s!^yUq|J%LFvIY(^pIib2@;CIra?moTvj&IMtQcPy$ zcYMyiGDx{pE(9BWb&}On645|2vUteI+UVPz9gv1M`d!UP0Mg}+{y^t5iQJ8u&m?j; ziqHO*n81STgLZHJmENcivKC|~{6Q92vJ?KmO(==p34h@C?vuQQc~BP0?d=aO_<<^J z&nRRoygl=aY=yUHfhAkv?O9;OD7igTG8RTr(inq>JACDwCb?grGlp!Kci47{C?h-O z9e%Bulz=p}!#{kGwPa3n4Ib$r4ejtxILS7|etKtSb=gk?T|<%~-kEhs_R~AF4#|Fc z=isbIc^cZ8^(aq6JEcd1NkApE^Lg6mzM-do?pIbDRdfQe91;&2N{%^UbG}RFY;BK( zc--Z4WBH}52)L1zEp5AR_a%EWWo6^OCsS57?t6SLwPmuT2FmX7xrMV3UHAA+M>~kF zd;Gz}*og~0$%}n{`pNybUb-*i=Z+Amotr5G|2{W)0^#51bN_4jE8*Yg4={5xPvPI^ zAANi>&*)Fu49|Qp{#)_8aR|iprk?$`2{yGRnfp9G4|AVNe9M#G> z#x`0FL2F>w#6(GEq%|m*We*5JYryrkJ`X066`9uF_)xt!a#}`F1I4tALNX=Og3=6K z1I4s}^r@Ul6GfI}W;*WIx1KUHBj^Od%#1)1Co?l0Izcc~bojlo16h+ff$HD5EIoR0 zQ+noa?l}eMx>F0)oQ$d#syTr@ni$%P;hfb9dvgEgNG)o3|*lREJ%keesR=-jG+L-f{dX6!-C8>1sE2HaU?mN zsQN;%Fi2l-8U7u9GprV7JoQXK3j>>@<|#Z21Dm4;!n06#ey({MxX20AiH+ma2Y-5e zy5-@~BZ00@4KO_z*bC1@HNf;>VDDFeFg+M>zcS5}5ry`P(lL+BC@u852r_0L4)iNAbVvsO!$E26%EDU?si>jc7F8Ca-v$-?0&`m=1Le0t?y%(D zkPcPqW&Zj0YaiXDE_vSd1S#4*AK1|aq|)<2t=Y=jIssc*8C^g|*Ykm0(}0Yw=L6QX z&%}3?vT<0IKDcDZC95)i**C1p_(lCyL9My0qz0B+6&zzOrhxFT3XVI?Hs`^=DmZy` zveWR>*VXCYm+mUA&iG~dTAlHW4yyw@`&8;p#p-}ujL}~<6{~~Z!yJTvbuj2CZS_j5 zz9vxhdg80hGx4nnDyvLMJ!59Dm=}L(EVE>#xM)pKV{%fU{{!l>JT+xCB5STS(tGSR zK?dE^2O@1z%(Ep>y&C66O&49=GU@7;iB0^|{?4*m|0EumaIDmKR9iA5$kt~|P-||F zd8%2shU-T(N;f}Do7)Er{V?mER49jNp zO`v`}>Kr}fD$bgqSA6c)y4$>p9{=tQn^1|NNZq$RQ1~j7{h{e8^ zQ7?nHisM~S@nB>IuPj0bf?Pu~PmEb5`@+c~v+QKQeea5IdBvuoLz`}xFmd9|Lz@1x zW#F~fHcgs%bJL^=P2Zfw6I+^o)-v&iaTCV( zF`)x7{e-y$>F4Co=6ZRG8k0ktp#{><$sq^C(sSXvHYFsH-kV)4P&zd={d8rYzEjyL=*_N{VwI^O_np7;Z8_@Q(LUt4yS)qU z2!mXyplo;V2pOYtsUbDNb3%Jhq%jo{m|Gt$&?VUUt~XZY`TX`S|LbjU)cni@GGomT z?TlEZPq_2LT9c#(VuJZ%f(0_GR!N(S+mHDDy{fo4qmW2i9NG;5WoTz{$cs(JYI1s6 z9Fm!`5F;)QdzzC8g)!pd@bIJQ75t2g=;2U3Q8J>Q|HHUiUu^JLjQA))-K z%!Q18f^Lt790!ij_R$v+OVXJy3~pXhUQEomq`Vk-S^Dk^gZnHiFD5-*CdK9_y5n?W zb$h>6-NQ>(XC0R_*y_x7GOw%-ZFas&PeiLjvh$|nat2!+b{piN%*G)JNO_GE%MzHc zrVCzv@{(6Gewj61&G=>3cr~<1Vrrn%t07wx!!NVOtD!xo^A!G9Lk`lP8h)tOr;Ar_ zyLf%ZF9-GY8NW;y>qEPmRO#treP~w`ApGk?yP5#uUmvoXoUGL+1U97G{_?F$He~d2 z*4dEJ%Pg`XGmp$78^SJT+OAR&^c%uPv-Sd^-w^g6WRf#g5+<9{scYt6u_@!1gV3go zUk*Z>!de$-auC`Sa+WgYk%Q2tu-UA=@Cji!^qAx&Z60}J?)^}G82XJ*dFidMoL+1? zXTqeG6Pw1|&@^Fe(-~vN-#CUT=a^x~96O}xh8wTHe!|2_O=Bm>`ZSIiM^8G}Pn>Yo z#FiUK&5ysb>BVPIap(3l<~FjvD`K$LzE^1`o~6ZFvAQeH#G4}z?Q zg#VWE8sNW$fq9EXC}s2_D4L6HEzw1YV_DIwWK*#myxedzzw2Z_x5|5qpc zzxhCh@MmG%MH>_!@b(Y~<}m1Cr(yGQ5dw3+sS9A9?IAaU#s|DV!pS$YDA)*`K@m`6 zhfEBv26$%}^eeR?6bOpFGl?!jO59b!lAo8WC5j`+)Z#651Z8UBs9jlT_&V!{z=Z|^ zYV68F!&gPd*B9kgWP(7DRpI@01f}@%WhMAWdEaHsBgpzLZzBAoyzh*|FT)_~sf=O- z67zSoS^lJCig%4LUqusX!>=t zeIc)Z>fV@}pZ#Ib$LJ=Q#t`sI*2%mIS|t+N+aFe2BZ`0)_lKQrP>O&y_lG2+n`P}o zK!F2cde$3#iw887Ws=4IKxp4R)8%x*20Q$vB1{KDcF)ETWIzsu%A6po7_=HXJMdaG zPi;1zr*It#c`@2dxRMGv6xIwqN^e`MB-_y%$w~DzenZq6l?+-5QEOyRsyv0LHL@pF zAVjSZ+t$%CX%Ohqlt}$5z4^^k3sWKt`Ifv!fLw;^^z^kiH;kSRw)R8{`Shq{Jp|BC zk2(*`O3=Xch-06;s3Sxan3aCI?&i_6%8BG2WL7zm4D4CuL}I*ILi96BL{!a57p=eP z%sJ&mvV)%!mAt_F4-n0X8ZwP!&ooDfNMIP15Zo07M>H<=(jDs>)7##9pa{--DR%;Q zl`AI`!d+2kJE_nqITzg(k-apYB{$R-+1F^RR22>ZI?u|h=50~Qv$8#Ji|h-z6o#oS zsvdHrK1ft?ok$Yn@wd+(xgcYxhG9WuQw9`)VL@b520$1VMD_$B38{sVoFIx-a)MYG z*}MUWYCv;>0AkOD5hsWq96YKRr1wXvy17%+#FpzO{H*25rfVi~0FW<7h!Z)|-XGZ` zEeNJ^2$O~*EYky#s%cJZ-}%OOABb%Bp-LZZ%ORCClmkq4A^LSxvBVx=q<_DTIKW6& zrdlF#Q9ApblSeLc7D0wZ7P%k?Qe%+|av&C26mcsdXR~Svh(|E#nWyj**F2KZNEANe z49im~=?n{m<`HLDNz^^24SROA81^w|SP<2K#;`zo_Lvw}dR9}29*-*4+MY>n?(v8V zm&;JBMtZh9J#pjZqn10BkkQWa$Q~hp)L0(Xnu|^#DlLzA!(^-Mv}&Yl&!!tUe)6Md zGX|NLp3NAfQ_n_rBT5Yzo{j8A6v+JlY-Bg0Kvs}vBQ~OPe6JxWo=dxR^f~f5=ldG% z`*KKUHC!#bkQ&+PuWG-#;|%YTRhdRIMptDTiPozkdtj#u8m)>(nCluK8m)>>I!Djx z0`=pOXX|LFk-{$#4I@tBC(e8+Yeh!wOD-mON-Hn9m;g#e7ZWvdLRhV1f}ip`qmd61 zR=b$sDKx8HOaP%-?P5YQudnEsIHyKp;uRMYAgTdPOaQUVD=sEF6{6Roimf&#B;ER2 zl9TTnfac>&2xqnmUQ? zH;DaCGJjv+qB%a=)JVGp6q+s0(?DppI8RH8{3GM( zPU7j0oToul0~${QG0aEK)3t@@lc?f=^|WNeKZ(eyiYIEt(cAPIek#AwY@5>zh-TZI zD}Yqo=3D_pvu(15ZlTco*-^C}bAc?R-HQDda*12*vKmUabJ}#qP*n ztpM@G?ue@uv0$x?Y2FKE{^Tcm?#&v}uOK)J@{~sQItv16WUsTJ+zjkD7OWKu?spah zQ4MG;2&BFJ&VqG?=ulK~Uu;ra`u)o&*E!iBJ+BiJ&S)R>$-CZ9X2do+5Yp0&*v_Cp z*k{Cc{sW@ajM(-ZNY7`)w&y^4J|m{*yCll%BoB2*tmdVc{r&S(?}+VD2C=j}JGLho zjcEme**0qdy_g+yWa!7HLj)9ymuK76Z>sH*FhHoEzI$ zdZn27U~a5mn3jICZA)WyXKY3Q7`GrW;{!FvE69`X{If<3DP=23u2uh z^9nL@@$k|(FkfY9 zjM50qE>R26Woc}8o?3tgOJn=(i58&x(wG-fl65&Z3ln^l|Bh zd{3r}=sH~Il?0GJ9y1Zk&a5D6J`pSP>I(=$pa}#ZmVF|wtk+X65UwX;K53B|7zoo7 zG08;z(riIbfKR1ezqqgXR7N2RJr&!0WI@N$Q?b3E1VZst%*P)_8EpP^tjtNTpu+{| zl#$ip>5NH?@pN1;=?n_P^mJ@?)J2p7J`>y5zd-a0=%^%D_)Kh5%{+zbnYhkey8?Ax zUjH&mQFTRZ-#?_220A9m3a-eMk~LsOT(q~Rl!j_WW^4*S8*{;J>?ijHKu0ABz-Ke1 zNEEuJ5%*xol*;UXt20+JjtR(wZW?IR?e`Q=S**8i}Ua;Yh=oloIpL@h}OpHojAZNymO8Kw;(ab1Y+v7v3L^N ztyF5D(pzzGS|*^<+y5q@R~zEsRO>xv_>Hl8ujD-JKHro%%N)cvk>oM? zqkRV2%=9LMjKG=R zWRMSLrss=8a&6f-0iy*1H%<`f5;h%D&)0{A;9t^2O;JaPe58l~XX*%(uM=VTcL5Aq zV8#voZq2EgIhn&`BnTq{H*92s)S9yyB%Z?7nzI=sAiitO@wz=pUR@dIwdRhTi51Np zroSt^EmxYuc;gcVC+FPU&nt}LyeT<7hsm(<#dlM4!StM)!hG$!897FY88!&0b9=5d zWAXXnFN--fx8yuoOMjWOS1|Q_yFsIOl(Y~`0R$%VstaJ1J93;5jqmg&&g@)iEim5? zA#iH}0&2|8>9s(HO_8z3ewup}YkDw^ATU>((ugUczr~YrgWB_Q>YkG6Wq*LcnO@F_ z^K$kMhSIRj%XK#wYd}mtFUQ;YX2uGJWBPfyVfU0wAIP{#OP%KR12O%bnduQgc~|=P z1D|?J({%^W;@{qf&M!Wa3w~QNeyENASS~o%8Xp0*mgIs{^!q3EBx;uBlzC00UXpdo za+NhEmUP0V9AY2~{h*%DVV=yXRrFrACH1nUell0xEg7ieQ17Y1W>3vi>OPt4+>I{= zbzNShJ?vlokAG2WmzqF{#@`6cys8Cwd|l3_xU~Qk*5&L4ffnHPbrPoMSWXJO zoePd`{ASxI-|N-(vhs$GMv!sJy7zXj+MEuBLhST*uImu(Pc4A+?c7nrlJhJl9euZL zxbJzivgh~Ha5wCum+Im*p#z#lRTDD`0oOm z)&f(bSRr>Zn{td88TnF0wEuU3u0jdhCN~`&GHz{~@+xSDC@n$OATD?>r;av-^>z(t z1{@FR;CngyZ4uDxBezuR%7aBR;9$COBA z`9P47$^mnGIjJlm+w%>wTpO#)BC}YvaQ3Wi#U*;?BOuWYTy|Qn0CSBb&pr_Z- z>C1esTXGZ8b(lDQPg`v-@4tS!#|0Ncf@@FS=4600wkLm>$+-e)YEPc8QDob3m;~29 z^D0eDaDgfP&wSF5%$A!nu(Yu+-}d)j-khuVxn5~Gz1ruztp!xw=e(^2G_}upTMO{^ zKId&Cz`6Ux+vnQW;5e9X+tS-RZ}h?P)+DwLIvYw=iLHbA26NG^1+;cB&y~L1I*I`5 z*0vj)yqiyJO{_Px7^c?54hk)RsWq|R{%HYBtqDny4rc=dQ`?U1NV}!eja~{KcByVzmUI(znH%qe|i2A{wn#a;;)*&8vZ)*SIb`=e+B;PS6th# IVZx98H~s9OIsgCw diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 0000000..35f8f86 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1" +clap = { version = "4.5", features = ["derive"] } +glob = "0.3" +pbjson-build.workspace = true +prost.workspace = true +prost-build.workspace = true +prost-types.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json = "1.0" +toml = "0.8" +tonic = { workspace = true, default-features = false, features = [ + "prost", + "codegen", +] } +tonic-build = { workspace = true, default-features = false, features = [ + "prost", +] } +xshell = "0.2" diff --git a/tests/generate_sources.rs b/xtask/src/main.rs similarity index 94% rename from tests/generate_sources.rs rename to xtask/src/main.rs index 60b7981..1d2b825 100644 --- a/tests/generate_sources.rs +++ b/xtask/src/main.rs @@ -6,11 +6,24 @@ use std::{ }; use anyhow::Context; +use clap::{Parser, ValueEnum}; use prost::Message; use prost_build::Module; use prost_types::FileDescriptorSet; use serde::Deserialize; -use xshell::{cmd, Shell}; +use xshell::{Shell, cmd}; + +#[derive(Debug, Parser)] +struct Args { + #[arg(value_enum)] + commands: Vec, +} + +#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)] +enum Commands { + Generate, + CheckDirty, +} /// Generate sources and check that the generated changes have been committed. /// @@ -20,14 +33,14 @@ use xshell::{cmd, Shell}; /// /// These flags are opt-out instead of opt-in so the checks run in CI and fail /// on pushes that get protos and generated sources out-of-sync. -#[test] -fn generate_sources() -> anyhow::Result<()> { +fn main() -> anyhow::Result<()> { + let args = Args::parse(); let sh = Shell::new().unwrap(); - if env::var("XDS_API_SKIP_GEN_SRC").is_err() { + + if args.commands.is_empty() || args.commands.contains(&Commands::Generate) { generate_xds_api(&sh)?; } - - if env::var("XDS_API_SKIP_GEN_SRC_DIRTY_CHECK").is_err() { + if args.commands.is_empty() || args.commands.contains(&Commands::CheckDirty) { check_dirty_repo(&sh)?; } @@ -36,6 +49,9 @@ fn generate_sources() -> anyhow::Result<()> { fn project_root() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("..") + .canonicalize() + .unwrap() } /// Generate the xds-api definitions by downloading protobuf dependencies and running