odctl 1.0.2__tar.gz → 1.2.0__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 (136) hide show
  1. {odctl-1.0.2 → odctl-1.2.0}/.github/renovate.json +9 -1
  2. {odctl-1.0.2 → odctl-1.2.0}/.github/scripts/select-profiles.py +50 -4
  3. {odctl-1.0.2 → odctl-1.2.0}/.github/scripts/smoke.sh +423 -397
  4. odctl-1.2.0/.github/scripts/spark_avro_producer.py +48 -0
  5. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/pipeline.yml +19 -3
  6. {odctl-1.0.2 → odctl-1.2.0}/.pre-commit-config.yaml +9 -0
  7. odctl-1.2.0/CLAUDE.md +59 -0
  8. {odctl-1.0.2 → odctl-1.2.0}/PKG-INFO +4 -2
  9. {odctl-1.0.2 → odctl-1.2.0}/README.md +3 -1
  10. {odctl-1.0.2 → odctl-1.2.0}/mkdocs.yml +38 -6
  11. {odctl-1.0.2 → odctl-1.2.0}/pyproject.toml +3 -1
  12. odctl-1.2.0/scripts/diagrams.py +187 -0
  13. {odctl-1.0.2 → odctl-1.2.0}/scripts/gen_pages.py +83 -1
  14. odctl-1.2.0/scripts/llmstxt_sections.py +31 -0
  15. odctl-1.2.0/scripts/release_notes.py +121 -0
  16. odctl-1.2.0/skills/odctl/SKILL.md +525 -0
  17. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/main.py +7 -6
  18. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-analytics.yml +15 -15
  19. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-flink.yml +2 -2
  20. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-infra.yml +10 -5
  21. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-kafka.yml +16 -20
  22. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-metadata.yml +5 -5
  23. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-mlops.yml +5 -5
  24. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-obsv.yml +7 -7
  25. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-orch.yml +3 -3
  26. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-spark.yml +6 -6
  27. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-store.yml +3 -3
  28. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/fetch_flink_dependencies.sh +7 -0
  29. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/fetch_spark_dependencies.sh +23 -0
  30. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/versions.env +8 -3
  31. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/docker/spark/Dockerfile +4 -2
  32. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/registry.yml +7 -10
  33. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/ui.py +6 -6
  34. {odctl-1.0.2 → odctl-1.2.0}/tests/test_airflow_profile.py +3 -1
  35. {odctl-1.0.2 → odctl-1.2.0}/tests/test_cli.py +18 -0
  36. {odctl-1.0.2 → odctl-1.2.0}/tests/test_compose_profiles.py +61 -4
  37. {odctl-1.0.2 → odctl-1.2.0}/tests/test_docs.py +147 -0
  38. {odctl-1.0.2 → odctl-1.2.0}/tests/test_evidently_profile.py +1 -1
  39. {odctl-1.0.2 → odctl-1.2.0}/tests/test_registry.py +2 -5
  40. odctl-1.2.0/tests/test_release_notes.py +76 -0
  41. {odctl-1.0.2 → odctl-1.2.0}/tests/test_telemetry_profile.py +1 -1
  42. {odctl-1.0.2 → odctl-1.2.0}/tests/test_temporal_profile.py +1 -1
  43. {odctl-1.0.2 → odctl-1.2.0}/uv.lock +229 -3
  44. {odctl-1.0.2 → odctl-1.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  45. {odctl-1.0.2 → odctl-1.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  46. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/build-deps.yml +0 -0
  47. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/build-platform-images.yml +0 -0
  48. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/ci.yml +0 -0
  49. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/e2e-test.yml +0 -0
  50. {odctl-1.0.2 → odctl-1.2.0}/.github/workflows/publish.yml +0 -0
  51. {odctl-1.0.2 → odctl-1.2.0}/.gitignore +0 -0
  52. {odctl-1.0.2 → odctl-1.2.0}/.vscode/settings.json +0 -0
  53. {odctl-1.0.2 → odctl-1.2.0}/LICENSE +0 -0
  54. {odctl-1.0.2 → odctl-1.2.0}/image/demo.gif +0 -0
  55. {odctl-1.0.2 → odctl-1.2.0}/image/diagram.drawio +0 -0
  56. {odctl-1.0.2 → odctl-1.2.0}/image/diagram.png +0 -0
  57. {odctl-1.0.2 → odctl-1.2.0}/scripts/local_links.py +0 -0
  58. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/__init__.py +0 -0
  59. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/config.py +0 -0
  60. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/docker.py +0 -0
  61. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/planner.py +0 -0
  62. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/registry.py +0 -0
  63. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/airflow/odctl_log_config.py +0 -0
  64. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/config.xml +0 -0
  65. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/init.sql +0 -0
  66. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/keeper_config.xml +0 -0
  67. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-11-lite.xml +0 -0
  68. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-11.xml +0 -0
  69. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-12-lite.xml +0 -0
  70. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-12.xml +0 -0
  71. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-21.xml +0 -0
  72. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/macros-22.xml +0 -0
  73. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/clickhouse/users.xml +0 -0
  74. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/compose-deps.yml +0 -0
  75. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/Dockerfile +0 -0
  76. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/build.gradle +0 -0
  77. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/build_connectors.sh +0 -0
  78. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/deps/fetch_standalone_plugins.sh +0 -0
  79. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/docker/airflow/Dockerfile +0 -0
  80. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/docker/mlflow/Dockerfile +0 -0
  81. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/docker/postgres/Dockerfile +0 -0
  82. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/evidently/config.yaml +0 -0
  83. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/feast/feature_store.yaml +0 -0
  84. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/flink/flink-conf.yml +0 -0
  85. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/airflow.json +0 -0
  86. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/clickhouse.json +0 -0
  87. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/feast.json +0 -0
  88. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/flink.json +0 -0
  89. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/fluss.json +0 -0
  90. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/iceberg-catalog.json +0 -0
  91. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/kafka-connect.json +0 -0
  92. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/kafka.json +0 -0
  93. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/karapace.json +0 -0
  94. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/marquez.json +0 -0
  95. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/metabase.json +0 -0
  96. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/mlflow.json +0 -0
  97. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/openmetadata.json +0 -0
  98. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/postgresql.json +0 -0
  99. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/seaweedfs.json +0 -0
  100. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/spark.json +0 -0
  101. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/temporal.json +0 -0
  102. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/trino.json +0 -0
  103. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/dashboards/valkey.json +0 -0
  104. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/odctl-dashboards.yaml +0 -0
  105. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/grafana/sources.yml +0 -0
  106. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/jmx/jmx-exporter.yml +0 -0
  107. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/marquez/marquez.yml +0 -0
  108. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/otelcol/odctl-receivers.yaml +0 -0
  109. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/postgres/01-init-databases.sh +0 -0
  110. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/prometheus/prometheus.yml +0 -0
  111. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/seaweed/s3.json +0 -0
  112. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/spark/log4j2.properties +0 -0
  113. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/spark/metrics.properties +0 -0
  114. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/spark/spark-defaults.conf +0 -0
  115. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/access-control.properties +0 -0
  116. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/catalog/clickhouse.properties +0 -0
  117. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/catalog/iceberg.properties +0 -0
  118. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/catalog/kafka.properties +0 -0
  119. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/catalog/postgres.properties +0 -0
  120. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/catalog/valkey.properties +0 -0
  121. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/group-provider.properties +0 -0
  122. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/groups.txt +0 -0
  123. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/resources/trino/rules.json +0 -0
  124. {odctl-1.0.2 → odctl-1.2.0}/src/odctl/workspace.py +0 -0
  125. {odctl-1.0.2 → odctl-1.2.0}/tests/conftest.py +0 -0
  126. {odctl-1.0.2 → odctl-1.2.0}/tests/test_cli_extended.py +0 -0
  127. {odctl-1.0.2 → odctl-1.2.0}/tests/test_config.py +0 -0
  128. {odctl-1.0.2 → odctl-1.2.0}/tests/test_docker.py +0 -0
  129. {odctl-1.0.2 → odctl-1.2.0}/tests/test_feast_profile.py +0 -0
  130. {odctl-1.0.2 → odctl-1.2.0}/tests/test_grafana_dashboards.py +0 -0
  131. {odctl-1.0.2 → odctl-1.2.0}/tests/test_metrics_collector.py +0 -0
  132. {odctl-1.0.2 → odctl-1.2.0}/tests/test_metrics_jvm.py +0 -0
  133. {odctl-1.0.2 → odctl-1.2.0}/tests/test_metrics_python_services.py +0 -0
  134. {odctl-1.0.2 → odctl-1.2.0}/tests/test_planner.py +0 -0
  135. {odctl-1.0.2 → odctl-1.2.0}/tests/test_postgres_image.py +0 -0
  136. {odctl-1.0.2 → odctl-1.2.0}/tests/test_workspace.py +0 -0
@@ -33,6 +33,14 @@
33
33
  "depNameTemplate": "org.apache.fluss:fluss-client",
34
34
  "datasourceTemplate": "maven"
35
35
  },
36
+ {
37
+ "customType": "regex",
38
+ "description": "Track SPARK_V in versions.env, so the Spark Kafka connector jars follow the apache/spark image tag.",
39
+ "managerFilePatterns": ["/^src/odctl/resources/deps/versions\\.env$/"],
40
+ "matchStrings": ["(?m)^SPARK_V=(?<currentValue>\\S+)\\s*$"],
41
+ "depNameTemplate": "org.apache.spark:spark-sql-kafka-0-10_2.13",
42
+ "datasourceTemplate": "maven"
43
+ },
36
44
  {
37
45
  "customType": "regex",
38
46
  "description": "Track DEB_V in fetch_standalone_plugins.sh, which no built-in manager reads.",
@@ -106,7 +114,7 @@
106
114
  },
107
115
  {
108
116
  "description": "Group Spark and PySpark updates together to prevent Py4J mismatches",
109
- "matchPackageNames": ["apache/spark", "pyspark"],
117
+ "matchPackageNames": ["apache/spark", "pyspark", "org.apache.spark:{/,}**"],
110
118
  "groupName": "Spark Ecosystem"
111
119
  },
112
120
  {
@@ -10,7 +10,8 @@ itself, the registry, the smoke script or the images, still runs everything.
10
10
  Groups are listed here rather than derived, because the grouping is a decision:
11
11
  lite and full variants share a large image, so running them together pays for
12
12
  the pull once. Which compose file each group needs comes from registry.yml, so
13
- the mapping is not repeated.
13
+ the mapping is not repeated, except the profiles a group's case starts from
14
+ another file, listed in ALSO_RUNS.
14
15
 
15
16
  Usage: select-profiles.py <changed-file>...
16
17
  select-profiles.py --all
@@ -56,6 +57,7 @@ GROUPS = [
56
57
  RUN_EVERYTHING = (
57
58
  "src/odctl/",
58
59
  ".github/scripts/smoke.sh",
60
+ ".github/scripts/spark_avro_producer.py",
59
61
  ".github/scripts/select-profiles.py",
60
62
  ".github/workflows/",
61
63
  )
@@ -66,6 +68,43 @@ COMPOSE_PREFIX = "src/odctl/resources/compose-"
66
68
 
67
69
  REGISTRY = Path("src/odctl/resources/registry.yml")
68
70
 
71
+ # smoke.sh starts some profiles from another group's case: the kafka case starts
72
+ # catalog, the flink case starts kafka-lite and feast, the spark case starts
73
+ # kafka-lite, and the fluss case starts flink-lite. A change to that compose file
74
+ # needs these groups as well as the ones the registry maps to it.
75
+ ALSO_RUNS = {
76
+ "compose-infra.yml": ["kafka-lite kafka-full"],
77
+ "compose-kafka.yml": ["flink-lite flink-full", "spark-lite spark-full"],
78
+ "compose-flink.yml": ["fluss"],
79
+ "compose-mlops.yml": ["flink-lite flink-full"],
80
+ }
81
+
82
+ # smoke.sh runs the guide commands in docs/snippets/<guide>/, so a change there
83
+ # needs the groups whose assertions run that guide. A folder missing from this
84
+ # map runs everything, and a test fails until it is added.
85
+ SNIPPET_PREFIX = "docs/snippets/"
86
+ SNIPPET_GROUPS = {
87
+ "kafka": ["kafka-lite kafka-full"],
88
+ "kafka-connect": ["kafka-lite kafka-full"],
89
+ "iceberg-ingestion": ["kafka-lite kafka-full", "flink-lite flink-full"],
90
+ "flink-sql": ["flink-lite flink-full", "mlflow"],
91
+ "fluss": ["fluss"],
92
+ "spark": ["spark-lite spark-full"],
93
+ "clickhouse": ["ch-lite ch-full"],
94
+ "trino-metabase": ["trino", "metabase"],
95
+ "hybrid-search": ["postgres"],
96
+ "storage": ["storage"],
97
+ "valkey": ["valkey"],
98
+ "airflow-dags": ["airflow"],
99
+ "temporal-workers": ["temporal"],
100
+ "mlflow": ["mlflow"],
101
+ "feast-iceberg": ["feast"],
102
+ "evidently-reports": ["evidently"],
103
+ "lineage": ["lineage"],
104
+ "openmetadata": ["metadata"],
105
+ "telemetry": ["telemetry"],
106
+ }
107
+
69
108
 
70
109
  def profile_to_file(registry_path: Path = REGISTRY) -> dict:
71
110
  """Map each profile to the compose file the registry says provides it."""
@@ -94,15 +133,22 @@ def select(changed: list, registry_path: Path = REGISTRY) -> list:
94
133
  if broad:
95
134
  return list(GROUPS)
96
135
 
136
+ snippet_groups = set()
137
+ for c in changed:
138
+ if c.startswith(SNIPPET_PREFIX):
139
+ guide = c[len(SNIPPET_PREFIX) :].split("/")[0]
140
+ if guide not in SNIPPET_GROUPS:
141
+ return list(GROUPS)
142
+ snippet_groups.update(SNIPPET_GROUPS[guide])
143
+
97
144
  mapping = profile_to_file(registry_path)
98
145
  touched_files = {Path(c).name for c in changed if is_compose(c)}
99
- if not touched_files:
100
- return []
101
146
 
102
147
  selected = []
103
148
  for group in GROUPS:
104
149
  files = {mapping.get(p) for p in group.split()}
105
- if files & touched_files:
150
+ also = any(group in ALSO_RUNS.get(name, []) for name in touched_files)
151
+ if files & touched_files or group in snippet_groups or also:
106
152
  selected.append(group)
107
153
  return selected
108
154