glean-parser 16.0.0__tar.gz → 16.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 (171) hide show
  1. {glean_parser-16.0.0 → glean_parser-16.2.0}/CHANGELOG.md +10 -0
  2. {glean_parser-16.0.0 → glean_parser-16.2.0}/PKG-INFO +11 -1
  3. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/history.md +10 -0
  4. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/lint.py +30 -0
  5. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/metrics.py +14 -0
  6. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/parser.py +38 -0
  7. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/schemas/metrics.2-0-0.schema.yaml +0 -1
  8. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/PKG-INFO +11 -1
  9. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/SOURCES.txt +1 -0
  10. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/all_metrics.yaml +2 -2
  11. glean_parser-16.2.0/tests/data/name_too_similar.yaml +31 -0
  12. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_lint.py +16 -0
  13. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_parser.py +45 -25
  14. {glean_parser-16.0.0 → glean_parser-16.2.0}/.circleci/config.yml +0 -0
  15. {glean_parser-16.0.0 → glean_parser-16.2.0}/.editorconfig +0 -0
  16. {glean_parser-16.0.0 → glean_parser-16.2.0}/.github/CODEOWNERS +0 -0
  17. {glean_parser-16.0.0 → glean_parser-16.2.0}/.github/ISSUE_TEMPLATE.md +0 -0
  18. {glean_parser-16.0.0 → glean_parser-16.2.0}/.github/dependabot.yml +0 -0
  19. {glean_parser-16.0.0 → glean_parser-16.2.0}/.github/pull_request_template.md +0 -0
  20. {glean_parser-16.0.0 → glean_parser-16.2.0}/.gitignore +0 -0
  21. {glean_parser-16.0.0 → glean_parser-16.2.0}/.swiftlint.yml +0 -0
  22. {glean_parser-16.0.0 → glean_parser-16.2.0}/AUTHORS.md +0 -0
  23. {glean_parser-16.0.0 → glean_parser-16.2.0}/CODE_OF_CONDUCT.md +0 -0
  24. {glean_parser-16.0.0 → glean_parser-16.2.0}/CONTRIBUTING.md +0 -0
  25. {glean_parser-16.0.0 → glean_parser-16.2.0}/LICENSE +0 -0
  26. {glean_parser-16.0.0 → glean_parser-16.2.0}/MANIFEST.in +0 -0
  27. {glean_parser-16.0.0 → glean_parser-16.2.0}/Makefile +0 -0
  28. {glean_parser-16.0.0 → glean_parser-16.2.0}/README.md +0 -0
  29. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/Makefile +0 -0
  30. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/_static/glean.jpeg +0 -0
  31. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/authors.md +0 -0
  32. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/conf.py +0 -0
  33. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/contributing.md +0 -0
  34. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/index.rst +0 -0
  35. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/installation.md +0 -0
  36. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/make.bat +0 -0
  37. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/metrics-yaml.rst +0 -0
  38. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/pings-yaml.rst +0 -0
  39. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/readme.md +0 -0
  40. {glean_parser-16.0.0 → glean_parser-16.2.0}/docs/tags-yaml.rst +0 -0
  41. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/__init__.py +0 -0
  42. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/__main__.py +0 -0
  43. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/coverage.py +0 -0
  44. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/data_review.py +0 -0
  45. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/go_server.py +0 -0
  46. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/javascript.py +0 -0
  47. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/javascript_server.py +0 -0
  48. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/kotlin.py +0 -0
  49. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/markdown.py +0 -0
  50. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/pings.py +0 -0
  51. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/python_server.py +0 -0
  52. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/ruby_server.py +0 -0
  53. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/rust.py +0 -0
  54. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/rust_server.py +0 -0
  55. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/schemas/metrics.1-0-0.schema.yaml +0 -0
  56. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/schemas/pings.1-0-0.schema.yaml +0 -0
  57. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/schemas/pings.2-0-0.schema.yaml +0 -0
  58. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/schemas/tags.1-0-0.schema.yaml +0 -0
  59. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/swift.py +0 -0
  60. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/tags.py +0 -0
  61. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/data_review.jinja2 +0 -0
  62. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/go_server.jinja2 +0 -0
  63. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/javascript.buildinfo.jinja2 +0 -0
  64. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/javascript.jinja2 +0 -0
  65. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/javascript_server.jinja2 +0 -0
  66. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/kotlin.buildinfo.jinja2 +0 -0
  67. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/kotlin.jinja2 +0 -0
  68. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/markdown.jinja2 +0 -0
  69. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/python_server.jinja2 +0 -0
  70. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/qmldir.jinja2 +0 -0
  71. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/ruby_server.jinja2 +0 -0
  72. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/rust.jinja2 +0 -0
  73. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/rust_server.jinja2 +0 -0
  74. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/templates/swift.jinja2 +0 -0
  75. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/translate.py +0 -0
  76. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/translation_options.py +0 -0
  77. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/util.py +0 -0
  78. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser/validate_ping.py +0 -0
  79. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/dependency_links.txt +0 -0
  80. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/entry_points.txt +0 -0
  81. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/not-zip-safe +0 -0
  82. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/requires.txt +0 -0
  83. {glean_parser-16.0.0 → glean_parser-16.2.0}/glean_parser.egg-info/top_level.txt +0 -0
  84. {glean_parser-16.0.0 → glean_parser-16.2.0}/pytest.ini +0 -0
  85. {glean_parser-16.0.0 → glean_parser-16.2.0}/requirements_dev.txt +0 -0
  86. {glean_parser-16.0.0 → glean_parser-16.2.0}/server_telemetry/sdk-metrics-compat.yaml +0 -0
  87. {glean_parser-16.0.0 → glean_parser-16.2.0}/server_telemetry/server-side-pings.yaml +0 -0
  88. {glean_parser-16.0.0 → glean_parser-16.2.0}/setup.cfg +0 -0
  89. {glean_parser-16.0.0 → glean_parser-16.2.0}/setup.py +0 -0
  90. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/conftest.py +0 -0
  91. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/all_pings.yaml +0 -0
  92. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/bad_ping.yamlx +0 -0
  93. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/core.yaml +0 -0
  94. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/duplicate_labeled.yaml +0 -0
  95. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/duplicate_send_in_ping.yaml +0 -0
  96. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/empty.yaml +0 -0
  97. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/event_key_ordering.yaml +0 -0
  98. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/events_with_types.yaml +0 -0
  99. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/fxa-server-metrics.yaml +0 -0
  100. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/fxa-server-pings.yaml +0 -0
  101. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_custom_ping_only_metrics.yaml +0 -0
  102. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_custom_ping_only_pings.yaml +0 -0
  103. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_events_and_custom_ping_metrics.yaml +0 -0
  104. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_events_and_custom_ping_pings.yaml +0 -0
  105. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_events_only_metrics.yaml +0 -0
  106. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/go_server_metrics_unsupported.yaml +0 -0
  107. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/invalid-ping-names.yaml +0 -0
  108. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/invalid.yamlx +0 -0
  109. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/jwe.yaml +0 -0
  110. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/metric-with-tags.yaml +0 -0
  111. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/mixed-expirations.yaml +0 -0
  112. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/object.yaml +0 -0
  113. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/old_event_api.yamlx +0 -0
  114. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/ordering.yaml +0 -0
  115. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/pings.yaml +0 -0
  116. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rate.yaml +0 -0
  117. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/ruby_server_metrics_unsupported.yaml +0 -0
  118. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/ruby_server_pings_unsupported.yaml +0 -0
  119. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_custom_ping_only_metrics.yaml +0 -0
  120. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_custom_ping_only_pings.yaml +0 -0
  121. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_events_and_custom_ping_metrics.yaml +0 -0
  122. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_events_and_custom_ping_pings.yaml +0 -0
  123. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_events_only_metrics.yaml +0 -0
  124. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/rust_server_metrics_unsupported.yaml +0 -0
  125. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/schema-violation.yaml +0 -0
  126. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/send_if_empty_with_metrics.yaml +0 -0
  127. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_custom_ping_only_compare.go +0 -0
  128. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_custom_ping_only_compare.rs +0 -0
  129. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_events_and_custom_ping_compare.go +0 -0
  130. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_events_and_custom_ping_compare.rs +0 -0
  131. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_events_compare.rb +0 -0
  132. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_events_only_compare.go +0 -0
  133. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_events_only_compare.rs +0 -0
  134. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_metrics_no_events_no_pings.yaml +0 -0
  135. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_metrics_with_event.yaml +0 -0
  136. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/server_pings.yaml +0 -0
  137. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/single_labeled.yaml +0 -0
  138. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/smaller.yaml +0 -0
  139. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/tags.yaml +0 -0
  140. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/telemetry_mirror.yaml +0 -0
  141. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/text.yaml +0 -0
  142. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/text_invalid.yaml +0 -0
  143. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/unknown_ping_used.yaml +0 -0
  144. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/wrong_key.yamlx +0 -0
  145. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/data/yaml_nits.yamlx +0 -0
  146. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/detekt.yml +0 -0
  147. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-go/test.go.tmpl +0 -0
  148. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-js/package.json +0 -0
  149. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-js/test.js.tmpl +0 -0
  150. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-py/test.py +0 -0
  151. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-rb/test.rb.tmpl +0 -0
  152. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test-rs/test.rs.tmpl +0 -0
  153. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_cli.py +0 -0
  154. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_go_server.py +0 -0
  155. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_javascript.py +0 -0
  156. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_javascript_server.py +0 -0
  157. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_kotlin.py +0 -0
  158. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_markdown.py +0 -0
  159. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_metrics.py +0 -0
  160. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_pings.py +0 -0
  161. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_python_server.py +0 -0
  162. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_ruby_server.py +0 -0
  163. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_rust.py +0 -0
  164. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_rust_server.py +0 -0
  165. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_swift.py +0 -0
  166. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_tags.py +0 -0
  167. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_translate.py +0 -0
  168. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_utils.py +0 -0
  169. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/test_validate_ping.py +0 -0
  170. {glean_parser-16.0.0 → glean_parser-16.2.0}/tests/util.py +0 -0
  171. {glean_parser-16.0.0 → glean_parser-16.2.0}/tools/extract_data_categories.py +0 -0
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 16.2.0
6
+
7
+ - New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099))
8
+ - Require `array` or `object` as the root type in object metrics ([#780](https://github.com/mozilla/glean_parser/pull/780))
9
+ - Remove 100-bucket limit for `custom_distribution` metrics ([bug 1940967](https://bugzilla.mozilla.org/show_bug.cgi?id=1940967))
10
+
11
+ ## 16.1.0
12
+
13
+ - Allow specifying a subset of interesting metrics to actually collect. Other metrics will be built, but marked as disabled ([bug 1931277](https://bugzilla.mozilla.org/show_bug.cgi?id=1911165)).
14
+
5
15
  ## 16.0.0
6
16
 
7
17
  - BREAKING CHANGE: Support `follows_collection_enabled` for pings ([#776](https://github.com/mozilla/glean_parser/pull/776))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glean_parser
3
- Version: 16.0.0
3
+ Version: 16.2.0
4
4
  Summary: Parser tools for Mozilla's Glean telemetry
5
5
  Home-page: https://github.com/mozilla/glean_parser
6
6
  Author: The Glean Team
@@ -79,6 +79,16 @@ $ glean_parser check < ping.json
79
79
 
80
80
  ## Unreleased
81
81
 
82
+ ## 16.2.0
83
+
84
+ - New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099))
85
+ - Require `array` or `object` as the root type in object metrics ([#780](https://github.com/mozilla/glean_parser/pull/780))
86
+ - Remove 100-bucket limit for `custom_distribution` metrics ([bug 1940967](https://bugzilla.mozilla.org/show_bug.cgi?id=1940967))
87
+
88
+ ## 16.1.0
89
+
90
+ - Allow specifying a subset of interesting metrics to actually collect. Other metrics will be built, but marked as disabled ([bug 1931277](https://bugzilla.mozilla.org/show_bug.cgi?id=1911165)).
91
+
82
92
  ## 16.0.0
83
93
 
84
94
  - BREAKING CHANGE: Support `follows_collection_enabled` for pings ([#776](https://github.com/mozilla/glean_parser/pull/776))
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 16.2.0
6
+
7
+ - New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099))
8
+ - Require `array` or `object` as the root type in object metrics ([#780](https://github.com/mozilla/glean_parser/pull/780))
9
+ - Remove 100-bucket limit for `custom_distribution` metrics ([bug 1940967](https://bugzilla.mozilla.org/show_bug.cgi?id=1940967))
10
+
11
+ ## 16.1.0
12
+
13
+ - Allow specifying a subset of interesting metrics to actually collect. Other metrics will be built, but marked as disabled ([bug 1931277](https://bugzilla.mozilla.org/show_bug.cgi?id=1911165)).
14
+
5
15
  ## 16.0.0
6
16
 
7
17
  - BREAKING CHANGE: Support `follows_collection_enabled` for pings ([#776](https://github.com/mozilla/glean_parser/pull/776))
@@ -385,6 +385,35 @@ def check_unknown_ping(
385
385
  yield nit
386
386
 
387
387
 
388
+ def check_name_too_similar(
389
+ check_name: str,
390
+ check_type: CheckType,
391
+ all_pings: Dict[str, pings.Ping],
392
+ all_metrics: Dict[str, metrics.Metric],
393
+ parser_config: Dict[str, Any],
394
+ ) -> NitGenerator:
395
+ """
396
+ Check that all metrics identifiers are suitably distinct.
397
+ Require that at least n-1 of the similarly-named metrics must be no_lint'd to dismiss the lint.
398
+
399
+ Current similarity test: the fully-qualified identifier differs solely in punctuation.
400
+ e.g. formautofill.credit_cards and formautofill.creditcards
401
+ """
402
+ seen_metrics: Dict[str, metrics.Metric] = dict()
403
+
404
+ for _, metric in all_metrics.items():
405
+ if check_name in metric.no_lint:
406
+ continue
407
+
408
+ no_punc = metric.identifier().replace("_", "").replace(".", "")
409
+ if no_punc in seen_metrics:
410
+ msg = f"Metric `{metric.identifier()}`'s name is too similar to existing metric `{seen_metrics[no_punc].identifier()}`"
411
+ nit = GlinterNit(check_name, metric.identifier(), msg, check_type)
412
+ yield nit
413
+
414
+ seen_metrics[no_punc] = metric
415
+
416
+
388
417
  # The checks that operate on an entire category of metrics:
389
418
  # {NAME: (function, is_error)}
390
419
  CATEGORY_CHECKS: Dict[
@@ -437,6 +466,7 @@ ALL_OBJECT_CHECKS: Dict[
437
466
  ],
438
467
  ] = {
439
468
  "UNKNOWN_PING_REFERENCED": (check_unknown_ping, CheckType.error),
469
+ "NAME_TOO_SIMILAR": (check_name_too_similar, CheckType.error),
440
470
  }
441
471
 
442
472
 
@@ -509,6 +509,20 @@ class Object(Metric):
509
509
  if None:
510
510
  raise ValueError("`structure` needed for object metric.")
511
511
 
512
+ # Different from `ALLOWED_TYPES`:
513
+ # We _require_ the root type to be an object or array.
514
+ allowed_types = ["object", "array"]
515
+ if "type" not in structure:
516
+ raise ValueError(
517
+ f"missing `type` in object structure. Allowed: {allowed_types}"
518
+ )
519
+ if structure["type"] not in allowed_types:
520
+ raise ValueError(
521
+ "invalid `type` in object structure. found: {}, allowed: {}".format(
522
+ structure["type"], allowed_types
523
+ )
524
+ )
525
+
512
526
  structure = Object._validate_substructure(structure)
513
527
  return structure
514
528
 
@@ -444,6 +444,8 @@ def parse_objects(
444
444
  the metric expires.
445
445
  - `allow_missing_files`: Do not raise a `FileNotFoundError` if any of
446
446
  the input `filepaths` do not exist.
447
+ - `interesting`: Contains an array of interesting metrics/ping files.
448
+ Probes not included in these files will be marked as disabled.
447
449
  """
448
450
  if config is None:
449
451
  config = {}
@@ -465,4 +467,40 @@ def parse_objects(
465
467
  yield from _instantiate_tags(
466
468
  all_objects, sources, content, filepath, config
467
469
  )
470
+
471
+ if config.get("interesting"):
472
+ # We're configured to disable probes not included in the interesting list.
473
+ filepaths = util.ensure_list(config.get("interesting"))
474
+ interesting_metrics_dict: Dict[str, Dict[str, Any]] = dict()
475
+ interesting_metrics_dict.setdefault("metrics", DictWrapper())
476
+ interesting_metrics_dict.setdefault("pings", DictWrapper())
477
+ for filepath in filepaths:
478
+ content, filetype = yield from _load_file(filepath, config)
479
+
480
+ if not isinstance(content, dict):
481
+ raise TypeError(f"Invalid content for {filepath}")
482
+
483
+ for category_key, category_val in sorted(content.items()):
484
+ if category_key.startswith("$"):
485
+ continue
486
+
487
+ interesting_metrics_dict.setdefault(category_key, DictWrapper())
488
+
489
+ if not isinstance(category_val, dict):
490
+ raise TypeError(f"Invalid category_val for {category_key}")
491
+
492
+ for metric_key, metric_val in sorted(category_val.items()):
493
+ interesting_metrics_dict[category_key][metric_key] = metric_val
494
+
495
+ for category_key, category_val in all_objects.items():
496
+ if category_key == "tags":
497
+ continue
498
+
499
+ for metric_key, metric_val in sorted(category_val.items()):
500
+ category_dict = interesting_metrics_dict.get(category_key, {})
501
+ if metric_key not in category_dict:
502
+ obj = all_objects[category_key][metric_key]
503
+ if hasattr(obj, "disabled"):
504
+ obj.disabled = True
505
+
468
506
  return _preprocess_objects(all_objects, config)
@@ -442,7 +442,6 @@ definitions:
442
442
  Required when `type`_ is `custom_distribution`.
443
443
  type: number
444
444
  minimum: 1
445
- maximum: 100
446
445
 
447
446
  histogram_type:
448
447
  title: Histogram type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: glean_parser
3
- Version: 16.0.0
3
+ Version: 16.2.0
4
4
  Summary: Parser tools for Mozilla's Glean telemetry
5
5
  Home-page: https://github.com/mozilla/glean_parser
6
6
  Author: The Glean Team
@@ -79,6 +79,16 @@ $ glean_parser check < ping.json
79
79
 
80
80
  ## Unreleased
81
81
 
82
+ ## 16.2.0
83
+
84
+ - New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099))
85
+ - Require `array` or `object` as the root type in object metrics ([#780](https://github.com/mozilla/glean_parser/pull/780))
86
+ - Remove 100-bucket limit for `custom_distribution` metrics ([bug 1940967](https://bugzilla.mozilla.org/show_bug.cgi?id=1940967))
87
+
88
+ ## 16.1.0
89
+
90
+ - Allow specifying a subset of interesting metrics to actually collect. Other metrics will be built, but marked as disabled ([bug 1931277](https://bugzilla.mozilla.org/show_bug.cgi?id=1911165)).
91
+
82
92
  ## 16.0.0
83
93
 
84
94
  - BREAKING CHANGE: Support `follows_collection_enabled` for pings ([#776](https://github.com/mozilla/glean_parser/pull/776))
@@ -126,6 +126,7 @@ tests/data/invalid.yamlx
126
126
  tests/data/jwe.yaml
127
127
  tests/data/metric-with-tags.yaml
128
128
  tests/data/mixed-expirations.yaml
129
+ tests/data/name_too_similar.yaml
129
130
  tests/data/object.yaml
130
131
  tests/data/old_event_api.yamlx
131
132
  tests/data/ordering.yaml
@@ -72,8 +72,8 @@ all_metrics:
72
72
  <<: *defaults
73
73
  type: custom_distribution
74
74
  range_min: 0
75
- range_max: 100
76
- bucket_count: 10
75
+ range_max: 200
76
+ bucket_count: 201
77
77
  histogram_type: linear
78
78
 
79
79
  uuid:
@@ -0,0 +1,31 @@
1
+ # Any copyright is dedicated to the Public Domain.
2
+ # https://creativecommons.org/publicdomain/zero/1.0/
3
+
4
+ ---
5
+ $schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
6
+
7
+ all_metrics:
8
+ valid_metric: &defaults
9
+ type: counter
10
+ lifetime: ping
11
+ description: for testing
12
+ bugs:
13
+ - https://bugzilla.mozilla.org/123
14
+ data_reviews:
15
+ - http://example.com/
16
+ notification_emails:
17
+ - CHANGE-ME@example.com
18
+ expires: never
19
+
20
+ validmetric:
21
+ <<: *defaults
22
+
23
+ similar_nolint:
24
+ <<: *defaults
25
+ no_lint:
26
+ - NAME_TOO_SIMILAR
27
+
28
+ similar_no_lint:
29
+ <<: *defaults
30
+ no_lint:
31
+ - NAME_TOO_SIMILAR
@@ -508,6 +508,22 @@ def test_unknown_pings_lint():
508
508
  assert "does-not-exist" in nits[0].msg
509
509
 
510
510
 
511
+ def test_name_too_similar_lint():
512
+ """Ensure the 'glinter' reports metrics whose names are too similar."""
513
+ # Note: NAME_TOO_SIMILAR is an all-object lint meaning we need pings for it to work.
514
+ input = [ROOT / "data" / "name_too_similar.yaml", ROOT / "data" / "pings.yaml"]
515
+ all_objects = parser.parse_objects(input)
516
+
517
+ errs = list(all_objects)
518
+ assert len(errs) == 0
519
+
520
+ nits = lint.lint_metrics(all_objects.value, parser_config={})
521
+ assert len(nits) == 1
522
+ assert nits[0].check_name == "NAME_TOO_SIMILAR"
523
+ assert nits[0].name == "all_metrics.validmetric"
524
+ assert "all_metrics.valid_metric" in nits[0].msg
525
+
526
+
511
527
  @pytest.mark.parametrize(
512
528
  "metric, num_nits",
513
529
  [
@@ -573,7 +573,7 @@ def test_custom_distribution():
573
573
  "type": "custom_distribution",
574
574
  "range_min": 0,
575
575
  "range_max": 60000,
576
- "bucket_count": 100,
576
+ "bucket_count": 200,
577
577
  "histogram_type": "exponential",
578
578
  }
579
579
  }
@@ -591,7 +591,6 @@ def test_custom_distribution():
591
591
  "category": {
592
592
  "metric": {
593
593
  "type": "custom_distribution",
594
- "gecko_datapoint": "FROM_GECKO",
595
594
  }
596
595
  }
597
596
  }
@@ -603,27 +602,6 @@ def test_custom_distribution():
603
602
  assert len(errors) == 1
604
603
  assert "`custom_distribution` is missing required parameters" in errors[0]
605
604
 
606
- # Test maximum bucket_count is enforced
607
- contents = [
608
- {
609
- "category": {
610
- "metric": {
611
- "type": "custom_distribution",
612
- "gecko_datapoint": "FROM_GECKO",
613
- "range_max": 60000,
614
- "bucket_count": 101,
615
- "histogram_type": "exponential",
616
- }
617
- }
618
- }
619
- ]
620
-
621
- contents = [util.add_required(x) for x in contents]
622
- all_metrics = parser.parse_objects(contents)
623
- errors = list(all_metrics)
624
- assert len(errors) == 1
625
- assert "101 is greater than" in errors[0]
626
-
627
605
  # Test that correct usage
628
606
  contents = [
629
607
  {
@@ -631,7 +609,7 @@ def test_custom_distribution():
631
609
  "metric": {
632
610
  "type": "custom_distribution",
633
611
  "range_max": 60000,
634
- "bucket_count": 100,
612
+ "bucket_count": 200,
635
613
  "histogram_type": "exponential",
636
614
  }
637
615
  }
@@ -645,7 +623,7 @@ def test_custom_distribution():
645
623
  distribution = all_metrics.value["category"]["metric"]
646
624
  assert distribution.range_min == 1
647
625
  assert distribution.range_max == 60000
648
- assert distribution.bucket_count == 100
626
+ assert distribution.bucket_count == 200
649
627
  assert distribution.histogram_type == metrics.HistogramType.exponential
650
628
 
651
629
 
@@ -727,6 +705,40 @@ def test_do_not_disable_expired():
727
705
  assert metrics["category"]["metric"].disabled is False
728
706
 
729
707
 
708
+ def test_interesting_disables_others():
709
+ # Test that if we get an "interesting" config param, only the metrics in
710
+ # the provided config files are enabled.
711
+
712
+ # We'll have aall_metrics.yaml available loaded.
713
+ all_metrics = ROOT / "data" / "all_metrics.yaml"
714
+ # But, only the metrics in metric-with-tags.yaml are marked as interesting
715
+ # so every other metric will be marked as disabled.
716
+ metrics_with_tags_yaml = ROOT / "data" / "metric-with-tags.yaml"
717
+ interesting = [Path(path) for path in [ metrics_with_tags_yaml ]]
718
+ config = {"interesting": interesting}
719
+
720
+ all_metrics = parser.parse_objects([all_metrics, metrics_with_tags_yaml], config)
721
+ errors = list(all_metrics)
722
+ assert len(errors) == 0
723
+
724
+ interesting_metrics = parser.parse_objects([metrics_with_tags_yaml])
725
+ errors = list(interesting_metrics)
726
+ assert len(errors) == 0
727
+
728
+ metrics = all_metrics.value
729
+ for category_key, category_val in metrics.items():
730
+ if category_key == "tags":
731
+ continue
732
+
733
+ for metric_key, metric_val in sorted(category_val.items()):
734
+ cat = interesting_metrics.value.get(category_key)
735
+ if cat and cat.get(metric_key):
736
+ disabled = cat.get(metric_key).disabled
737
+ else:
738
+ disabled = True
739
+ assert metrics[category_key][metric_key].disabled is disabled
740
+
741
+
730
742
  def test_send_in_pings_restrictions():
731
743
  """Test that invalid ping names are disallowed in `send_in_pings`."""
732
744
  all_metrics = parser.parse_objects(ROOT / "data" / "invalid-ping-names.yaml")
@@ -1239,3 +1251,11 @@ def test_object_invalid():
1239
1251
  errors = list(all_metrics)
1240
1252
  assert len(errors) == 1
1241
1253
  assert "`items` not allowed in object structure" in errors[0]
1254
+
1255
+ structure = {"type": "string"}
1256
+ contents = [{"category": {"metric": {"type": "object", "structure": structure}}}]
1257
+ contents = [util.add_required(x) for x in contents]
1258
+ all_metrics = parser.parse_objects(contents)
1259
+ errors = list(all_metrics)
1260
+ assert len(errors) == 1
1261
+ assert "invalid `type` in object structure." in errors[0]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes