mq-bridge-py-basic 0.4.11__tar.gz → 0.4.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/ci.yml +8 -3
  2. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/conda.yml +1 -1
  3. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/publish-node.yml +2 -2
  4. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/release.yml +9 -6
  5. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.gitignore +1 -0
  6. mq_bridge_py_basic-0.4.12/.justfile +465 -0
  7. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/CHANGELOG.md +196 -11
  8. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/CLAUDE.md +2 -1
  9. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/CONTRIBUTING.md +12 -1
  10. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/Cargo.lock +5 -5
  11. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/Cargo.toml +53 -9
  12. mq_bridge_py_basic-0.4.12/LICENSE +19 -0
  13. mq_bridge_py_basic-0.4.12/LICENSE-APACHE +201 -0
  14. mq_bridge_py_basic-0.4.12/LICENSE-APACHE.python +201 -0
  15. mq_bridge_py_basic-0.4.12/LICENSE.python +19 -0
  16. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/PKG-INFO +5 -2
  17. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/README.md +16 -6
  18. mq_bridge_py_basic-0.4.12/benches/ETL_BENCHMARKS.md +85 -0
  19. mq_bridge_py_basic-0.4.12/benches/csv_to_json_bench.rs +134 -0
  20. mq_bridge_py_basic-0.4.12/benches/middleware_expr_bench.rs +112 -0
  21. mq_bridge_py_basic-0.4.12/benches/pack_bench.rs +298 -0
  22. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/bindings-common/Cargo.toml +1 -1
  23. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/build.rs +8 -2
  24. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/DELIVERY.md +17 -6
  25. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/REFERENCE.md +145 -5
  26. mq_bridge_py_basic-0.4.12/docs/THIRD_PARTY_LICENSES.md +62 -0
  27. mq_bridge_py_basic-0.4.12/docs/assets/copy-demo.png +0 -0
  28. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq-bridge.schema.json +94 -0
  29. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/config.py +6 -0
  30. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/config.pyi +17 -0
  31. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/pyproject.toml +3 -2
  32. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/Cargo.toml +2 -1
  33. mq_bridge_py_basic-0.4.12/python/mq-bridge-py/LICENSE-APACHE.python +201 -0
  34. mq_bridge_py_basic-0.4.12/python/mq-bridge-py/LICENSE.python +19 -0
  35. mq_bridge_py_basic-0.4.12/python/mq-bridge-py/examples/IBM_MQ.md +233 -0
  36. mq_bridge_py_basic-0.4.12/python/mq-bridge-py/examples/ibm-mq-input.py +67 -0
  37. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/pyproject-basic.toml +3 -2
  38. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/pyproject-reduced.toml +3 -2
  39. mq_bridge_py_basic-0.4.12/scripts/mqb-agent.py +253 -0
  40. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/canonical_message.rs +1 -1
  41. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/command_handler.rs +1 -1
  42. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/clickhouse.rs +116 -9
  43. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/dir_spool/mod.rs +1 -1
  44. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/file/mod.rs +384 -128
  45. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/file/tests.rs +297 -0
  46. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/consumer.rs +1 -1
  47. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/dynamic.rs +1 -1
  48. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/mod.rs +1 -1
  49. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/publisher.rs +1 -1
  50. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/server.rs +1 -1
  51. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/http/mod.rs +1 -1
  52. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/http/publisher.rs +1 -1
  53. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/http/tests.rs +1 -1
  54. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/ibm_mq.rs +1 -1
  55. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/endpoint.rs +1 -1
  56. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/framed.rs +1 -1
  57. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/ipc_unix.rs +1 -1
  58. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/ipc_windows.rs +1 -1
  59. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/memory_transport.rs +1 -1
  60. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/mod.rs +1 -1
  61. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/memory/transport.rs +1 -1
  62. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mod.rs +31 -9
  63. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/consumer.rs +1 -1
  64. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/dedup.rs +1 -1
  65. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/publisher.rs +1 -1
  66. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/readers.rs +13 -4
  67. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/tests.rs +1 -1
  68. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/object_store.rs +42 -34
  69. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/poll.rs +1 -1
  70. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/redis_streams.rs +1 -1
  71. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/sled.rs +1 -1
  72. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/sqlx/dedup.rs +1 -1
  73. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/sqlx/mod.rs +12 -4
  74. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/mod.rs +1 -1
  75. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/static_endpoint.rs +1 -1
  76. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/stream_buffer.rs +1 -1
  77. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/websocket.rs +1 -1
  78. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/event_handler.rs +1 -1
  79. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/event_store.rs +1 -1
  80. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/lib.rs +1 -1
  81. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/buffer.rs +1 -1
  82. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/compression.rs +1 -1
  83. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/deduplication.rs +1 -1
  84. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/dlq.rs +1 -1
  85. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/encryption.rs +1 -1
  86. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/filter.rs +431 -78
  87. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/id.rs +1 -1
  88. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/metrics.rs +1 -1
  89. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/mod.rs +20 -4
  90. mq_bridge_py_basic-0.4.12/src/middleware/pack.rs +980 -0
  91. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/coerce.rs +1 -1
  92. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/compiled.rs +201 -14
  93. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/error.rs +1 -1
  94. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/mod.rs +74 -24
  95. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/path.rs +1 -1
  96. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/schema.rs +74 -1
  97. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/transform/tests.rs +133 -1
  98. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models/builders.rs +1 -1
  99. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models/defaults.rs +1 -1
  100. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models/secrets.rs +1 -1
  101. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models/serde_support.rs +1 -1
  102. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models/tests.rs +107 -1
  103. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/models.rs +75 -1
  104. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/conformance.rs +1 -1
  105. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/endpoint.rs +1 -1
  106. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/message.rs +1 -1
  107. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/middleware.rs +1 -1
  108. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/mod.rs +1 -1
  109. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/sdk.rs +1 -1
  110. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/plugin/test_support.rs +1 -1
  111. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/route.rs +33 -11
  112. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/base64_engine.rs +1 -1
  113. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/compression.rs +1 -1
  114. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/compression_pool.rs +1 -1
  115. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/connection_registry.rs +1 -1
  116. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/crypto.rs +1 -1
  117. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/crypto_envelope.rs +1 -1
  118. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/interpolation.rs +1 -1
  119. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/mod.rs +3 -1
  120. mq_bridge_py_basic-0.4.12/src/support/pack.rs +714 -0
  121. mq_bridge_py_basic-0.4.12/src/support/parallel.rs +213 -0
  122. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/plugin_abi.rs +1 -1
  123. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/test_utils.rs +191 -21
  124. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/traits.rs +1 -1
  125. mq_bridge_py_basic-0.4.12/tests/integration/docker-compose/nats.yml +13 -0
  126. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/ipc.rs +1 -1
  127. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/reference_docs_test.rs +39 -0
  128. mq_bridge_py_basic-0.4.11/benches/ETL_BENCHMARKS.md +0 -107
  129. mq_bridge_py_basic-0.4.11/tests/integration/docker-compose/nats.yml +0 -13
  130. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.cargo/config.toml +0 -0
  131. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.dockerignore +0 -0
  132. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  133. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  134. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  135. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/dependabot.yml +0 -0
  136. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/app.yml +0 -0
  137. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/benchmark.yml +0 -0
  138. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/build-node.yml +0 -0
  139. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/docs.yml +0 -0
  140. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/ibm-mq.yml +0 -0
  141. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/node.yml +0 -0
  142. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/publish-python.yml +0 -0
  143. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/python.yml +0 -0
  144. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/.github/workflows/test-matrix.yml +0 -0
  145. /mq_bridge_py_basic-0.4.11/LICENSE → /mq_bridge_py_basic-0.4.12/LICENSE-MIT +0 -0
  146. /mq_bridge_py_basic-0.4.11/LICENSE.python → /mq_bridge_py_basic-0.4.12/LICENSE-MIT.python +0 -0
  147. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/SECURITY.md +0 -0
  148. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/THIRD_PARTY_LICENSES.txt +0 -0
  149. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/benches/performance_bench.rs +0 -0
  150. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/benches/router_bench.rs +0 -0
  151. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/benches/zeromq_backends.rs +0 -0
  152. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/bindings-common/src/lib.rs +0 -0
  153. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/bindings-common/src/logging.rs +0 -0
  154. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/deny.toml +0 -0
  155. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/ARCHITECTURE.md +0 -0
  156. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/CONFIGURATION.md +0 -0
  157. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/EXTENDING.md +0 -0
  158. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/GRPC.md +0 -0
  159. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/docs/PLUGINS.md +0 -0
  160. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/examples/ipc_worker_queue.yaml +0 -0
  161. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/__init__.py +0 -0
  162. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/__init__.pyi +0 -0
  163. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/plugin_packaging.py +0 -0
  164. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/mq_bridge/py.typed +0 -0
  165. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/package-lock.json +0 -0
  166. /mq_bridge_py_basic-0.4.11/python/mq-bridge-py/LICENSE.python → /mq_bridge_py_basic-0.4.12/python/mq-bridge-py/LICENSE-MIT.python +0 -0
  167. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/README.md +0 -0
  168. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/THIRD_PARTY_LICENSES.txt +0 -0
  169. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/analysis/bench_http_native.py +0 -0
  170. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/example.py +0 -0
  171. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/bench_memory.py +0 -0
  172. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/bench_memory.yaml +0 -0
  173. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/consume_pull.py +0 -0
  174. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/dlt_source.py +0 -0
  175. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/json_route.py +0 -0
  176. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/memory.yaml +0 -0
  177. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/examples/raw_route.py +0 -0
  178. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/scripts/gen_config_types.py +0 -0
  179. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/src/lib.rs +0 -0
  180. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_config_types.py +0 -0
  181. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_custom_endpoint.py +0 -0
  182. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_logging.py +0 -0
  183. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_packaging.py +0 -0
  184. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_performance_smoke.py +0 -0
  185. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_plugin_package.py +0 -0
  186. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_public_api.py +0 -0
  187. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/tests/test_routes.py +0 -0
  188. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/python/mq-bridge-py/uv.lock +0 -0
  189. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/benches/metadata_bench.rs +0 -0
  190. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/debug_ibm_mq_tls.rs +0 -0
  191. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/http/analyze_xctrace_time_profile.py +0 -0
  192. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/http/http_flamegraph.py +0 -0
  193. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/http/mq_bridge_http_profile.rs +0 -0
  194. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/analysis/http/run_http_ladder.sh +0 -0
  195. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/ci/format_bench_output.sh +0 -0
  196. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/httparena/README.md +0 -0
  197. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/httparena/frameworks/mq-bridge-py/Dockerfile +0 -0
  198. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/httparena/frameworks/mq-bridge-py/meta.json +0 -0
  199. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/httparena/frameworks/mq-bridge-py/server.py +0 -0
  200. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/sync-version.mjs +0 -0
  201. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/Python/mq-bridge-py/README.md +0 -0
  202. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/Python/mq-bridge-py/benchmark_config.json +0 -0
  203. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/Python/mq-bridge-py/mq-bridge-py.dockerfile +0 -0
  204. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/Python/mq-bridge-py/server.py +0 -0
  205. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/README.md +0 -0
  206. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/postgres.yml +0 -0
  207. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/seed.sql +0 -0
  208. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/techempower/verify.sh +0 -0
  209. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/the-benchmarker/README.md +0 -0
  210. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/the-benchmarker/python/mq-bridge-py/config.yaml +0 -0
  211. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/the-benchmarker/python/mq-bridge-py/pyproject.toml +0 -0
  212. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/scripts/the-benchmarker/python/mq-bridge-py/server.py +0 -0
  213. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/checkpoint.rs +0 -0
  214. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/amqp.rs +0 -0
  215. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/aws.rs +0 -0
  216. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/dir_spool/tests.rs +0 -0
  217. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/proto/mqbridge/bridge.proto +0 -0
  218. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/grpc/tests.rs +0 -0
  219. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/http/stream.rs +0 -0
  220. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/kafka.rs +0 -0
  221. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mongodb/mod.rs +0 -0
  222. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/mqtt.rs +0 -0
  223. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/nats.rs +0 -0
  224. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/VENDORED.md +0 -0
  225. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/mod.rs +0 -0
  226. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/pgoutput/decoder.rs +0 -0
  227. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/pgoutput/messages.rs +0 -0
  228. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/pgoutput/mod.rs +0 -0
  229. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/pgoutput/registry.rs +0 -0
  230. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/pgoutput/values.rs +0 -0
  231. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/replication.rs +0 -0
  232. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/postgres/state.rs +0 -0
  233. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/sqlx/tests.rs +0 -0
  234. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/fanout.rs +0 -0
  235. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/null.rs +0 -0
  236. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/reader.rs +0 -0
  237. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/request.rs +0 -0
  238. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/response.rs +0 -0
  239. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/structural/switch.rs +0 -0
  240. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/zeromq/codec.rs +0 -0
  241. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/zeromq/mod.rs +0 -0
  242. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/zeromq/omq.rs +0 -0
  243. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/endpoints/zeromq/zmq.rs +0 -0
  244. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/errors.rs +0 -0
  245. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/extensions.rs +0 -0
  246. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/cookie_jar.rs +0 -0
  247. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/deferred_commit.rs +0 -0
  248. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/delay.rs +0 -0
  249. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/limiter.rs +0 -0
  250. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/random_panic.rs +0 -0
  251. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/raw_json.rs +0 -0
  252. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/retry.rs +0 -0
  253. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/middleware/weak_join.rs +0 -0
  254. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/outcomes.rs +0 -0
  255. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/publisher.rs +0 -0
  256. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/response.rs +0 -0
  257. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/support/source_ranges.rs +0 -0
  258. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/src/type_handler.rs +0 -0
  259. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/README.md +0 -0
  260. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/armature_integration.rs +0 -0
  261. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/compat/python/bridge_client.py +0 -0
  262. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/amqp.rs +0 -0
  263. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/aws.rs +0 -0
  264. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/clickhouse.rs +0 -0
  265. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/config.toml +0 -0
  266. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/amqp.yml +0 -0
  267. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/aws.yml +0 -0
  268. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/clickhouse.yml +0 -0
  269. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm-mq-certs/client.crl +0 -0
  270. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm-mq-certs/client.kdb +0 -0
  271. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm-mq-certs/client.p12 +0 -0
  272. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm-mq-certs/client.rdb +0 -0
  273. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm-mq-certs/client.sth +0 -0
  274. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm_mq.yml +0 -0
  275. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/ibm_mq_tls.yml +0 -0
  276. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/kafka-tls.yml +0 -0
  277. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/kafka.yml +0 -0
  278. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mariadb.yml +0 -0
  279. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mongodb-replica.yml +0 -0
  280. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mongodb-tls.yml +0 -0
  281. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mongodb.yml +0 -0
  282. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mosquitto.conf +0 -0
  283. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mosquitto_performance.conf +0 -0
  284. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mosquitto_persistence.conf +0 -0
  285. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mq_init.mqsc +0 -0
  286. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mq_init_tls.mqsc +0 -0
  287. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mqtt.yml +0 -0
  288. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mqtt_performance.yml +0 -0
  289. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/mysql.yml +0 -0
  290. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/object_store.yml +0 -0
  291. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/postgres.yml +0 -0
  292. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/postgres_cdc.yml +0 -0
  293. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/docker-compose/redis.yml +0 -0
  294. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/file.rs +0 -0
  295. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/grpc.rs +0 -0
  296. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/grpc_tls.rs +0 -0
  297. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/http.rs +0 -0
  298. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/http_tls.rs +0 -0
  299. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/ibm_mq.rs +0 -0
  300. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/ibm_mq_tls.rs +0 -0
  301. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/kafka.rs +0 -0
  302. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/kafka_tls.rs +0 -0
  303. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/logic_test.rs +0 -0
  304. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mariadb.rs +0 -0
  305. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/memory.rs +0 -0
  306. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mod.rs +0 -0
  307. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mongodb.rs +0 -0
  308. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mongodb_raw.rs +0 -0
  309. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mongodb_tls.rs +0 -0
  310. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mqtt.rs +0 -0
  311. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/mysql.rs +0 -0
  312. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/nats.rs +0 -0
  313. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/object_store.rs +0 -0
  314. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/performance_static.rs +0 -0
  315. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/postgres.rs +0 -0
  316. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/postgres_cdc.rs +0 -0
  317. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/redis_streams.rs +0 -0
  318. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/route.rs +0 -0
  319. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/scripts/gen_certs.sh +0 -0
  320. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/sqlite.rs +0 -0
  321. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/tls_helpers.rs +0 -0
  322. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/websocket.rs +0 -0
  323. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration/zeromq.rs +0 -0
  324. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/integration_test.rs +0 -0
  325. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/memory_leak_test.rs +0 -0
  326. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/ref_test.rs +0 -0
  327. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/sqlite_test.rs +0 -0
  328. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/tls_example.rs +0 -0
  329. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/unit_tests.md +0 -0
  330. {mq_bridge_py_basic-0.4.11 → mq_bridge_py_basic-0.4.12}/tests/websocket_test.rs +0 -0
