зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1754474 - Update to Glean 44.0.0 and glean_parser 5.0.1. r=janerik
Differential Revision: https://phabricator.services.mozilla.com/D138446
This commit is contained in:
Родитель
375555b717
Коммит
c6eac14b6e
|
@ -2107,9 +2107,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee21709bc0417a5e2b8ea436717bba01c6851111d3ac096994efa73bb79dab"
|
||||
checksum = "d39b68297fbdd3a9cf37243ab30913542cfce546b4c58a5cd7f4ee9cd9ab3d02"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
|
@ -2127,9 +2127,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6078d68e763d57610d362f34223f856fff64d8d3b1c8974833c9fa02a971f59c"
|
||||
checksum = "7b26fe58cf3ba06a2902239e5c26511a1269e57d61214870837b0ac968332616"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
|
@ -2147,9 +2147,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean-ffi"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a33681c61cb007b4d4c19b3cac1a8e74b211f7afe88f179328c04a3bc72ec466"
|
||||
checksum = "30511afa692ca3764711da025e0bcd8f07dd09271d9885ee70fa4c970fe91e41"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"env_logger",
|
||||
|
|
|
@ -36,7 +36,7 @@ allprojects {
|
|||
topsrcdir = gradle.mozconfig.topsrcdir
|
||||
topobjdir = gradle.mozconfig.topobjdir
|
||||
|
||||
gleanVersion = "43.0.2"
|
||||
gleanVersion = "44.0.0"
|
||||
if (gleanVersion != getRustVersionFor("glean")) {
|
||||
throw new StopExecutionException("Mismatched Glean version, expected: ${gleanVersion}," +
|
||||
" found ${getRustVersionFor("glean")}")
|
||||
|
|
|
@ -129,7 +129,7 @@ pth:xpcom/geckoprocesstypes_generator
|
|||
pth:xpcom/idl-parser
|
||||
# glean-sdk may not be installable if a wheel isn't available
|
||||
# and it has to be built from source.
|
||||
pypi-optional:glean-sdk==43.0.2:telemetry will not be collected
|
||||
pypi-optional:glean-sdk==44.0.0:telemetry will not be collected
|
||||
# Mach gracefully handles the case where `psutil` is unavailable.
|
||||
# We aren't (yet) able to pin packages in automation, so we have to
|
||||
# support down to the oldest locally-installed version (5.4.2).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 2.1
|
||||
Name: glean-parser
|
||||
Version: 4.4.0
|
||||
Version: 5.0.1
|
||||
Summary: Parser tools for Mozilla's Glean telemetry
|
||||
Home-page: https://github.com/mozilla/glean_parser
|
||||
Author: Michael Droettboom
|
||||
|
@ -85,6 +85,19 @@ $ glean_parser check < ping.json
|
|||
|
||||
## Unreleased
|
||||
|
||||
## 5.0.1
|
||||
|
||||
- Fix the logic for the metric expiration by version ([bug 1753194](https://bugzilla.mozilla.org/show_bug.cgi?id=1753194))
|
||||
|
||||
## 5.0.0
|
||||
|
||||
- Remove C# support ([#436](https://github.com/mozilla/glean_parser/pull/436)).
|
||||
- Add support for Rust code generation ([bug 1677434](https://bugzilla.mozilla.org/show_bug.cgi?id=1677434))
|
||||
- Report an error if no files are passed ([bug 1751730](https://bugzilla.mozilla.org/show_bug.cgi?id=1751730))
|
||||
- [data-review] Report an error if no metrics match provided bug number ([bug 1752576](https://bugzilla.mozilla.org/show_bug.cgi?id=1752576))
|
||||
- [data-review] Include notification_emails in list of those responsible ([bug 1752576](https://bugzilla.mozilla.org/show_bug.cgi?id=1752576))
|
||||
- Add support for expiring metrics by the provided major version ([bug 1753194](https://bugzilla.mozilla.org/show_bug.cgi?id=1753194))
|
||||
|
||||
## 4.4.0
|
||||
|
||||
- Support global file-level tags in metrics.yaml ([bug 1745283](https://bugzilla.mozilla.org/show_bug.cgi?id=1745283))
|
|
@ -1,37 +1,37 @@
|
|||
glean_parser/__init__.py,sha256=kaoYIRhwZiOE1d8TniW1SHSlEivLBXZQJJ3eiDcamvQ,538
|
||||
glean_parser/__main__.py,sha256=1lA0kuQkEIMZSnG8xYha5dASadwEHI5-MeHmuNqyViA,6509
|
||||
glean_parser/__main__.py,sha256=qX305uTa4EqFFDTpBWoh3i2zwS_TXW3nJPKfdmMoOBI,6769
|
||||
glean_parser/coverage.py,sha256=2IwC4XMDtDamMkBFoYilmqJzW4gyypq65YVCur8SNas,4405
|
||||
glean_parser/csharp.py,sha256=tOrwOLjJCnfie0GvhWvg0Q3fnP4VFQM_4GRaaAqUh4I,5242
|
||||
glean_parser/data_review.py,sha256=SjbeSdmZTTg1a2cTxsrQPRRoQxwqhNMtfUjyK_yrhtw,4767
|
||||
glean_parser/data_review.py,sha256=pTWIg__B6h32G1udHkR3snwjGo2wJ9uRLXA411nzClo,5031
|
||||
glean_parser/javascript.py,sha256=e2hslgxRB56aS2_JVOkatKexrblcz6-XqsDnGuw0MPQ,8150
|
||||
glean_parser/kotlin.py,sha256=V_Toa2ims5GBHOap6nkxL7ShmaaBDb0EPXhxVdjEt9g,12294
|
||||
glean_parser/lint.py,sha256=_N294HLf5-PgGa-oQxb64xcLP24W9874IGheGzjO6jk,17088
|
||||
glean_parser/markdown.py,sha256=0auYAmzIrX0kqmQyq9DKkRRvTE66yAYdrU-YMgLhrpw,8996
|
||||
glean_parser/metrics.py,sha256=Z0gkVMHH-u4eCu_bpsu5JKm9gumZhCz1Jq-xSmHjo8k,11621
|
||||
glean_parser/metrics.py,sha256=o3cjNAA8uCrraYXokcdaaFPOT3yGQ8wvkVPQgkYWcrI,11873
|
||||
glean_parser/parser.py,sha256=OydnNQYHfNW_UKNzZuZCL-ZEAxTlVzsabXNMxmUuht4,15741
|
||||
glean_parser/pings.py,sha256=6XakkO9jnQc2oojLQJvTCMwF7w-BEm6rR54tunCb38o,2805
|
||||
glean_parser/rust.py,sha256=mJ_fd5dfofx30U6eZhBADN53ZfTDLGLDhr0FKmeLeRw,5973
|
||||
glean_parser/swift.py,sha256=fWI41IcVhMaOAta9V1xBm7_Y5AjT_-uGXytiXaxbfzI,7982
|
||||
glean_parser/tags.py,sha256=bemKYvcbMO4JrghiNSe-A4BNNDtx_FlUPkgrPPJy84Y,1391
|
||||
glean_parser/translate.py,sha256=ZyWEEp1bQO2-cneiC-YvbCuTUEra-xgp33X6dkvtgUY,7476
|
||||
glean_parser/util.py,sha256=XWVBr2b5k-GJhx4-_i4JgE2hejCr1q0IbxvfmRFgdsE,15369
|
||||
glean_parser/translate.py,sha256=93pJfbocM81TC9tlt7Gg3-L5KNTme75glEPrF5tenqI,7743
|
||||
glean_parser/util.py,sha256=aahrqfadLSmp9tGjCEKpTgRGEp4yHcqv9MooCeP80iA,16617
|
||||
glean_parser/validate_ping.py,sha256=0TNvILH6dtzJDys3W8Kqorw6kk03me73OCUDtpoHcXU,2118
|
||||
glean_parser/schemas/metrics.1-0-0.schema.yaml,sha256=cND3cvi6iBfPUVmtfIBQfGJV9AALpbvN7nu8E33_J-o,19566
|
||||
glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=lXjTXyAVaBlx7DNjE8Y4PaOs7au2hGTMs8zSnZxV8Tk,23225
|
||||
glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=P5-hNS1Tz-kTo66v4xThU1mS21iwpgjg7CWC4Iybl1E,23886
|
||||
glean_parser/schemas/pings.1-0-0.schema.yaml,sha256=hwCnsKpEysmrmVp-QHGBArEkVY3vaU1rVsxlTwhAzws,4315
|
||||
glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=rD1s-rfz1xC9biHyLfBCnsoQxVYHwpe_S05awfe2xDA,4363
|
||||
glean_parser/schemas/tags.1-0-0.schema.yaml,sha256=OGXIJlvvVW1vaqB_NVZnwKeZ-sLlfH57vjBSHbj6DNI,1231
|
||||
glean_parser/templates/csharp.jinja2,sha256=tPj09JzgSK0YyNb53WkL8WFTA7fcVXyiJ7V-bARnfM0,4354
|
||||
glean_parser/templates/javascript.jinja2,sha256=Qiv0lxsqVABzdME1MRsmezwtwn8_hHdH9S_v8fJAh-E,2647
|
||||
glean_parser/templates/kotlin.buildinfo.jinja2,sha256=m5OngVSjLv4CwpsyNc5Z2O5kixejOXsiIYgzhAkANVA,899
|
||||
glean_parser/templates/kotlin.geckoview.jinja2,sha256=K0c1BeKSXDVbshC3gpWALCQFp2JtsoqWhGyN1ScPhC0,5077
|
||||
glean_parser/templates/kotlin.jinja2,sha256=fsFXKI_fKwj5AEO4odJ5sRvoC5geW59_DhU6GATaA90,4475
|
||||
glean_parser/templates/markdown.jinja2,sha256=tOMN62xEGA1p8QoMKnpCVXUiK_jI5GwLuvCnuOROy8c,3381
|
||||
glean_parser/templates/qmldir.jinja2,sha256=m6IGsp-tgTiOfQ7VN8XW6GqX0gJqJkt3B6Pkaul6FVo,156
|
||||
glean_parser/templates/rust.jinja2,sha256=CtoFNkVB3NFxeTzUIjTxJHmhp2CyhoBap7tkM9SxRWE,10592
|
||||
glean_parser/templates/swift.jinja2,sha256=qDsAANvlIdcZUo_WwE1G_Sbp4XepxBoBGLMbaOmJwjk,5077
|
||||
glean_parser-4.4.0.dist-info/AUTHORS.md,sha256=jBsSsn3EpmpLejgHMhzU1XTFwkCARqYeUs9iGLNgwkQ,432
|
||||
glean_parser-4.4.0.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
||||
glean_parser-4.4.0.dist-info/METADATA,sha256=dyViwyJtouX-bFuMzOeoUluaOZ0Ct9q2Yu1mdRbN8p4,23214
|
||||
glean_parser-4.4.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||
glean_parser-4.4.0.dist-info/entry_points.txt,sha256=s-clJTIqp-PpJD-n3AnIQZFkTafIrzsTbAPX9vNY018,69
|
||||
glean_parser-4.4.0.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
|
||||
glean_parser-4.4.0.dist-info/RECORD,,
|
||||
glean_parser-5.0.1.dist-info/AUTHORS.md,sha256=jBsSsn3EpmpLejgHMhzU1XTFwkCARqYeUs9iGLNgwkQ,432
|
||||
glean_parser-5.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
|
||||
glean_parser-5.0.1.dist-info/METADATA,sha256=ui6vTxp0wDoGzs1jpFbxsGpz157XECoTAOuoxJxAIgo,24079
|
||||
glean_parser-5.0.1.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
||||
glean_parser-5.0.1.dist-info/entry_points.txt,sha256=s-clJTIqp-PpJD-n3AnIQZFkTafIrzsTbAPX9vNY018,69
|
||||
glean_parser-5.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
|
||||
glean_parser-5.0.1.dist-info/RECORD,,
|
|
@ -68,8 +68,21 @@ from . import validate_ping
|
|||
is_flag=True,
|
||||
help=("Require tags to be specified for metrics and pings."),
|
||||
)
|
||||
@click.option(
|
||||
"--expire-by-version",
|
||||
help="Expire metrics by version, with the provided major version.",
|
||||
type=click.INT,
|
||||
required=False,
|
||||
)
|
||||
def translate(
|
||||
input, format, output, option, allow_reserved, allow_missing_files, require_tags
|
||||
input,
|
||||
format,
|
||||
output,
|
||||
option,
|
||||
allow_reserved,
|
||||
allow_missing_files,
|
||||
require_tags,
|
||||
expire_by_version,
|
||||
):
|
||||
"""
|
||||
Translate metrics.yaml and pings.yaml files to other formats.
|
||||
|
@ -89,6 +102,7 @@ def translate(
|
|||
"allow_reserved": allow_reserved,
|
||||
"allow_missing_files": allow_missing_files,
|
||||
"require_tags": require_tags,
|
||||
"expire_by_version": expire_by_version,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
"""
|
||||
Outputter to generate C# code for metrics.
|
||||
"""
|
||||
|
||||
import enum
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union # noqa
|
||||
|
||||
from . import metrics
|
||||
from . import pings
|
||||
from . import util
|
||||
|
||||
|
||||
def csharp_datatypes_filter(value: util.JSONType) -> str:
|
||||
"""
|
||||
A Jinja2 filter that renders C# literals.
|
||||
|
||||
Based on Python's JSONEncoder, but overrides:
|
||||
- lists to use `new string[] {}` (only strings)
|
||||
- dicts to use `new Dictionary<string, string> { ...}` (string, string)
|
||||
- sets to use `new HashSet<string>() {}` (only strings)
|
||||
- enums to use the like-named C# enum
|
||||
"""
|
||||
|
||||
class CSharpEncoder(json.JSONEncoder):
|
||||
def iterencode(self, value):
|
||||
if isinstance(value, list):
|
||||
assert all(isinstance(x, str) for x in value)
|
||||
yield "new string[] {"
|
||||
first = True
|
||||
for subvalue in value:
|
||||
if not first:
|
||||
yield ", "
|
||||
yield from self.iterencode(subvalue)
|
||||
first = False
|
||||
yield "}"
|
||||
elif isinstance(value, dict):
|
||||
yield "new Dictionary<string, string> {"
|
||||
first = True
|
||||
for key, subvalue in value.items():
|
||||
if not first:
|
||||
yield ", "
|
||||
yield "{"
|
||||
yield from self.iterencode(key)
|
||||
yield ", "
|
||||
yield from self.iterencode(subvalue)
|
||||
yield "}"
|
||||
first = False
|
||||
yield "}"
|
||||
elif isinstance(value, enum.Enum):
|
||||
yield (value.__class__.__name__ + "." + util.Camelize(value.name))
|
||||
elif isinstance(value, set):
|
||||
yield "new HashSet<string>() {"
|
||||
first = True
|
||||
for subvalue in sorted(list(value)):
|
||||
if not first:
|
||||
yield ", "
|
||||
yield from self.iterencode(subvalue)
|
||||
first = False
|
||||
yield "}"
|
||||
else:
|
||||
yield from super().iterencode(value)
|
||||
|
||||
return "".join(CSharpEncoder().iterencode(value))
|
||||
|
||||
|
||||
def type_name(obj: Union[metrics.Metric, pings.Ping]) -> str:
|
||||
"""
|
||||
Returns the C# type to use for a given metric or ping object.
|
||||
"""
|
||||
generate_enums = getattr(obj, "_generate_enums", [])
|
||||
if len(generate_enums):
|
||||
template_args = []
|
||||
for member, suffix in generate_enums:
|
||||
if len(getattr(obj, member)):
|
||||
template_args.append(util.camelize(obj.name) + suffix)
|
||||
else:
|
||||
if suffix == "Keys":
|
||||
template_args.append("NoExtraKeys")
|
||||
else:
|
||||
template_args.append("No" + suffix)
|
||||
|
||||
return "{}<{}>".format(class_name(obj.type), ", ".join(template_args))
|
||||
|
||||
return class_name(obj.type)
|
||||
|
||||
|
||||
def class_name(obj_type: str) -> str:
|
||||
"""
|
||||
Returns the C# class name for a given metric or ping type.
|
||||
"""
|
||||
if obj_type == "ping":
|
||||
return "PingType"
|
||||
if obj_type.startswith("labeled_"):
|
||||
obj_type = obj_type[8:]
|
||||
return util.Camelize(obj_type) + "MetricType"
|
||||
|
||||
|
||||
def output_csharp(
|
||||
objs: metrics.ObjectTree, output_dir: Path, options: Optional[Dict[str, Any]] = None
|
||||
) -> None:
|
||||
"""
|
||||
Given a tree of objects, output C# code to `output_dir`.
|
||||
|
||||
:param objects: A tree of objects (metrics and pings) as returned from
|
||||
`parser.parse_objects`.
|
||||
:param output_dir: Path to an output directory to write to.
|
||||
:param options: options dictionary, with the following optional keys:
|
||||
|
||||
- `namespace`: The package namespace to declare at the top of the
|
||||
generated files. Defaults to `GleanMetrics`.
|
||||
- `glean_namespace`: The package namespace of the glean library itself.
|
||||
This is where glean objects will be imported from in the generated
|
||||
code.
|
||||
"""
|
||||
if options is None:
|
||||
options = {}
|
||||
|
||||
template = util.get_jinja2_template(
|
||||
"csharp.jinja2",
|
||||
filters=(
|
||||
("csharp", csharp_datatypes_filter),
|
||||
("type_name", type_name),
|
||||
("class_name", class_name),
|
||||
),
|
||||
)
|
||||
|
||||
namespace = options.get("namespace", "GleanMetrics")
|
||||
glean_namespace = options.get("glean_namespace", "Mozilla.Glean")
|
||||
|
||||
for category_key, category_val in objs.items():
|
||||
filename = util.Camelize(category_key) + ".cs"
|
||||
filepath = output_dir / filename
|
||||
|
||||
with filepath.open("w", encoding="utf-8") as fd:
|
||||
fd.write(
|
||||
template.render(
|
||||
category_name=category_key,
|
||||
objs=category_val,
|
||||
extra_args=util.extra_args,
|
||||
namespace=namespace,
|
||||
glean_namespace=glean_namespace,
|
||||
)
|
||||
)
|
||||
# Jinja2 squashes the final newline, so we explicitly add it
|
||||
fd.write("\n")
|
|
@ -45,6 +45,7 @@ def generate(
|
|||
# I tried [\W\Z] but it complained. So `|` it is.
|
||||
reobj = re.compile(f"\\W{bug}\\W|\\W{bug}$")
|
||||
durations = set()
|
||||
responsible_emails = set()
|
||||
metrics_table = ""
|
||||
for category_name, metrics in all_objects.value.items():
|
||||
for metric in metrics.values():
|
||||
|
@ -61,6 +62,9 @@ def generate(
|
|||
|
||||
durations.add(metric.expires)
|
||||
|
||||
if metric.expires == "never":
|
||||
responsible_emails.update(metric.notification_emails)
|
||||
|
||||
if len(durations) == 1:
|
||||
duration = next(iter(durations))
|
||||
if duration == "never":
|
||||
|
@ -72,9 +76,13 @@ def generate(
|
|||
collection_duration += f"{durations}"
|
||||
|
||||
if "never" in durations:
|
||||
collection_duration += "\n**TODO: identify at least one individual here** "
|
||||
collection_duration += "\n" + ", ".join(responsible_emails) + " "
|
||||
collection_duration += "will be responsible for the permanent collections."
|
||||
|
||||
if len(durations) == 0:
|
||||
print(f"I'm sorry, I couldn't find metrics matching the bug number {bug}.")
|
||||
return 1
|
||||
|
||||
# This template is pulled from
|
||||
# https://github.com/mozilla/data-review/blob/main/request.md
|
||||
print(
|
||||
|
|
|
@ -198,10 +198,16 @@ class Metric:
|
|||
return self.disabled or self.is_expired()
|
||||
|
||||
def is_expired(self) -> bool:
|
||||
return self._config.get("custom_is_expired", util.is_expired)(self.expires)
|
||||
def default_handler(expires) -> bool:
|
||||
return util.is_expired(expires, self._config.get("expire_by_version"))
|
||||
|
||||
return self._config.get("custom_is_expired", default_handler)(self.expires)
|
||||
|
||||
def validate_expires(self):
|
||||
return self._config.get("custom_validate_expires", util.validate_expires)(
|
||||
def default_handler(expires):
|
||||
return util.validate_expires(expires, self._config.get("expire_by_version"))
|
||||
|
||||
return self._config.get("custom_validate_expires", default_handler)(
|
||||
self.expires
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
"""
|
||||
Outputter to generate Rust code for metrics.
|
||||
"""
|
||||
|
||||
import enum
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from . import metrics
|
||||
from . import pings
|
||||
from . import tags
|
||||
from . import util
|
||||
|
||||
|
||||
def rust_datatypes_filter(value):
|
||||
"""
|
||||
A Jinja2 filter that renders Rust literals.
|
||||
|
||||
Based on Python's JSONEncoder, but overrides:
|
||||
- dicts and sets to raise an error
|
||||
- sets to vec![] (used in labels)
|
||||
- enums to become Class::Value
|
||||
- lists to vec![] (used in send_in_pings)
|
||||
- null to None
|
||||
- strings to "value".into()
|
||||
- Rate objects to a CommonMetricData initializer
|
||||
(for external Denominators' Numerators lists)
|
||||
"""
|
||||
|
||||
class RustEncoder(json.JSONEncoder):
|
||||
def iterencode(self, value):
|
||||
if isinstance(value, dict):
|
||||
raise ValueError("RustEncoder doesn't know dicts {}".format(str(value)))
|
||||
elif isinstance(value, enum.Enum):
|
||||
yield (value.__class__.__name__ + "::" + util.Camelize(value.name))
|
||||
elif isinstance(value, set):
|
||||
yield "vec!["
|
||||
first = True
|
||||
for subvalue in sorted(list(value)):
|
||||
if not first:
|
||||
yield ", "
|
||||
yield from self.iterencode(subvalue)
|
||||
first = False
|
||||
yield "]"
|
||||
elif isinstance(value, list):
|
||||
yield "vec!["
|
||||
first = True
|
||||
for subvalue in list(value):
|
||||
if not first:
|
||||
yield ", "
|
||||
yield from self.iterencode(subvalue)
|
||||
first = False
|
||||
yield "]"
|
||||
elif value is None:
|
||||
yield "None"
|
||||
elif isinstance(value, str):
|
||||
yield f'"{value}".into()'
|
||||
else:
|
||||
yield from super().iterencode(value)
|
||||
|
||||
return "".join(RustEncoder().iterencode(value))
|
||||
|
||||
|
||||
def ctor(obj):
|
||||
"""
|
||||
Returns the scope and name of the constructor to use for a metric object.
|
||||
Necessary because LabeledMetric<T> is constructed using LabeledMetric::new
|
||||
not LabeledMetric<T>::new
|
||||
"""
|
||||
if getattr(obj, "labeled", False):
|
||||
return "LabeledMetric::new"
|
||||
return class_name(obj.type) + "::new"
|
||||
|
||||
|
||||
def type_name(obj):
|
||||
"""
|
||||
Returns the Rust type to use for a given metric or ping object.
|
||||
"""
|
||||
|
||||
if getattr(obj, "labeled", False):
|
||||
return "LabeledMetric<Labeled{}>".format(class_name(obj.type))
|
||||
generate_enums = getattr(obj, "_generate_enums", []) # Extra Keys? Reasons?
|
||||
if len(generate_enums):
|
||||
for name, suffix in generate_enums:
|
||||
if not len(getattr(obj, name)) and suffix == "Keys":
|
||||
return class_name(obj.type) + "<NoExtraKeys>"
|
||||
else:
|
||||
# we always use the `extra` suffix,
|
||||
# because we only expose the new event API
|
||||
suffix = "Extra"
|
||||
return "{}<{}>".format(
|
||||
class_name(obj.type), util.Camelize(obj.name) + suffix
|
||||
)
|
||||
return class_name(obj.type)
|
||||
|
||||
|
||||
def extra_type_name(typ: str) -> str:
|
||||
"""
|
||||
Returns the corresponding Rust type for event's extra key types.
|
||||
"""
|
||||
|
||||
if typ == "boolean":
|
||||
return "bool"
|
||||
elif typ == "string":
|
||||
return "String"
|
||||
elif typ == "quantity":
|
||||
return "u32"
|
||||
else:
|
||||
return "UNSUPPORTED"
|
||||
|
||||
|
||||
def class_name(obj_type):
|
||||
"""
|
||||
Returns the Rust class name for a given metric or ping type.
|
||||
"""
|
||||
if obj_type == "ping":
|
||||
return "Ping"
|
||||
if obj_type.startswith("labeled_"):
|
||||
obj_type = obj_type[8:]
|
||||
return util.Camelize(obj_type) + "Metric"
|
||||
|
||||
|
||||
def extra_keys(allowed_extra_keys):
|
||||
"""
|
||||
Returns the &'static [&'static str] ALLOWED_EXTRA_KEYS for impl ExtraKeys
|
||||
"""
|
||||
return "&[" + ", ".join([f'"{key}"' for key in allowed_extra_keys]) + "]"
|
||||
|
||||
|
||||
class Category:
|
||||
"""
|
||||
Data struct holding information about a metric to be used in the template.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
objs: Dict[str, Union[metrics.Metric, pings.Ping, tags.Tag]],
|
||||
contains_pings: bool,
|
||||
):
|
||||
self.name = name
|
||||
self.objs = objs
|
||||
self.contains_pings = contains_pings
|
||||
|
||||
|
||||
def output_rust(
|
||||
objs: metrics.ObjectTree, output_dir: Path, options: Optional[Dict[str, Any]] = None
|
||||
) -> None:
|
||||
"""
|
||||
Given a tree of objects, output Rust code to `output_dir`.
|
||||
|
||||
:param objs: A tree of objects (metrics and pings) as returned from
|
||||
`parser.parse_objects`.
|
||||
:param output_dir: Path to an output directory to write to.
|
||||
:param options: options dictionary, not currently used for Rust
|
||||
"""
|
||||
|
||||
if options is None:
|
||||
options = {}
|
||||
|
||||
template = util.get_jinja2_template(
|
||||
"rust.jinja2",
|
||||
filters=(
|
||||
("rust", rust_datatypes_filter),
|
||||
("snake_case", util.snake_case),
|
||||
("camelize", util.camelize),
|
||||
("type_name", type_name),
|
||||
("extra_type_name", extra_type_name),
|
||||
("ctor", ctor),
|
||||
("extra_keys", extra_keys),
|
||||
),
|
||||
)
|
||||
|
||||
filename = "glean_metrics.rs"
|
||||
filepath = output_dir / filename
|
||||
categories = []
|
||||
|
||||
for category_key, category_val in objs.items():
|
||||
contains_pings = any(
|
||||
isinstance(obj, pings.Ping) for obj in category_val.values()
|
||||
)
|
||||
|
||||
cat = Category(category_key, category_val, contains_pings)
|
||||
categories.append(cat)
|
||||
|
||||
with filepath.open("w", encoding="utf-8") as fd:
|
||||
fd.write(
|
||||
template.render(
|
||||
categories=categories,
|
||||
extra_args=util.metric_args,
|
||||
)
|
||||
)
|
|
@ -270,12 +270,24 @@ definitions:
|
|||
metric expires. For example, `2019-03-13`. This date is checked at
|
||||
build time. Except in special cases, this form should be used so
|
||||
that the metric automatically "sunsets" after a period of time.
|
||||
- `<major version>`: An integer greater than 0 representing the
|
||||
major version the metric expires in. For example, `11`. The
|
||||
version is checked at build time against the major provided to the
|
||||
glean_parser and is only valid if a major version is provided at
|
||||
built time. If no major version is provided at build time and
|
||||
expiration by major version is used for a metric, an error is
|
||||
raised.
|
||||
Note that mixing expiration by date and version is not allowed
|
||||
within a product.
|
||||
- `never`: This metric never expires.
|
||||
- `expired`: This metric is manually expired.
|
||||
|
||||
The default may be overriden in certain applications by the
|
||||
`custom_validate_expires` and `custom_is_expired` configs.
|
||||
type: string
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: integer
|
||||
minimum: 1
|
||||
|
||||
version:
|
||||
title: Metric version
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
// -*- mode: csharp -*-
|
||||
|
||||
/*
|
||||
* AUTOGENERATED BY glean_parser. DO NOT EDIT. DO NOT COMMIT.
|
||||
*/
|
||||
{# The rendered markdown is autogenerated, but this
|
||||
Jinja2 template is not. Please file bugs! #}
|
||||
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
{% macro obj_declaration(obj, suffix='', access='', lazy=False) %}
|
||||
{{ access }} {% if lazy %} Lazy<{{ obj|type_name }}>{%- else %} {{ obj|type_name }}{% endif %} {{ obj.name|camelize }}{{ suffix }}
|
||||
{%- if lazy %} = new Lazy<{{ obj|type_name }}>(() => {%- else %} = // generated from {{ obj.identifier() }}{% endif %}
|
||||
|
||||
new {{ obj|type_name }}(
|
||||
{% for arg_name in extra_args if obj[arg_name] is defined %}
|
||||
{{ arg_name|camelize }}: {{ obj[arg_name]|csharp }}{{ "," if not loop.last }}
|
||||
{% endfor %}
|
||||
){% if lazy %});{% else %};{% endif %}{% endmacro %}
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using {{ glean_namespace }}.Private;
|
||||
|
||||
{# The C# metrics design require the class name to have a 'Definition'
|
||||
suffix, in order to nicely call in the metrics from the consumer code.
|
||||
The user code will be interested in the Value of the lazy instance, so
|
||||
that's where the real class name should be used. #}
|
||||
{% set metrics_class_name = category_name|Camelize + 'Definition' %}
|
||||
namespace {{ namespace }}
|
||||
{
|
||||
internal sealed class {{ metrics_class_name }}
|
||||
{
|
||||
private static readonly Lazy<{{ metrics_class_name }}>
|
||||
lazyInstance = new Lazy<{{ metrics_class_name }}>(() => new {{ metrics_class_name }}());
|
||||
public static {{ metrics_class_name }} {{ category_name|Camelize }} => lazyInstance.Value;
|
||||
|
||||
// Private constructor to disallow instantiation from external callers.
|
||||
private {{ metrics_class_name }}() { }
|
||||
|
||||
#pragma warning disable IDE1006 // Naming Styles
|
||||
{% for obj in objs.values() %}
|
||||
{% if obj|attr("_generate_enums") %}
|
||||
{% for name, suffix in obj["_generate_enums"] %}
|
||||
{% if obj|attr(name)|length %}
|
||||
internal enum {{ obj.name|camelize }}{{ suffix }} {
|
||||
{% for key in obj|attr(name) %}
|
||||
{{ key|camelize }}{{ "," if not loop.last }}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for obj in objs.values() %}
|
||||
{% if obj.labeled %}
|
||||
{{ obj_declaration(obj, 'Label', 'private ') }}
|
||||
private readonly Lazy<LabeledMetricType<{{ obj|type_name }}>> {{ obj.name|camelize }}Lazy = new Lazy<LabeledMetricType<{{ obj|type_name }}>>(() => new LabeledMetricType<{{ obj|type_name }}>( // generated from {{ obj.identifier() }}
|
||||
category: {{ obj.category|csharp }},
|
||||
name: {{ obj.name|csharp }},
|
||||
submetric: {{ category_name|Camelize }}.{{ obj.name|camelize }}Label,
|
||||
disabled: {{ obj.is_disabled()|csharp }},
|
||||
lifetime: {{ obj.lifetime|csharp }},
|
||||
sendInPings: {{ obj.send_in_pings|csharp }},
|
||||
labels: {{ obj.labels|csharp }}
|
||||
)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n /// ') }}
|
||||
/// </summary>
|
||||
public LabeledMetricType<{{ obj|type_name }}> {{ obj.name|camelize }} => {{ obj.name|camelize }}Lazy.Value;
|
||||
|
||||
{% else %}
|
||||
{# Deal with non-ping objects first. We need them to be lazy and we
|
||||
want their description to stick on an accessor object. #}
|
||||
{% if obj.type != 'ping' %}
|
||||
{{ obj_declaration(obj, access='private readonly', suffix='Lazy', lazy=True) }}
|
||||
|
||||
/// <summary>
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n /// ') }}
|
||||
/// </summary>
|
||||
internal {{ obj|type_name }} {{ obj.name|camelize }} => {{ obj.name|camelize }}Lazy.Value; // generated from {{ obj.identifier() }}
|
||||
|
||||
{% else %}
|
||||
{# Finally handle pings. #}
|
||||
/// <summary>
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n /// ') }}
|
||||
/// </summary>
|
||||
{{ obj_declaration(obj, access='internal readonly', lazy=False) }}
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
#pragma warning restore IDE1006 // Naming Styles
|
||||
}
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
// -*- mode: Rust -*-
|
||||
|
||||
// AUTOGENERATED BY glean_parser. DO NOT EDIT.
|
||||
{# The rendered source is autogenerated, but this
|
||||
Jinja2 template is not. Please file bugs! #}
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
{% macro generate_extra_keys(obj) %}
|
||||
{% for name, _ in obj["_generate_enums"] %}
|
||||
{# we always use the `extra` suffix, because we only expose the new event API #}
|
||||
{% set suffix = "Extra" %}
|
||||
{% if obj|attr(name)|length %}
|
||||
{% if obj.has_extra_types %}
|
||||
{{ extra_keys_with_types(obj, name, suffix)|indent }}
|
||||
{% else %}
|
||||
compile_error!("Untyped event extras not supported. Please annotate event extras with a type. See documentation for details. (Metric: {{obj.category}}.{{obj.name}}, defined in: {{obj.defined_in['filepath']}}:{{obj.defined_in['line']}})");
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{% macro extra_keys_with_types(obj, name, suffix) %}
|
||||
#[derive(Default, Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct {{ obj.name|Camelize }}{{ suffix }} {
|
||||
{% for item, type in obj|attr(name) %}
|
||||
pub {{ item|snake_case }}: Option<{{type|extra_type_name}}>,
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
impl ExtraKeys for {{ obj.name|Camelize }}{{ suffix }} {
|
||||
const ALLOWED_KEYS: &'static [&'static str] = {{ obj.allowed_extra_keys|extra_keys }};
|
||||
|
||||
fn into_ffi_extra(self) -> ::std::collections::HashMap<i32, String> {
|
||||
let mut map = ::std::collections::HashMap::new();
|
||||
{% for key, _ in obj|attr(name) %}
|
||||
self.{{key|snake_case}}.and_then(|val| map.insert({{loop.index-1}}, val));
|
||||
{% endfor %}
|
||||
map
|
||||
}
|
||||
}
|
||||
{% endmacro %}
|
||||
{% for category in categories %}
|
||||
{% if category.contains_pings %}
|
||||
use glean::private::Ping;
|
||||
use once_cell::sync::Lazy;
|
||||
{% for obj in category.objs.values() %}
|
||||
|
||||
#[allow(non_upper_case_globals, dead_code)]
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n/// ') }}
|
||||
#[rustfmt::skip]
|
||||
pub static {{ obj.name|snake_case }}: Lazy<Ping> =
|
||||
Lazy::new(|| Ping::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.reason_codes|rust }}));
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
pub mod {{ category.name|snake_case }} {
|
||||
#[allow(unused_imports)] // HistogramType might be unusued, let's avoid warnings
|
||||
use glean::{private::*, traits::ExtraKeys, CommonMetricData, HistogramType, Lifetime};
|
||||
use once_cell::sync::Lazy;
|
||||
{% for obj in category.objs.values() %}
|
||||
|
||||
{% if obj|attr("_generate_enums") %}
|
||||
{{ generate_extra_keys(obj) }}
|
||||
{%- endif %}
|
||||
#[allow(non_upper_case_globals, dead_code)]
|
||||
/// generated from {{ category.name }}.{{ obj.name }}
|
||||
///
|
||||
/// {{ obj.description|wordwrap() | replace('\n', '\n /// ') }}
|
||||
pub static {{ obj.name|snake_case }}: Lazy<{{ obj|type_name }}> = Lazy::new(|| {
|
||||
{{ obj|ctor }}(CommonMetricData {
|
||||
category: {{ obj.category|rust }},
|
||||
name: {{ obj.name|rust }},
|
||||
send_in_pings: {{ obj.send_in_pings|rust }},
|
||||
lifetime: {{ obj.lifetime|rust }},
|
||||
disabled: {{ obj.is_disabled()|rust }},
|
||||
..Default::default()
|
||||
}{{ ", " if obj.labeled else ")\n" }}
|
||||
{%- if obj.labeled -%}
|
||||
{%- if obj.labels -%}
|
||||
Some({{ obj.labels|rust }})
|
||||
{%- else -%}
|
||||
None
|
||||
{%- endif -%})
|
||||
{% endif %}
|
||||
});
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if metric_by_type|length > 0 %}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod __glean_metric_maps {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::{id_for_extra_key, extra_keys_len};
|
||||
use crate::private::*;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
{% for typ, metrics in metric_by_type.items() %}
|
||||
pub static {{typ.0}}: Lazy<HashMap<MetricId, &Lazy<{{typ.1}}>>> = Lazy::new(|| {
|
||||
let mut map = HashMap::with_capacity({{metrics|length}});
|
||||
{% for metric in metrics %}
|
||||
map.insert({{metric.0}}.into(), &super::{{metric.1}});
|
||||
{% endfor %}
|
||||
map
|
||||
});
|
||||
|
||||
{% endfor %}
|
||||
|
||||
/// Wrapper to record an event based on its metric ID.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `metric_id` - The metric's ID to look up
|
||||
/// * `extra` - An map of (extra key id, string) pairs.
|
||||
/// The map will be decoded into the appropriate `ExtraKeys` type.
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the event was found and `record` was called with the given `extra`,
|
||||
/// or an `EventRecordingError::InvalidId` if no event by that ID exists
|
||||
/// or an `EventRecordingError::InvalidExtraKey` if the `extra` map could not be deserialized.
|
||||
pub(crate) fn record_event_by_id(metric_id: u32, extra: HashMap<i32, String>) -> Result<(), EventRecordingError> {
|
||||
match metric_id {
|
||||
{% for metric_id, event in events_by_id.items() %}
|
||||
{{metric_id}} => {
|
||||
assert!(
|
||||
extra_keys_len(&super::{{event}}) != 0 || extra.is_empty(),
|
||||
"No extra keys allowed, but some were passed"
|
||||
);
|
||||
|
||||
super::{{event}}.record_raw(extra);
|
||||
Ok(())
|
||||
}
|
||||
{% endfor %}
|
||||
_ => Err(EventRecordingError::InvalidId),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper to record an event based on its metric ID, with a provided timestamp.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `metric_id` - The metric's ID to look up
|
||||
/// * `timestamp` - The time at which this event was recorded.
|
||||
/// * `extra` - An map of (extra key id, string) pairs.
|
||||
/// The map will be decoded into the appropriate `ExtraKeys` type.
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the event was found and `record` was called with the given `extra`,
|
||||
/// or an `EventRecordingError::InvalidId` if no event by that ID exists
|
||||
/// or an `EventRecordingError::InvalidExtraKey` if the event doesn't take extra pairs,
|
||||
/// but some are passed in.
|
||||
pub(crate) fn record_event_by_id_with_time(metric_id: MetricId, timestamp: u64, extra: HashMap<i32, String>) -> Result<(), EventRecordingError> {
|
||||
match metric_id {
|
||||
{% for metric_id, event in events_by_id.items() %}
|
||||
MetricId({{metric_id}}) => {
|
||||
if extra_keys_len(&super::{{event}}) == 0 && !extra.is_empty() {
|
||||
return Err(EventRecordingError::InvalidExtraKey);
|
||||
}
|
||||
|
||||
super::{{event}}.record_with_time(timestamp, extra);
|
||||
Ok(())
|
||||
}
|
||||
{% endfor %}
|
||||
_ => Err(EventRecordingError::InvalidId),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper to record an event based on its metric ID.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `metric_id` - The metric's ID to look up
|
||||
/// * `extra` - An map of (string, string) pairs.
|
||||
/// The map will be decoded into the appropriate `ExtraKeys` types.
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns `Ok(())` if the event was found and `record` was called with the given `extra`,
|
||||
/// or an `EventRecordingError::InvalidId` if no event by that ID exists
|
||||
/// or an `EventRecordingError::InvalidExtraKey` if the `extra` map could not be deserialized.
|
||||
pub(crate) fn record_event_by_id_with_strings(metric_id: u32, extra: HashMap<String, String>) -> Result<(), EventRecordingError> {
|
||||
match metric_id {
|
||||
{% for metric_id, event in events_by_id.items() %}
|
||||
{{metric_id}} => {
|
||||
assert!(
|
||||
extra_keys_len(&super::{{event}}) != 0 || extra.is_empty(),
|
||||
"No extra keys allowed, but some were passed"
|
||||
);
|
||||
|
||||
let extra = extra
|
||||
.into_iter()
|
||||
.map(|(k, v)| id_for_extra_key(&*k, &super::{{event}}).map(|k| (k, v)))
|
||||
.collect::<Result<HashMap<_, _>, _>>()?;
|
||||
super::{{event}}.record_raw(extra);
|
||||
Ok(())
|
||||
}
|
||||
{% endfor %}
|
||||
_ => Err(EventRecordingError::InvalidId),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper to get the currently stored events for event metric.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `metric_id` - The metric's ID to look up
|
||||
/// * `ping_name` - (Optional) The ping name to look into.
|
||||
/// Defaults to the first value in `send_in_pings`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns the recorded events or `None` if nothing stored.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if no event by the given metric ID could be found.
|
||||
pub(crate) fn event_test_get_value_wrapper(metric_id: u32, ping_name: Option<String>) -> Option<Vec<RecordedEvent>> {
|
||||
match metric_id {
|
||||
{% for metric_id, event in events_by_id.items() %}
|
||||
{{metric_id}} => super::{{event}}.test_get_value(ping_name.as_deref()),
|
||||
{% endfor %}
|
||||
_ => panic!("No event for metric id {}", metric_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the provided event for errors.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `metric_id` - The metric's ID to look up
|
||||
/// * `ping_name` - (Optional) The ping name to look into.
|
||||
/// Defaults to the first value in `send_in_pings`.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a string for the recorded error or `None`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if no event by the given metric ID could be found.
|
||||
#[allow(unused_variables)]
|
||||
pub(crate) fn event_test_get_error(metric_id: u32, ping_name: Option<String>) -> Option<String> {
|
||||
#[cfg(feature = "with_gecko")]
|
||||
match metric_id {
|
||||
{% for metric_id, event in events_by_id.items() %}
|
||||
{{metric_id}} => test_get_errors_string!(super::{{event}}, ping_name),
|
||||
{% endfor %}
|
||||
_ => panic!("No event for metric id {}", metric_id),
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "with_gecko"))]
|
||||
{
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod submetric_maps {
|
||||
use std::sync::{
|
||||
atomic::AtomicU32,
|
||||
RwLock,
|
||||
};
|
||||
use super::*;
|
||||
|
||||
pub(crate) const MIN_LABELED_SUBMETRIC_ID: u32 = {{min_submetric_id}};
|
||||
pub(crate) static NEXT_LABELED_SUBMETRIC_ID: AtomicU32 = AtomicU32::new(MIN_LABELED_SUBMETRIC_ID);
|
||||
pub(crate) static LABELED_METRICS_TO_IDS: Lazy<RwLock<HashMap<(u32, String), u32>>> = Lazy::new(||
|
||||
RwLock::new(HashMap::new())
|
||||
);
|
||||
|
||||
{% for typ, metrics in metric_by_type.items() %}
|
||||
{% if typ.0 in ('BOOLEAN_MAP', 'COUNTER_MAP', 'STRING_MAP') %}
|
||||
pub static {{typ.0}}: Lazy<RwLock<HashMap<MetricId, Labeled{{typ.1}}>>> = Lazy::new(||
|
||||
RwLock::new(HashMap::new())
|
||||
);
|
||||
{% endif %}
|
||||
{% endfor%}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
|
@ -17,11 +17,11 @@ from typing import Any, Callable, Dict, Iterable, List, Optional
|
|||
|
||||
from . import lint
|
||||
from . import parser
|
||||
from . import csharp
|
||||
from . import javascript
|
||||
from . import kotlin
|
||||
from . import markdown
|
||||
from . import metrics
|
||||
from . import rust
|
||||
from . import swift
|
||||
from . import util
|
||||
|
||||
|
@ -52,12 +52,12 @@ class Outputter:
|
|||
|
||||
|
||||
OUTPUTTERS = {
|
||||
"csharp": Outputter(csharp.output_csharp, ["*.cs"]),
|
||||
"javascript": Outputter(javascript.output_javascript, []),
|
||||
"typescript": Outputter(javascript.output_typescript, []),
|
||||
"kotlin": Outputter(kotlin.output_kotlin, ["*.kt"]),
|
||||
"markdown": Outputter(markdown.output_markdown, []),
|
||||
"swift": Outputter(swift.output_swift, ["*.swift"]),
|
||||
"rust": Outputter(rust.output_rust, []),
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,6 +136,12 @@ def translate_metrics(
|
|||
|
||||
input_filepaths = util.ensure_list(input_filepaths)
|
||||
|
||||
allow_missing_files = parser_config.get("allow_missing_files", False)
|
||||
if not input_filepaths and not allow_missing_files:
|
||||
print("❌ No metric files specified. ", end="")
|
||||
print("Use `--allow-missing-files` to not treat this as an error.")
|
||||
return 1
|
||||
|
||||
if lint.glinter(input_filepaths, parser_config):
|
||||
return 1
|
||||
|
||||
|
|
|
@ -374,21 +374,41 @@ def format_error(
|
|||
return f"{filepath}:\n{textwrap.indent(content, ' ')}"
|
||||
|
||||
|
||||
def parse_expires(expires: str) -> datetime.date:
|
||||
def parse_expiration_date(expires: str) -> datetime.date:
|
||||
"""
|
||||
Parses the expired field date (yyyy-mm-dd) as a date.
|
||||
Raises a ValueError in case the string is not properly formatted.
|
||||
"""
|
||||
try:
|
||||
return date_fromisoformat(expires)
|
||||
except ValueError:
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError(
|
||||
f"Invalid expiration date '{expires}'. "
|
||||
"Must be of the form yyyy-mm-dd in UTC."
|
||||
)
|
||||
|
||||
|
||||
def is_expired(expires: str) -> bool:
|
||||
def parse_expiration_version(expires: str) -> int:
|
||||
"""
|
||||
Parses the expired field version string as an integer.
|
||||
Raises a ValueError in case the string does not contain a valid
|
||||
positive integer.
|
||||
"""
|
||||
try:
|
||||
if isinstance(expires, int):
|
||||
version_number = int(expires)
|
||||
if version_number > 0:
|
||||
return version_number
|
||||
# Fall-through: if it's not an integer or is not greater than zero,
|
||||
# raise an error.
|
||||
raise ValueError()
|
||||
except ValueError:
|
||||
raise ValueError(
|
||||
f"Invalid expiration version '{expires}'. Must be a positive integer."
|
||||
)
|
||||
|
||||
|
||||
def is_expired(expires: str, major_version: Optional[int] = None) -> bool:
|
||||
"""
|
||||
Parses the `expires` field in a metric or ping and returns whether
|
||||
the object should be considered expired.
|
||||
|
@ -397,20 +417,32 @@ def is_expired(expires: str) -> bool:
|
|||
return False
|
||||
elif expires == "expired":
|
||||
return True
|
||||
elif major_version is not None:
|
||||
return parse_expiration_version(expires) <= major_version
|
||||
else:
|
||||
date = parse_expires(expires)
|
||||
date = parse_expiration_date(expires)
|
||||
return date <= datetime.datetime.utcnow().date()
|
||||
|
||||
|
||||
def validate_expires(expires: str) -> None:
|
||||
def validate_expires(expires: str, major_version: Optional[int] = None) -> None:
|
||||
"""
|
||||
Raises a ValueError in case the `expires` is not ISO8601 parseable,
|
||||
or in case the date is more than 730 days (~2 years) in the future.
|
||||
If expiration by major version is enabled, raises a ValueError in
|
||||
case `expires` is not a positive integer.
|
||||
Otherwise raises a ValueError in case the `expires` is not ISO8601
|
||||
parseable, or in case the date is more than 730 days (~2 years) in
|
||||
the future.
|
||||
"""
|
||||
if expires in ("never", "expired"):
|
||||
return
|
||||
|
||||
date = parse_expires(expires)
|
||||
if major_version is not None:
|
||||
parse_expiration_version(expires)
|
||||
# Don't need to keep parsing dates if expiration by version
|
||||
# is enabled. We don't allow mixing dates and versions for a
|
||||
# single product.
|
||||
return
|
||||
|
||||
date = parse_expiration_date(expires)
|
||||
max_date = datetime.datetime.now() + datetime.timedelta(days=730)
|
||||
if date > max_date.date():
|
||||
raise ValueError(
|
||||
|
|
|
@ -15,7 +15,7 @@ ecdsa==0.15
|
|||
esprima==4.0.1
|
||||
fluent.migrate==0.11
|
||||
fluent.syntax==0.18.1
|
||||
glean_parser==4.4.0
|
||||
glean_parser==5.0.1
|
||||
jsmin==2.1.0
|
||||
json-e==2.7.0
|
||||
mozilla-version==0.3.4
|
||||
|
|
|
@ -162,9 +162,9 @@ fluent.syntax==0.18.1 \
|
|||
# -r requirements-mach-vendor-python.in
|
||||
# compare-locales
|
||||
# fluent.migrate
|
||||
glean_parser==4.4.0 \
|
||||
--hash=sha256:3ae1435b183936a49368806421df27ab944f1802e86a02b38b8e08e53ff0aac5 \
|
||||
--hash=sha256:948a2b3c81270564a33251fc8ecbfe48bf0549f74bc2d5a8027f6d7b1abae828
|
||||
glean_parser==5.0.1 \
|
||||
--hash=sha256:309f36ed55f2f1ed82472ab8b18e1dd01edeb71060464e3f859c9b60e38b87d4 \
|
||||
--hash=sha256:7357aac9a857883db99121abb15b9fdb9bcb5437cecee28c9b8a09a2123408ed
|
||||
# via -r requirements-mach-vendor-python.in
|
||||
idna-ssl==1.1.0 \
|
||||
--hash=sha256:a933e3bb13da54383f9e8f35dc4f9cb9eb9b3b78c6b36f311254d6d0d92c6c7c
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -27,9 +27,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
|
@ -80,9 +80,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.0"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -111,9 +111,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.6.0"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2"
|
||||
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
@ -163,7 +163,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glean-core"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"chrono",
|
||||
|
@ -247,9 +247,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.112"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
|
||||
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-rkv"
|
||||
|
@ -265,9 +265,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lmdb-rkv-sys"
|
||||
version = "0.11.0"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b27470ac25167b3afdfb6af8fcd3bc1be67de50ffbdaf4073378cfded6ae24a5"
|
||||
checksum = "61b9ce6b3be08acefa3003c57b7565377432a89ec24476bbe72e11d101f852fe"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -404,9 +404,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.14"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -460,18 +460,18 @@ checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.133"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.133"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -480,9 +480,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.75"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79"
|
||||
checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -491,9 +491,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.85"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "glean-core"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
authors = ["Jan-Erik Rediger <jrediger@mozilla.com>", "The Glean Team <glean-team@mozilla.com>"]
|
||||
include = ["/README.md", "/LICENSE", "/src", "/examples", "/tests", "/Cargo.toml"]
|
||||
description = "A modern Telemetry library"
|
||||
|
@ -21,7 +21,7 @@ keywords = ["telemetry"]
|
|||
license = "MPL-2.0"
|
||||
repository = "https://github.com/mozilla/glean"
|
||||
[package.metadata.glean]
|
||||
glean-parser = "4.4.0"
|
||||
glean-parser = "5.0.1"
|
||||
[dependencies.bincode]
|
||||
version = "1.2.1"
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"c200013c760171403ce1aad530f51936b053f2db0e7d36c0a84b6d9068374968","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"bfe00cc2501c9b15d5bc463c6db30ebbf8d7b5d6c555cf3827ae529fc9e7d6cc","cbindgen.toml":"ac25d1bc2ab7d6afaf25cfa0d35233f93b01f7129088cdd1fa89b9d987a8c564","glean.h":"bbe571147f9fee34f7deac1057c541f00523317328e591446d4c96bbe84c99eb","src/boolean.rs":"0d1d59d0c13cdb63592a9513f2abcf3d1a8260d6523cc7d1af40cfcb4c75572a","src/byte_buffer.rs":"eeb6df25da7b393517f0c993e1e99a0acbccd7678b1127ce0e471d0e53a4bb45","src/counter.rs":"4d8f41285e4a9dbfa2733cdf937905006b475c0af7a501df73fde4ca77818e82","src/custom_distribution.rs":"b0b3b23289e413e7d150e8dae8217e6bd409cbbab68abb127f146041bcbfaf45","src/datetime.rs":"a5c1c993605b1a8ff044d88de4f4a385aff1a781cb8cb45573b90882da801fae","src/event.rs":"ef6dd4f0493ae223e4f7091d5779e46b33ea9864c2a4e5953811a7d9e8884c32","src/fd_logger.rs":"0f8197bb086f49413cca30a72bae029f663842fc3b78ceef6d0854a070b1cdfd","src/ffi_string_ext.rs":"389ae94dcdace1f56ca2c87207e865edda6d42da45733f1027e0a4dcfa86c492","src/from_raw.rs":"b17515a58d7e303ee746ea54c1c1c6d0523dc4de0bd8157dfaba2a610da637bb","src/handlemap_ext.rs":"3b1b088a2de197a0c3eaae0f2f0915d53602f51c13d27f48297f52cd885d5abc","src/jwe.rs":"72adff64900ca16d6527e8d6a436ac2ba85f738d6e92e33f3d71df32b485d0c3","src/labeled.rs":"9cc706511961dbe62350d62b39e9b2c3a9c9e9f53d5577274e273c0f826cd8c3","src/lib.rs":"b5bee8a36a3d0e32eaa01caad0ca57f8649b61b0f99cd3df1f697c27ec9fc47a","src/macros.rs":"e11614edb156552617354d7f6120c8e60ffeb6632ebc19d2b7c6c3e88523b01b","src/memory_distribution.rs":"08ef15e340f2e7ab2f4f83cd8e883c864d4affb94458e80198c106393bfb6bd8","src/ping_type.rs":"6401bcf4342ec1e4ba3782e2b67b3320aa96c9eddc03fc3c75ecc54e2f08a619","src/quantity.rs":"f72781ea642b5f7e363e9fecaded143d1afd772575603763543f1df3448ec337","src/string.rs":"199a238f3524eb36643d82b63df5c7f013adedb6af80632a2675f8562f34e692","src/string_list.rs":"12e2fbbdc08a1b8da1885fb14acd59ab27c8b598a24dc15a4eaca16636540a54","src/timespan.rs":"b7ac51dbfd5169d8c688c3fd2db51e38b6173c925ca14d7b0e8353f225b30a50","src/timing_distribution.rs":"4b5962729fb0b4c9ebf65a5fc5af105357652fcc282c6f8840f328452ba86ac6","src/upload.rs":"320c6e97df0a87040d2a269765401cd67da50f0a226c95a9a314f22452116f7c","src/url.rs":"2dfaf006cd4024ee07eb37dc312201b027d774f6c9881e556774cc09077a6290","src/uuid.rs":"c9ea7225fac53b55a8aeef39cd33470228c0a178185aa74b8fa652657994e404","src/weak.rs":"0199f4ef38d667f0b9f8ef3c5505ff15cd6e911bc83c27e7e9954fdffe1be0bb"},"package":"a33681c61cb007b4d4c19b3cac1a8e74b211f7afe88f179328c04a3bc72ec466"}
|
||||
{"files":{"Cargo.toml":"a850e273cc805ce2b1c281d88362e26e0cc85ea53d93685e7642339450b32559","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"bfe00cc2501c9b15d5bc463c6db30ebbf8d7b5d6c555cf3827ae529fc9e7d6cc","cbindgen.toml":"ac25d1bc2ab7d6afaf25cfa0d35233f93b01f7129088cdd1fa89b9d987a8c564","glean.h":"bbe571147f9fee34f7deac1057c541f00523317328e591446d4c96bbe84c99eb","src/boolean.rs":"0d1d59d0c13cdb63592a9513f2abcf3d1a8260d6523cc7d1af40cfcb4c75572a","src/byte_buffer.rs":"eeb6df25da7b393517f0c993e1e99a0acbccd7678b1127ce0e471d0e53a4bb45","src/counter.rs":"4d8f41285e4a9dbfa2733cdf937905006b475c0af7a501df73fde4ca77818e82","src/custom_distribution.rs":"b0b3b23289e413e7d150e8dae8217e6bd409cbbab68abb127f146041bcbfaf45","src/datetime.rs":"a5c1c993605b1a8ff044d88de4f4a385aff1a781cb8cb45573b90882da801fae","src/event.rs":"ef6dd4f0493ae223e4f7091d5779e46b33ea9864c2a4e5953811a7d9e8884c32","src/fd_logger.rs":"0f8197bb086f49413cca30a72bae029f663842fc3b78ceef6d0854a070b1cdfd","src/ffi_string_ext.rs":"389ae94dcdace1f56ca2c87207e865edda6d42da45733f1027e0a4dcfa86c492","src/from_raw.rs":"b17515a58d7e303ee746ea54c1c1c6d0523dc4de0bd8157dfaba2a610da637bb","src/handlemap_ext.rs":"3b1b088a2de197a0c3eaae0f2f0915d53602f51c13d27f48297f52cd885d5abc","src/jwe.rs":"72adff64900ca16d6527e8d6a436ac2ba85f738d6e92e33f3d71df32b485d0c3","src/labeled.rs":"9cc706511961dbe62350d62b39e9b2c3a9c9e9f53d5577274e273c0f826cd8c3","src/lib.rs":"b5bee8a36a3d0e32eaa01caad0ca57f8649b61b0f99cd3df1f697c27ec9fc47a","src/macros.rs":"e11614edb156552617354d7f6120c8e60ffeb6632ebc19d2b7c6c3e88523b01b","src/memory_distribution.rs":"08ef15e340f2e7ab2f4f83cd8e883c864d4affb94458e80198c106393bfb6bd8","src/ping_type.rs":"6401bcf4342ec1e4ba3782e2b67b3320aa96c9eddc03fc3c75ecc54e2f08a619","src/quantity.rs":"f72781ea642b5f7e363e9fecaded143d1afd772575603763543f1df3448ec337","src/string.rs":"199a238f3524eb36643d82b63df5c7f013adedb6af80632a2675f8562f34e692","src/string_list.rs":"12e2fbbdc08a1b8da1885fb14acd59ab27c8b598a24dc15a4eaca16636540a54","src/timespan.rs":"b7ac51dbfd5169d8c688c3fd2db51e38b6173c925ca14d7b0e8353f225b30a50","src/timing_distribution.rs":"4b5962729fb0b4c9ebf65a5fc5af105357652fcc282c6f8840f328452ba86ac6","src/upload.rs":"320c6e97df0a87040d2a269765401cd67da50f0a226c95a9a314f22452116f7c","src/url.rs":"2dfaf006cd4024ee07eb37dc312201b027d774f6c9881e556774cc09077a6290","src/uuid.rs":"c9ea7225fac53b55a8aeef39cd33470228c0a178185aa74b8fa652657994e404","src/weak.rs":"0199f4ef38d667f0b9f8ef3c5505ff15cd6e911bc83c27e7e9954fdffe1be0bb"},"package":"30511afa692ca3764711da025e0bcd8f07dd09271d9885ee70fa4c970fe91e41"}
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "glean-ffi"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
authors = ["Jan-Erik Rediger <jrediger@mozilla.com>", "The Glean Team <glean-team@mozilla.com>"]
|
||||
include = ["/README.md", "/LICENSE", "/src", "/tests", "/Cargo.toml", "/cbindgen.toml", "/glean.h"]
|
||||
description = "FFI layer for Glean, a modern Telemetry library"
|
||||
|
@ -28,7 +28,7 @@ crate-type = ["lib"]
|
|||
version = "0.4.0"
|
||||
|
||||
[dependencies.glean-core]
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
|
||||
[dependencies.log]
|
||||
version = "0.4.8"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"5bb22247135b1f2966f8045dc205b2559a95768507d3bee4b2d4e77fd071f446","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"fd9e0ca6907917ea6bec5de05e15dd21d20fae1cb7f3250467bb20231a8e1065","src/common_test.rs":"bd7ab2f6384bea8971f97ba68b11c946899303891bc534898f7aabbf27f9008a","src/configuration.rs":"4acbedba16d45f6404ccedde86e8aa33eea8c1b9554210cb69c79ff2ec9040c9","src/core_metrics.rs":"0593192ec0fa1b4d267411cdfb75c70f78578083eca91f6e09cd08346de32264","src/dispatcher/global.rs":"460ccfec311163b469c54f63f4cb41e057b93421ccb7675e435c2994d478cd4b","src/dispatcher/mod.rs":"9f59e466fbbcc3e1bdc42659822a2a2c4b8250456858ee885e53b16458f4a47e","src/glean_metrics.rs":"d376e4f40ec620ce31667451a78adc1146213016e100c0d457505ec240ab31bf","src/lib.rs":"5ecf8102426bbfbd941a7e19bb79a65485a90d9842783a1940c42ebdec61e183","src/net/http_uploader.rs":"9e8c1837ca0d3f6ea165ec936ab054173c4fe95a958710176c33b4d4d1d98beb","src/net/mod.rs":"284bcf182156c52ea25fa33bcc48d80b4970ee3c187a4ea3a06602cc34c710bf","src/pings.rs":"02a3ddb4e77d2033fb5a8fc9bbec09ad5500691e0bd2a1db334805cba88670fd","src/private/boolean.rs":"eeadc0529e2c69a930479f208746799b064b27facab8306c1c10c650e83fb63c","src/private/counter.rs":"0bc8a2d0df72e47b7365ff80bfc16427a5da701fd0adadeedbcce13cebcd79ce","src/private/custom_distribution.rs":"6d1271fb91e9d51a8dcf5eb9d540b3757ebe9cc998b196943ed8c729f62afc67","src/private/datetime.rs":"cb8f26f74d318e2118d6ae1b15972557eb205d4d8b24795fb0d08fdea2bc3f56","src/private/denominator.rs":"95332737f3ac80346f4811440a2141cd427692819bd04d5d3ac7374299dc20b0","src/private/event.rs":"b674ceb85351b7989bd25ed4f5d98c5c9b31e2a03f13b054a8c0dbef54190e49","src/private/labeled.rs":"2cd90d132954ee3ada43ff1ad538072ba43eece7a53ed89811a2a7b43a4819f1","src/private/memory_distribution.rs":"8b78a0e33601081d76639445c8b4875a4fe7c3aded720bb43afdabe86e0fd6ee","src/private/mod.rs":"63368b123fecb6de210ec634b8d387799b4b9dd960016335ebc3c6851e81628f","src/private/numerator.rs":"334ac2ad3d8dd7b9f02f1ca5391b683d50fbc8c6728a12882a68bb067604c800","src/private/ping.rs":"915fc42994e0929656daee5511946ac1f56fe0d4d704e97e13795771d9890180","src/private/quantity.rs":"528675cd388010b89e6ac23c9152701c78d32c2dcd0b5e9abf1a50a52ee818a5","src/private/rate.rs":"7ddfdb3d5f2d1887b378caa3769ade92ea0fbd193f6e760f5f383c8b3e9f3aff","src/private/recorded_experiment_data.rs":"66b2601902a2dc2b7a283717c21ce754de94fcca30d12e0398195c8ad49c90af","src/private/string.rs":"c85ded40b1409793ae5b78da692bc2e708f8d55defb76ec5f515096d32f206c9","src/private/string_list.rs":"472ad79fba4b9bcde0ff5b3e05fd8e0aaa3d1d2941fc181faf2ceb90f1d518bd","src/private/timespan.rs":"19ed08aa5103b685a3a0b9f06f2c60250d55f3c8f36337f8c7bdbb2dfdb92786","src/private/timing_distribution.rs":"ee7fa0c3d5427e371b5413373cb1f5841ac10df9b7ca08316ef724e7ad3591d9","src/private/url.rs":"223de8a025e2f749255103402eecb5582961c2b5af7492e294362a0e8f55c414","src/private/uuid.rs":"2b69ddaf3978aaa31c625c0f3eb948c44369744334aacc6b5a2b217268d244a7","src/system.rs":"ff23a5b94f52dab484342dfed702412bc29ab1bbfd5af326033d8e07e7b9075f","src/test.rs":"0cbe4f51fa01b1ca04e4b726e8eb729c3504086bc6b0d644e2114a5a4473165a","tests/common/mod.rs":"4837df2e771929cc077e6fb9a9239645e8e0f7bc6c9f409b71c4d147edf334fc","tests/init_fails.rs":"1e832fe454962ddb1155d546bb71b6395aa9936f848ff0fbe88affaaab7dfae3","tests/never_init.rs":"1f33b8ce7ca3514b57b48cc16d98408974c85cf8aa7d13257ffc2ad878ebb295","tests/no_time_to_init.rs":"4d61e4196d8eef23f3bcb24b59bd0b0379c1f2cb50f03434a53996ab097bfb17","tests/overflowing_preinit.rs":"be7e9a7984162da33f17a5edae29e1e07e5d0b27e8830f7f32bb238a7e788638","tests/persist_ping_lifetime.rs":"adfab91baf978f464e265eae828fcc03aa6eef83422d3918ffb680b2c2ec859e","tests/persist_ping_lifetime_nopanic.rs":"92f4739b21c0d46cb368eafea43bfb822d8dee96412d5f4fc32e01636f0cf244","tests/schema.rs":"621caef0cc7f98c79740422835485fea2343ca105d0d9a7eec6ded9cfad6232c","tests/simple.rs":"2f58d3ff90005231f2febd21f66ee41d06302618408ea990b446510449c3444f"},"package":"5eee21709bc0417a5e2b8ea436717bba01c6851111d3ac096994efa73bb79dab"}
|
||||
{"files":{"Cargo.toml":"87d83d11f397667c67c48fbf31cd627028f038e48b22060f57c8e49761216127","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"fd9e0ca6907917ea6bec5de05e15dd21d20fae1cb7f3250467bb20231a8e1065","src/common_test.rs":"bd7ab2f6384bea8971f97ba68b11c946899303891bc534898f7aabbf27f9008a","src/configuration.rs":"4acbedba16d45f6404ccedde86e8aa33eea8c1b9554210cb69c79ff2ec9040c9","src/core_metrics.rs":"0593192ec0fa1b4d267411cdfb75c70f78578083eca91f6e09cd08346de32264","src/dispatcher/global.rs":"460ccfec311163b469c54f63f4cb41e057b93421ccb7675e435c2994d478cd4b","src/dispatcher/mod.rs":"9f59e466fbbcc3e1bdc42659822a2a2c4b8250456858ee885e53b16458f4a47e","src/glean_metrics.rs":"d376e4f40ec620ce31667451a78adc1146213016e100c0d457505ec240ab31bf","src/lib.rs":"a2e01d4ef103d0bdc73215e8cff2d48766a8853a6dcb1635bed3b0421861336d","src/net/http_uploader.rs":"9e8c1837ca0d3f6ea165ec936ab054173c4fe95a958710176c33b4d4d1d98beb","src/net/mod.rs":"284bcf182156c52ea25fa33bcc48d80b4970ee3c187a4ea3a06602cc34c710bf","src/pings.rs":"02a3ddb4e77d2033fb5a8fc9bbec09ad5500691e0bd2a1db334805cba88670fd","src/private/boolean.rs":"eeadc0529e2c69a930479f208746799b064b27facab8306c1c10c650e83fb63c","src/private/counter.rs":"0bc8a2d0df72e47b7365ff80bfc16427a5da701fd0adadeedbcce13cebcd79ce","src/private/custom_distribution.rs":"6d1271fb91e9d51a8dcf5eb9d540b3757ebe9cc998b196943ed8c729f62afc67","src/private/datetime.rs":"cb8f26f74d318e2118d6ae1b15972557eb205d4d8b24795fb0d08fdea2bc3f56","src/private/denominator.rs":"95332737f3ac80346f4811440a2141cd427692819bd04d5d3ac7374299dc20b0","src/private/event.rs":"b674ceb85351b7989bd25ed4f5d98c5c9b31e2a03f13b054a8c0dbef54190e49","src/private/labeled.rs":"2cd90d132954ee3ada43ff1ad538072ba43eece7a53ed89811a2a7b43a4819f1","src/private/memory_distribution.rs":"8b78a0e33601081d76639445c8b4875a4fe7c3aded720bb43afdabe86e0fd6ee","src/private/mod.rs":"63368b123fecb6de210ec634b8d387799b4b9dd960016335ebc3c6851e81628f","src/private/numerator.rs":"334ac2ad3d8dd7b9f02f1ca5391b683d50fbc8c6728a12882a68bb067604c800","src/private/ping.rs":"915fc42994e0929656daee5511946ac1f56fe0d4d704e97e13795771d9890180","src/private/quantity.rs":"528675cd388010b89e6ac23c9152701c78d32c2dcd0b5e9abf1a50a52ee818a5","src/private/rate.rs":"7ddfdb3d5f2d1887b378caa3769ade92ea0fbd193f6e760f5f383c8b3e9f3aff","src/private/recorded_experiment_data.rs":"66b2601902a2dc2b7a283717c21ce754de94fcca30d12e0398195c8ad49c90af","src/private/string.rs":"c85ded40b1409793ae5b78da692bc2e708f8d55defb76ec5f515096d32f206c9","src/private/string_list.rs":"472ad79fba4b9bcde0ff5b3e05fd8e0aaa3d1d2941fc181faf2ceb90f1d518bd","src/private/timespan.rs":"19ed08aa5103b685a3a0b9f06f2c60250d55f3c8f36337f8c7bdbb2dfdb92786","src/private/timing_distribution.rs":"ee7fa0c3d5427e371b5413373cb1f5841ac10df9b7ca08316ef724e7ad3591d9","src/private/url.rs":"223de8a025e2f749255103402eecb5582961c2b5af7492e294362a0e8f55c414","src/private/uuid.rs":"2b69ddaf3978aaa31c625c0f3eb948c44369744334aacc6b5a2b217268d244a7","src/system.rs":"ff23a5b94f52dab484342dfed702412bc29ab1bbfd5af326033d8e07e7b9075f","src/test.rs":"0cbe4f51fa01b1ca04e4b726e8eb729c3504086bc6b0d644e2114a5a4473165a","tests/common/mod.rs":"4837df2e771929cc077e6fb9a9239645e8e0f7bc6c9f409b71c4d147edf334fc","tests/init_fails.rs":"1e832fe454962ddb1155d546bb71b6395aa9936f848ff0fbe88affaaab7dfae3","tests/never_init.rs":"1f33b8ce7ca3514b57b48cc16d98408974c85cf8aa7d13257ffc2ad878ebb295","tests/no_time_to_init.rs":"4d61e4196d8eef23f3bcb24b59bd0b0379c1f2cb50f03434a53996ab097bfb17","tests/overflowing_preinit.rs":"be7e9a7984162da33f17a5edae29e1e07e5d0b27e8830f7f32bb238a7e788638","tests/persist_ping_lifetime.rs":"adfab91baf978f464e265eae828fcc03aa6eef83422d3918ffb680b2c2ec859e","tests/persist_ping_lifetime_nopanic.rs":"92f4739b21c0d46cb368eafea43bfb822d8dee96412d5f4fc32e01636f0cf244","tests/schema.rs":"621caef0cc7f98c79740422835485fea2343ca105d0d9a7eec6ded9cfad6232c","tests/simple.rs":"2f58d3ff90005231f2febd21f66ee41d06302618408ea990b446510449c3444f"},"package":"d39b68297fbdd3a9cf37243ab30913542cfce546b4c58a5cd7f4ee9cd9ab3d02"}
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "glean"
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
authors = ["Jan-Erik Rediger <jrediger@mozilla.com>", "The Glean Team <glean-team@mozilla.com>"]
|
||||
include = ["/README.md", "/LICENSE", "/src", "/tests", "/Cargo.toml"]
|
||||
description = "Glean SDK Rust language bindings"
|
||||
|
@ -28,7 +28,7 @@ features = ["serde"]
|
|||
version = "0.5"
|
||||
|
||||
[dependencies.glean-core]
|
||||
version = "43.0.2"
|
||||
version = "44.0.0"
|
||||
|
||||
[dependencies.inherent]
|
||||
version = "0.1.4"
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
//! prototype_ping.submit(None);
|
||||
//! ```
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub use configuration::Configuration;
|
||||
use configuration::DEFAULT_GLEAN_ENDPOINT;
|
||||
|
@ -101,6 +101,12 @@ static PRE_INIT_PING_REGISTRATION: OnceCell<Mutex<Vec<private::PingType>>> = Onc
|
|||
/// Requires a Mutex, because in tests we can actual reset this.
|
||||
static STATE: OnceCell<Mutex<RustBindingsState>> = OnceCell::new();
|
||||
|
||||
/// Global singleton of the handles of the glean.init threads.
|
||||
/// For joining. For tests.
|
||||
/// (Why a Vec? There might be more than one concurrent call to initialize.)
|
||||
static INIT_HANDLES: Lazy<Arc<Mutex<Vec<std::thread::JoinHandle<()>>>>> =
|
||||
Lazy::new(|| Arc::new(Mutex::new(Vec::new())));
|
||||
|
||||
/// Get a reference to the global state object.
|
||||
///
|
||||
/// Panics if no global state object was set.
|
||||
|
@ -173,16 +179,9 @@ fn launch_with_glean_mut(callback: impl FnOnce(&mut Glean) + Send + 'static) {
|
|||
/// * `client_info` - the [`ClientInfoMetrics`] values used to set Glean
|
||||
/// core metrics.
|
||||
pub fn initialize(cfg: Configuration, client_info: ClientInfoMetrics) {
|
||||
initialize_internal(cfg, client_info);
|
||||
}
|
||||
|
||||
fn initialize_internal(
|
||||
cfg: Configuration,
|
||||
client_info: ClientInfoMetrics,
|
||||
) -> Option<std::thread::JoinHandle<()>> {
|
||||
if was_initialize_called() {
|
||||
log::error!("Glean should not be initialized multiple times");
|
||||
return None;
|
||||
return;
|
||||
}
|
||||
|
||||
let init_handle = std::thread::Builder::new()
|
||||
|
@ -351,10 +350,21 @@ fn initialize_internal(
|
|||
})
|
||||
.expect("Failed to spawn Glean's init thread");
|
||||
|
||||
// For test purposes, store the glean init thread's JoinHandle.
|
||||
INIT_HANDLES.lock().unwrap().push(init_handle);
|
||||
|
||||
// Mark the initialization as called: this needs to happen outside of the
|
||||
// dispatched block!
|
||||
INITIALIZE_CALLED.store(true, Ordering::SeqCst);
|
||||
Some(init_handle)
|
||||
}
|
||||
|
||||
/// TEST ONLY FUNCTION
|
||||
/// Waits on all the glean.init threads' join handles.
|
||||
pub fn join_init() {
|
||||
let mut handles = INIT_HANDLES.lock().unwrap();
|
||||
for handle in handles.drain(..) {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Shuts down Glean in an orderly fashion.
|
||||
|
@ -668,6 +678,9 @@ pub fn test_get_experiment_data(experiment_id: String) -> RecordedExperimentData
|
|||
pub(crate) fn destroy_glean(clear_stores: bool) {
|
||||
// Destroy the existing glean instance from glean-core.
|
||||
if was_initialize_called() {
|
||||
// Just because initialize was called doesn't mean it's done.
|
||||
join_init();
|
||||
|
||||
// Reset the dispatcher first (it might still run tasks against the database)
|
||||
dispatcher::reset_dispatcher();
|
||||
|
||||
|
@ -709,9 +722,8 @@ pub(crate) fn destroy_glean(clear_stores: bool) {
|
|||
pub fn test_reset_glean(cfg: Configuration, client_info: ClientInfoMetrics, clear_stores: bool) {
|
||||
destroy_glean(clear_stores);
|
||||
|
||||
if let Some(handle) = initialize_internal(cfg, client_info) {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
initialize(cfg, client_info);
|
||||
join_init();
|
||||
}
|
||||
|
||||
/// Sets a debug view tag.
|
||||
|
|
|
@ -6,7 +6,7 @@ edition = "2018"
|
|||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
glean = { version = "43.0.2", features = ["rkv-safe-mode"] }
|
||||
glean = { version = "44.0.0", features = ["rkv-safe-mode"] }
|
||||
# In theory we only need this for `target_os = "android"` builds.
|
||||
# Cargo has the ability to do that with `[target.'cfg(target_os = "android")'.dependencies]`.
|
||||
# However that seems to confuse `cbindgen` quite a lot;
|
||||
|
@ -15,7 +15,7 @@ glean = { version = "43.0.2", features = ["rkv-safe-mode"] }
|
|||
# So for now we unconditionally depend on it, but in the code we only `extern crate` it on Android builds.
|
||||
# While `glean-ffi` is still built (I think it is),
|
||||
# it's not linked into the final library.
|
||||
glean-ffi = "43.0.2"
|
||||
glean-ffi = "44.0.0"
|
||||
log = "0.4"
|
||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||
|
|
|
@ -8,7 +8,7 @@ publish = false
|
|||
[dependencies]
|
||||
bincode = "1.0"
|
||||
chrono = "0.4.10"
|
||||
glean = "43.0.2"
|
||||
glean = "44.0.0"
|
||||
inherent = "0.1.4"
|
||||
log = "0.4"
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring", optional = true }
|
||||
|
|
Загрузка…
Ссылка в новой задаче