@@ -46,7 +46,7 @@ jobs:
46
46
  run: cargo fmt --all -- --check
47
47
 
48
48
  - name: Run clippy
49
- run: cargo clippy --all-targets --all-features -- -D warnings
49
+ run: cargo clippy --all-targets --features lint-all -- -D warnings
50
50
 
51
51
  # Not a workspace default member, so nothing else builds it. It pins the
52
52
  # exhaustive `GrpcConfig` literal a downstream crate would write.
@@ -203,7 +203,12 @@ jobs:
203
203
 
204
204
  - name: Pre-pull docker images
205
205
  run: |
206
- find tests/integration/docker-compose -name "*.yml" | xargs -P 5 -I {} docker compose -f {} pull -q
206
+ # Best-effort cache warm-up: each test pulls what it needs at `compose up`
207
+ # anyway, so a flaky registry must not fail the job before tests run.
208
+ # ibm_mq*.yml is excluded: those tests are gated on a dlopen'd client that
209
+ # is not installed here, and icr.io is the slowest registry in the set.
210
+ find tests/integration/docker-compose -name "*.yml" ! -name "ibm_mq*.yml" \
211
+ | xargs -P 5 -I {} sh -c 'docker compose -f "$1" pull -q || echo "pre-pull failed (non-fatal): $1"' _ {}
207
212
 
208
213
  - name: Install JRE (for keytool)
209
214
  timeout-minutes: 5
@@ -268,7 +273,7 @@ jobs:
268
273
  uses: Swatinem/rust-cache@v2
269
274
 
270
275
  - name: Build documentation (deny warnings)
271
- run: RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps
276
+ run: RUSTDOCFLAGS="-D warnings" cargo doc --features lint-all --no-deps
272
277
 
273
278
  # Supply chain: licenses, banned crates, source registries, RustSec advisories
274
279
  supply-chain:
@@ -53,7 +53,7 @@ jobs:
53
53
  NODE
54
54
 
55
55
  - name: Build, test, and retain conda package
56
- uses: prefix-dev/rattler-build-action@5181e1960c2bbd84537e94b18586475dc1f63309 # v0.2.34
56
+ uses: prefix-dev/rattler-build-action@1ca5f45832f419a46d1326ccc5861d7e14d67c44 # v0.2.39
57
57
  with:
58
58
  recipe-path: apps/mq-bridge-app/packaging/conda/recipe.yaml
59
59
  build-args: --target-platform=${{ matrix.target }} -c conda-forge
@@ -107,8 +107,8 @@ jobs:
107
107
  \`mq-bridge\` package and is selected automatically via optionalDependencies —
108
108
  you install \`mq-bridge\`, not this package directly.
109
109
  EOF
110
- cp LICENSE THIRD_PARTY_LICENSES.txt "$dir/"
111
- node -e "const p='./$dir/package.json',j=require(p);j.description='Prebuilt '+j.name+' binary for the mq-bridge Node.js addon';j.homepage='https://github.com/marcomq/mq-bridge#readme';j.keywords=['mq-bridge','napi','native','prebuilt','addon'];j.files=[...new Set([...(j.files||[]),'THIRD_PARTY_LICENSES.txt'])];require('fs').writeFileSync(p,JSON.stringify(j,null,2)+'\n')"
110
+ cp LICENSE LICENSE-MIT LICENSE-APACHE THIRD_PARTY_LICENSES.txt "$dir/"
111
+ node -e "const p='./$dir/package.json',j=require(p);j.description='Prebuilt '+j.name+' binary for the mq-bridge Node.js addon';j.homepage='https://github.com/marcomq/mq-bridge#readme';j.keywords=['mq-bridge','napi','native','prebuilt','addon'];j.files=[...new Set([...(j.files||[]),'LICENSE-MIT','LICENSE-APACHE','THIRD_PARTY_LICENSES.txt'])];require('fs').writeFileSync(p,JSON.stringify(j,null,2)+'\n')"
112
112
  done
113
113
 
114
114
  - name: Publish platform packages and root
@@ -324,8 +324,11 @@ jobs:
324
324
  # a release must be built from the tag it claims to be.
325
325
  ref: ${{ inputs.tag_name || github.ref }}
326
326
 
327
+ # No `rustflags:` here or in build-release. v1 defaulted it to
328
+ # `-D warnings`; v2 denies the same lints through CARGO_BUILD_WARNINGS
329
+ # instead, and setting RUSTFLAGS would override `[target.*].rustflags`.
327
330
  - name: Install Rust toolchain
328
- uses: actions-rust-lang/setup-rust-toolchain@v1
331
+ uses: actions-rust-lang/setup-rust-toolchain@v2
329
332
  with:
330
333
  toolchain: stable
331
334
 
@@ -478,7 +481,7 @@ jobs:
478
481
  ref: ${{ inputs.tag_name || github.ref }}
479
482
 
480
483
  - name: Install Rust toolchain
481
- uses: actions-rust-lang/setup-rust-toolchain@v1
484
+ uses: actions-rust-lang/setup-rust-toolchain@v2
482
485
  with:
483
486
  toolchain: stable
484
487
  target: ${{ matrix.target }}
@@ -523,7 +526,7 @@ jobs:
523
526
  else
524
527
  cp "target/${{ matrix.target }}/release/mqb" staging/
525
528
  fi
526
- cp apps/mq-bridge-app/LICENSE apps/mq-bridge-app/README.md apps/mq-bridge-app/crates/core/THIRD_PARTY_LICENSES.txt staging/
529
+ cp apps/mq-bridge-app/LICENSE apps/mq-bridge-app/LICENSE-MIT apps/mq-bridge-app/LICENSE-APACHE apps/mq-bridge-app/README.md apps/mq-bridge-app/crates/core/THIRD_PARTY_LICENSES.txt staging/
527
530
  if [ "$RUNNER_OS" == "Windows" ]; then
528
531
  7z a "${ASSET_NAME}.zip" ./staging/*
529
532
  echo "ASSET_PATH=${ASSET_NAME}.zip" >> "$GITHUB_ENV"
@@ -998,7 +1001,7 @@ jobs:
998
1001
  contents: read
999
1002
  steps:
1000
1003
  - name: Download built packages
1001
- uses: actions/download-artifact@v4
1004
+ uses: actions/download-artifact@v8
1002
1005
  with:
1003
1006
  pattern: mq-bridge-app-*
1004
1007
  path: conda-packages
@@ -1011,7 +1014,7 @@ jobs:
1011
1014
  echo "::warning::ANACONDA_API_TOKEN is not configured; packages were built but not published"
1012
1015
  exit 0
1013
1016
  fi
1014
- pipx install anaconda-client
1017
+ pipx install --include-deps anaconda-client
1015
1018
  find conda-packages -type f -name '*.conda' -print0 \
1016
1019
  | xargs -0 anaconda --token "$ANACONDA_API_TOKEN" upload --user marcomq --label main
1017
1020
 
@@ -1271,7 +1274,7 @@ jobs:
1271
1274
 
1272
1275
  - name: Package artifacts
1273
1276
  run: |
1274
- cp apps/mq-bridge-app/LICENSE apps/mq-bridge-app/README.md apps/mq-bridge-app/crates/core/THIRD_PARTY_LICENSES.txt staging/
1277
+ cp apps/mq-bridge-app/LICENSE apps/mq-bridge-app/LICENSE-MIT apps/mq-bridge-app/LICENSE-APACHE apps/mq-bridge-app/README.md apps/mq-bridge-app/crates/core/THIRD_PARTY_LICENSES.txt staging/
1275
1278
  tar -czf mq-bridge-cli-aarch64-unknown-linux-gnu.tar.gz -C staging .
1276
1279
 
1277
1280
  - name: Upload Release Asset
@@ -58,3 +58,4 @@ python/mq-bridge-py/dist/
58
58
  # rattler-build writes here; it sits inside the recipe's source path, so it must be
59
59
  # ignored or the source copy recurses into its own output.
60
60
  /output
61
+ /build
@@ -0,0 +1,465 @@
1
+ # Prescribed actions for mq-bridge. Each recipe is the command
2
+ # .github/workflows/ runs, so a green `just ci` means the PR gate has already
3
+ # been answered locally. When a workflow changes, change it here too.
4
+ #
5
+ # Two cargo workspaces live in this repository: the engine at the root, and the
6
+ # application under apps/mq-bridge-app with its own Cargo.lock. Recipes for the
7
+ # latter are prefixed `app-` and run from inside it.
8
+ #
9
+ # `just` on its own lists everything, grouped.
10
+
11
+ # The feature set for every lint and doc build. NOT `--all-features`: that
12
+ # enables `link-dynamic`, whose build script probes pkg-config for a system
13
+ # librdkafka. See the `lint-all` comment in Cargo.toml.
14
+ lint_features := "lint-all"
15
+
16
+ _default:
17
+ @just --list
18
+
19
+ # Fail early, with instructions, for the recipes that need a protoc the build
20
+ # does not supply itself.
21
+ #
22
+ # The engine's own `grpc` needs none: it carries `vendored-protoc`, which hands
23
+ # its build script a prebuilt binary. What that does not cover is the app
24
+ # workspace, which depends on `pulsar`, whose build script calls protoc and
25
+ # vendors nothing — `std::env::set_var("PROTOC", …)` in the engine's build
26
+ # script sets it only in that process, not in a sibling's. So only the `app-`
27
+ # recipes need this.
28
+ _require-protoc:
29
+ #!/usr/bin/env bash
30
+ if [ -n "${PROTOC:-}" ] && [ -x "${PROTOC:-}" ]; then exit 0; fi
31
+ if command -v protoc >/dev/null 2>&1; then exit 0; fi
32
+ cat >&2 <<'EOF'
33
+ error: protoc not found, and this target does not vendor one.
34
+
35
+ Fedora sudo dnf install protobuf-compiler
36
+ Debian sudo apt-get install protobuf-compiler
37
+ macOS brew install protobuf
38
+ conda-forge <env>/bin/protoc, from the libprotobuf package
39
+ Windows choco install protoc
40
+
41
+ Or point $PROTOC at a binary you already have.
42
+ EOF
43
+ exit 1
44
+
45
+ # Check that the recipes compiling pyo3 have an interpreter to compile against.
46
+ #
47
+ # Only the chain those recipes actually leave pyo3: $PYO3_PYTHON, then
48
+ # $VIRTUAL_ENV, then PATH. $CONDA_PREFIX is deliberately NOT considered — the
49
+ # python recipes unset it, for the reasons documented above that group — so
50
+ # treating it as a candidate here would reject the very recipe that fixes it.
51
+ _require-python:
52
+ #!/usr/bin/env bash
53
+ if [ -n "${PYO3_PYTHON:-}" ]; then
54
+ [ -x "${PYO3_PYTHON}" ] && exit 0
55
+ echo "error: \$PYO3_PYTHON=${PYO3_PYTHON} is not executable." >&2
56
+ exit 1
57
+ fi
58
+ if [ -n "${VIRTUAL_ENV:-}" ]; then
59
+ if [ -x "${VIRTUAL_ENV}/bin/python" ] || [ -x "${VIRTUAL_ENV}/bin/python3" ]; then exit 0; fi
60
+ cat >&2 <<EOF
61
+ error: \$VIRTUAL_ENV=${VIRTUAL_ENV} has no bin/python, and pyo3 prefers it
62
+ over PATH rather than falling through.
63
+
64
+ Clear it, or point \$PYO3_PYTHON at a real interpreter:
65
+ unset VIRTUAL_ENV
66
+ PYO3_PYTHON=\$(command -v python3) just <recipe>
67
+ EOF
68
+ exit 1
69
+ fi
70
+ command -v python3 >/dev/null 2>&1 && exit 0
71
+ echo "error: no python3 on PATH, \$PYO3_PYTHON unset and \$VIRTUAL_ENV unset." >&2
72
+ exit 1
73
+
74
+ # --- Gates --------------------------------------------------------------------
75
+
76
+ [doc('Everything ci.yml gates a PR on, bar the Docker suites')]
77
+ [group('gate')]
78
+ ci: fmt-check lint config-compat check-features test test-no-docker doc
79
+
80
+ [doc('Format the workspace')]
81
+ [group('gate')]
82
+ fmt:
83
+ cargo fmt --all
84
+
85
+ [doc('Fail on unformatted code')]
86
+ [group('gate')]
87
+ fmt-check:
88
+ cargo fmt --all -- --check
89
+
90
+ [doc('Clippy as CI does, warnings denied')]
91
+ [group('gate')]
92
+ lint:
93
+ cargo clippy --all-targets --features {{ lint_features }} -- -D warnings
94
+
95
+ [doc('Build rustdoc, warnings denied')]
96
+ [group('gate')]
97
+ doc:
98
+ RUSTDOCFLAGS="-D warnings" cargo doc --features {{ lint_features }} --no-deps
99
+
100
+ # Not a workspace default member, so nothing else builds it. It pins the
101
+ # exhaustive `GrpcConfig` literal a downstream crate would write.
102
+ [doc('Check the downstream config-compat fixture')]
103
+ [group('gate')]
104
+ config-compat:
105
+ cargo check -p grpc-config-compat
106
+
107
+ # The list mirrors CI's exactly, so a pass here means the same there. `grpc`
108
+ # needs no `vendored-protoc` alongside it: the feature carries it (Cargo.toml).
109
+ [doc('cargo check each feature subset CI covers')]
110
+ [group('gate')]
111
+ check-features:
112
+ #!/usr/bin/env bash
113
+ set -uo pipefail
114
+ failed=""
115
+ for f in "" full kafka nats grpc mqtt mongodb http; do
116
+ echo "::: cargo check --features ${f:-<default>}"
117
+ if [ -z "$f" ]; then
118
+ cargo check --all-targets || failed="$failed <default>"
119
+ else
120
+ cargo check --all-targets --features "$f" || failed="$failed $f"
121
+ fi
122
+ done
123
+ if [ -n "$failed" ]; then echo "FAILED:$failed" >&2; exit 1; fi
124
+
125
+ # A hard gate in CI: an unapproved license, a banned crate or a non-crates.io
126
+ # source is always actionable here.
127
+ [doc('Licenses, bans and sources')]
128
+ [group('gate')]
129
+ deny:
130
+ cargo deny check bans licenses sources
131
+
132
+ # Informational in CI, because every current advisory is in a transitive
133
+ # dependency we cannot upgrade ourselves. deny.toml carries the reasoning.
134
+ [doc('RustSec advisories (never fails)')]
135
+ [group('gate')]
136
+ deny-advisories:
137
+ -cargo deny check advisories
138
+
139
+ # --- Tests --------------------------------------------------------------------
140
+
141
+ [doc('Unit tests, full features')]
142
+ [group('test')]
143
+ test:
144
+ cargo test --lib --features full
145
+
146
+ [doc('Integration tests that need no Docker services')]
147
+ [group('test')]
148
+ test-no-docker:
149
+ cargo test --test ref_test --test sqlite_test --test tls_example --test websocket_test --features full
150
+
151
+ # #[ignore]d, so it has to be named explicitly.
152
+ [doc('Route commit-task JoinSet leak soak')]
153
+ [group('test')]
154
+ test-memory-leak:
155
+ cargo test --test memory_leak_test --features full -- --ignored --nocapture
156
+
157
+ # Compiled once into an archive, as ci.yml does, so the filtered runs need no
158
+ # recompilation.
159
+ [doc('Build the nextest archive for the Docker suites')]
160
+ [group('test')]
161
+ integration-archive:
162
+ cargo nextest archive --release --features full,test-utils \
163
+ --test integration_test --test armature_integration \
164
+ --archive-file nextest-archive.tar.zst
165
+
166
+ # Needs a running Docker daemon, the archive above, and the TLS fixtures from
167
+ # `just integration-certs`. Narrow it with a nextest filter, e.g.
168
+ # `just integration 'binary(integration_test) & test(=test_all_status)'`.
169
+ [doc('Run the Docker suites from the archive; takes a nextest filter')]
170
+ [group('test')]
171
+ integration filter='all()':
172
+ cargo nextest run --archive-file nextest-archive.tar.zst \
173
+ --run-ignored all --no-capture -E '{{ filter }}'
174
+
175
+ [doc('Generate the TLS fixtures the integration services need')]
176
+ [group('test')]
177
+ integration-certs:
178
+ #!/usr/bin/env bash
179
+ set -euo pipefail
180
+ chmod +x tests/integration/scripts/gen_certs.sh
181
+ for svc in mongodb kafka ibm-mq; do ./tests/integration/scripts/gen_certs.sh "$svc"; done
182
+
183
+ # --- Build variants -----------------------------------------------------------
184
+ #
185
+ # Two ways to obtain the C libraries; see "The two build variants" in
186
+ # Cargo.toml. They differ only in librdkafka — SQLite is bundled either way,
187
+ # and IBM MQ reaches both the same way, via runtime dlopen.
188
+
189
+ # librdkafka and SQLite compiled from bundled sources, protoc from the vendored
190
+ # binary, IBM MQ resolved at runtime via dlopen. Needs nothing installed.
191
+ [doc('Self-contained release build (the default variant)')]
192
+ [group('build')]
193
+ build-static:
194
+ cargo build --release --features full
195
+
196
+ # Links librdkafka >= 2.12.1 from the environment via pkg-config. What a
197
+ # conda-forge recipe or a distro package wants, so the shared library stays
198
+ # patchable.
199
+ #
200
+ # Two prerequisites, from two different places, which is why this recipe is
201
+ # more than a cargo line:
202
+ #
203
+ # librdkafka pkg-config. A distro's librdkafka-dev, or
204
+ # `pixi global install librdkafka`. protoc is NOT among them:
205
+ # `grpc` carries `vendored-protoc` either way.
206
+ # SQLite is NOT among them: it is bundled either way, so this variant needs
207
+ # neither libsqlite3 nor the libclang that generating its bindings would have
208
+ # required. See the sqlx dependency in Cargo.toml.
209
+ #
210
+ # The rpath is derived from pkg-config rather than hard-coded, because the
211
+ # shared library generally lives somewhere the loader does not search by
212
+ # default — a conda prefix, a Conan package cache — and a binary linked here
213
+ # would not start without it. rustc does not read LDFLAGS, hence RUSTFLAGS.
214
+ # Appended, so an ambient RUSTFLAGS survives.
215
+ [doc('Link librdkafka from the environment')]
216
+ [group('build')]
217
+ build-dynamic:
218
+ #!/usr/bin/env bash
219
+ set -euo pipefail
220
+ if ! pkg-config --exists rdkafka; then
221
+ echo "error: rdkafka not on PKG_CONFIG_PATH." >&2
222
+ echo " 'just check-native-deps' reports what is missing." >&2
223
+ exit 1
224
+ fi
225
+ for dir in $(pkg-config --libs-only-L rdkafka | tr ' ' '\n' | sed -n 's/^-L//p' | sort -u); do
226
+ RUSTFLAGS="${RUSTFLAGS:-} -C link-arg=-Wl,-rpath,$dir"
227
+ done
228
+ export RUSTFLAGS
229
+ cargo build --release --features full-dynamic
230
+
231
+ # Reports every prerequisite rather than failing on the first, so it is usable
232
+ # as a diagnosis of a broken `build-dynamic`, and tells you how to fix whatever
233
+ # is missing. Exits non-zero if anything is.
234
+ #
235
+ # Advice is accumulated as one array element per output line rather than as
236
+ # multi-line strings: a just recipe body has to stay indented, so a string
237
+ # containing a column-0 line silently ends the recipe.
238
+ #
239
+ # Each remediation leads with `just build-static`, because `full` compiles its
240
+ # own librdkafka and carries a prebuilt protoc — so wanting `full-dynamic` at
241
+ # all is a packaging requirement, and someone who just wants a working build
242
+ # should be told the shorter way out first.
243
+ [doc('Check the environment can satisfy build-dynamic, and how to fix gaps')]
244
+ [group('build')]
245
+ check-native-deps:
246
+ #!/usr/bin/env bash
247
+ missing=0
248
+ advice=()
249
+ say() { advice+=("$@"); }
250
+
251
+ search_path() {
252
+ if [ -n "${PKG_CONFIG_LIBDIR:-}" ]; then
253
+ echo "PKG_CONFIG_LIBDIR=$PKG_CONFIG_LIBDIR (this replaces the built-in path)"
254
+ elif [ -n "${PKG_CONFIG_PATH:-}" ]; then
255
+ echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH, then pkg-config's built-in path"
256
+ else
257
+ echo "pkg-config's built-in path only (PKG_CONFIG_PATH is unset)"
258
+ fi
259
+ }
260
+
261
+ # An rdkafka.pc that exists but is not on the search path is the common
262
+ # case, not the exceptional one: `pixi global install` and `conda install`
263
+ # both place one under their prefix, and neither puts that prefix on
264
+ # PKG_CONFIG_PATH — pixi global exposes binaries only. Look before telling
265
+ # anyone to install something they already have.
266
+ find_rdkafka_pc() {
267
+ local d
268
+ for d in "${HOME}/.pixi/envs"/*/lib/pkgconfig \
269
+ "${CONDA_PREFIX:-/nonexistent}/lib/pkgconfig" \
270
+ .pixi/envs/*/lib/pkgconfig \
271
+ build/conan \
272
+ /opt/homebrew/lib/pkgconfig \
273
+ /usr/local/lib/pkgconfig; do
274
+ # Absolute, always: this path goes into an `export` line the
275
+ # reader will paste, and a relative one only works from the
276
+ # repository root.
277
+ [ -f "$d/rdkafka.pc" ] && (cd "$d" && pwd)
278
+ done
279
+ }
280
+
281
+ advise_rdkafka() {
282
+ say "librdkafka $1." ""
283
+
284
+ local found
285
+ found=$(find_rdkafka_pc | head -1)
286
+ if [ -n "$found" ]; then
287
+ say "It is already installed — pkg-config just cannot see it. Its" \
288
+ "rdkafka.pc is here:" "" " $found" "" \
289
+ "so all that is missing is the search path:" "" \
290
+ " export PKG_CONFIG_PATH=$found\${PKG_CONFIG_PATH:+:\$PKG_CONFIG_PATH}" "" \
291
+ "\`pixi global install\` and \`conda install\` both expose binaries" \
292
+ "rather than libraries, so installing librdkafka does not by itself" \
293
+ "make its .pc discoverable." "" \
294
+ "Currently searching: $(search_path)"
295
+ return
296
+ fi
297
+
298
+ say "Only the dynamic variant needs it. If you do not specifically want" \
299
+ "dynamic linkage, build the self-contained variant instead — it" \
300
+ "compiles its own librdkafka and needs nothing installed:" \
301
+ "" " just build-static" ""
302
+ say "To supply it, any one of:" "" \
303
+ " Fedora sudo dnf install librdkafka-devel" \
304
+ " Debian sudo apt-get install librdkafka-dev" \
305
+ " macOS brew install librdkafka" \
306
+ " pixi pixi global install librdkafka" \
307
+ " conda-forge the librdkafka package" \
308
+ " Conan just conan" ""
309
+ say "then make sure its rdkafka.pc is somewhere pkg-config looks — the" \
310
+ "install alone is often not enough:" "" \
311
+ " export PKG_CONFIG_PATH=/path/to/lib/pkgconfig:\$PKG_CONFIG_PATH" "" \
312
+ "Currently searching: $(search_path)"
313
+ }
314
+
315
+ advise_protoc() {
316
+ say "protoc is not on PATH, and \$PROTOC is unset or not executable." ""
317
+ say "\`build-dynamic\` does not need it — \`grpc\` carries" \
318
+ "\`vendored-protoc\`. The \`app-\` recipes do: the app workspace" \
319
+ "depends on \`pulsar\`, which vendors no protoc." "" \
320
+ " Fedora sudo dnf install protobuf-compiler" \
321
+ " Debian sudo apt-get install protobuf-compiler" \
322
+ " macOS brew install protobuf" \
323
+ " pixi pixi global install libprotobuf" \
324
+ " conda-forge the libprotobuf package" \
325
+ " Windows choco install protoc" ""
326
+ say "or point \$PROTOC at one you already have:" "" \
327
+ " export PROTOC=/path/to/protoc" ""
328
+ }
329
+
330
+ for probe in "rdkafka >= 2.12.1"; do
331
+ name="${probe%% *}"
332
+ if version=$(pkg-config --modversion "$name" 2>/dev/null); then
333
+ if pkg-config "$probe"; then
334
+ printf ' %-10s %s\n' "$name" "$version"
335
+ else
336
+ printf ' %-10s %s TOO OLD, need "%s"\n' "$name" "$version" "$probe"
337
+ advise_rdkafka "is $version, but rdkafka-sys probes for \"$probe\""
338
+ missing=1
339
+ fi
340
+ else
341
+ printf ' %-10s MISSING\n' "$name"
342
+ advise_rdkafka "was not found by pkg-config"
343
+ missing=1
344
+ fi
345
+ done
346
+
347
+ if command -v protoc >/dev/null 2>&1; then
348
+ printf ' %-10s %s\n' protoc "$(protoc --version)"
349
+ elif [ -n "${PROTOC:-}" ] && [ -x "${PROTOC}" ]; then
350
+ printf ' %-10s %s (from $PROTOC)\n' protoc "$("$PROTOC" --version)"
351
+ else
352
+ printf ' %-10s MISSING (not needed by build-dynamic; the app- recipes want it)\n' protoc
353
+ advise_protoc
354
+ fi
355
+
356
+ if [ "$missing" -eq 0 ]; then
357
+ printf '\n all prerequisites satisfied; `just build-dynamic` should work\n'
358
+ exit 0
359
+ fi
360
+
361
+ printf '\n ── how to fix ──\n\n'
362
+ printf ' %s\n' "${advice[@]}"
363
+ exit 1
364
+
365
+ # --- Python bindings ----------------------------------------------------------
366
+ #
367
+ # These recipes drop $CONDA_PREFIX, which CI never has but a local shell often
368
+ # does — `pixi global install` and `conda activate` both export it. It breaks
369
+ # the Python build two different ways:
370
+ #
371
+ # * pyo3-ffi picks its interpreter from $PYO3_PYTHON, then $VIRTUAL_ENV, then
372
+ # $CONDA_PREFIX, and does not fall through when the one it picked is wrong.
373
+ # A prefix with no bin/python fails the build naming a path you never chose.
374
+ # * maturin refuses outright when $VIRTUAL_ENV and $CONDA_PREFIX are *both*
375
+ # set ("Please unset one of them") — and `uv run` always sets the first.
376
+ # This one bites even when $CONDA_PREFIX is a perfectly good env, so
377
+ # pointing $PYO3_PYTHON somewhere valid does not rescue it.
378
+ #
379
+ # uv owns the interpreter for this project (python/mq-bridge-py/.venv), so
380
+ # $CONDA_PREFIX has no say here and dropping it is the fix for both.
381
+
382
+ [doc('Sync the dev environment and build the extension into it')]
383
+ [group('python')]
384
+ py-dev: _require-python
385
+ #!/usr/bin/env bash
386
+ set -euo pipefail
387
+ cd python/mq-bridge-py
388
+ unset CONDA_PREFIX
389
+ uv sync --group dev --no-install-project
390
+ uv run maturin develop
391
+
392
+ [doc('Run the Python test suite')]
393
+ [group('python')]
394
+ py-test:
395
+ #!/usr/bin/env bash
396
+ set -euo pipefail
397
+ cd python/mq-bridge-py
398
+ unset CONDA_PREFIX
399
+ uv run pytest -q
400
+
401
+ # python.yml's regression check that the lean, no-default build still exposes
402
+ # the always-on public API. The two cargo steps run outside uv, as they do in
403
+ # CI, so they need an interpreter of their own — hence _require-python.
404
+ [doc('Lean no-default-features regression tests')]
405
+ [group('python')]
406
+ py-test-lean: _require-python
407
+ #!/usr/bin/env bash
408
+ set -euo pipefail
409
+ unset CONDA_PREFIX
410
+ cargo test -p mq-bridge-py --no-default-features --features http,rustls-ring test_config_schema_is_always_available
411
+ cargo test -p mq-bridge-py --no-default-features --features http,rustls-ring test_module_init_installs_rustls_provider
412
+ cd python/mq-bridge-py
413
+ uv run maturin develop --no-default-features -F http -F rustls-ring -F pyo3/extension-module
414
+ uv run pytest -q tests/test_public_api.py tests/test_config_types.py
415
+
416
+ # --- Application (separate workspace) -----------------------------------------
417
+
418
+ [doc('Everything app.yml gates the app crates on')]
419
+ [group('app')]
420
+ app-ci: app-check app-lint app-test
421
+
422
+ [doc('cargo check the app crates')]
423
+ [group('app')]
424
+ app-check: _require-protoc
425
+ cd apps/mq-bridge-app && cargo check -p mq-bridge-app-core -p mq-bridge-app --all-targets
426
+
427
+ [doc('Clippy the app crates, warnings denied')]
428
+ [group('app')]
429
+ app-lint: _require-protoc
430
+ cd apps/mq-bridge-app && cargo clippy -p mq-bridge-app-core -p mq-bridge-app --all-targets -- -D warnings
431
+
432
+ [doc('Unit and bin tests for the app crates')]
433
+ [group('app')]
434
+ app-test: _require-protoc
435
+ cd apps/mq-bridge-app && cargo test -p mq-bridge-app-core -p mq-bridge-app --lib --bins
436
+
437
+ # Reaches the engine's `link-dynamic` through the passthroughs in crates/core
438
+ # and crates/cli. `--no-default-features` is required: `default = ["full"]`
439
+ # would otherwise be on too and collide with it.
440
+ [doc('The app, linked against the environment libraries')]
441
+ [group('app')]
442
+ app-build-dynamic: _require-protoc
443
+ cd apps/mq-bridge-app && cargo build --release -p mq-bridge-app \
444
+ --no-default-features --features full-dynamic
445
+
446
+ # --- Node bindings ------------------------------------------------------------
447
+
448
+ [doc('cargo check the node bindings as node.yml does')]
449
+ [group('node')]
450
+ node-check:
451
+ cargo check -p mq-bridge-node --no-default-features --features "http middleware schema"
452
+
453
+ # --- Release chores -----------------------------------------------------------
454
+
455
+ # Everything downstream of the root [workspace.package] version is rewritten
456
+ # from it. Pass the new version, or none to re-sync.
457
+ [doc('Set the version everywhere')]
458
+ [group('release')]
459
+ version new='':
460
+ node scripts/sync-version.mjs {{ new }}
461
+
462
+ [doc('Fail if any committed copy of the version has drifted')]
463
+ [group('release')]
464
+ version-check:
465
+ node scripts/sync-version.mjs --check