Source code

Revision control

Copy as Markdown

Other Tools

# 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/.
from mach.decorators import Command, CommandArgument
LICENSE_HEADER = """# 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/.
"""
GENERATED_HEADER = """
### This file was AUTOMATICALLY GENERATED by `./mach update-glean-tags`
### DO NOT edit it by hand.
"""
@Command(
"data-review",
category="misc",
description="Generate a skeleton data review request form for a given bug's data",
)
@CommandArgument(
"bug", default=None, nargs="?", type=str, help="bug number or search pattern"
)
def data_review(command_context, bug=None):
# Get the metrics_index's list of metrics indices
# by loading the index as a module.
import sys
from os import path
sys.path.append(path.join(path.dirname(__file__), path.pardir))
from pathlib import Path
from glean_parser import data_review
from metrics_index import metrics_yamls
return data_review.generate(
bug, [Path(command_context.topsrcdir) / x for x in metrics_yamls]
)
@Command(
"perf-data-review",
category="misc",
description="Generate a skeleton performance data review request form for a given bug's data",
)
@CommandArgument(
"bug", default=None, nargs="?", type=str, help="bug number or search pattern"
)
def perf_data_review(command_context, bug=None):
# Get the metrics_index's list of metrics indices
# by loading the index as a module.
import sys
from os import path
sys.path.append(path.join(path.dirname(__file__), path.pardir))
from metrics_index import metrics_yamls
sys.path.append(path.dirname(__file__))
from pathlib import Path
import perf_data_review
return perf_data_review.generate(
bug, [Path(command_context.topsrcdir) / x for x in metrics_yamls]
)
@Command(
"update-glean-tags",
category="misc",
description=(
"Creates a list of valid glean tags based on in-tree bugzilla component definitions"
),
)
def update_glean_tags(command_context):
from pathlib import Path
import yaml
from mozbuild.backend.configenvironment import ConfigEnvironment
from mozbuild.frontend.reader import BuildReader
config = ConfigEnvironment(
command_context.topsrcdir,
command_context.topobjdir,
defines=command_context.defines,
substs=command_context.substs,
)
reader = BuildReader(config)
bug_components = set()
for p in reader.read_topsrcdir():
if p.get("BUG_COMPONENT"):
bug_components.add(p["BUG_COMPONENT"])
tags_filename = (Path(__file__).parent / "../tags.yaml").resolve()
for bug_component in bug_components:
product = bug_component.product.strip()
component = bug_component.component.strip()
tags["{} :: {}".format(product, component)] = {
"description": "The Bugzilla component which applies to this object."
}
open(tags_filename, "w").write(
"{}\n{}\n\n".format(LICENSE_HEADER, GENERATED_HEADER)
+ yaml.dump(tags, width=78, explicit_start=True)
)
def replace_in_file(path, pattern, replace):
"""
Replace `pattern` with `replace` in the file `path`.
The file is modified on disk.
Returns `True` if exactly one replacement happened.
`False` otherwise.
"""
import re
with open(path, "r+") as file:
data = file.read()
data, subs_made = re.subn(pattern, replace, data, flags=re.MULTILINE)
file.seek(0)
file.write(data)
file.truncate()
if subs_made != 1:
return False
return True
def replace_in_file_or_die(path, pattern, replace):
"""
Replace `pattern` with `replace` in the file `path`.
The file is modified on disk.
If not exactly one occurrence of `pattern` was replaced it will exit with exit code 1.
"""
import sys
success = replace_in_file(path, pattern, replace)
if not success:
print(f"ERROR: Failed to replace one occurrence in {path}")
print(f" Pattern: {pattern}")
print(f" Replace: {replace}")
print("File was modified. Check the diff.")
sys.exit(1)
@Command(
"update-glean",
category="misc",
description="Update Glean to the given version",
)
@CommandArgument("version", help="Glean version to upgrade to")
def update_glean(command_context, version):
import textwrap
from pathlib import Path
topsrcdir = Path(command_context.topsrcdir)
replace_in_file_or_die(
topsrcdir
/ "mobile"
/ "android"
/ "android-components"
/ "plugins"
/ "dependencies"
/ "src"
/ "main"
/ "java"
/ "DependenciesPlugin.kt",
r'mozilla_glean = "[0-9.]+"',
f'mozilla_glean = "{version}"',
)
replace_in_file_or_die(
topsrcdir / "toolkit" / "components" / "glean" / "Cargo.toml",
r'^glean = "[0-9.]+"',
f'glean = "{version}"',
)
replace_in_file_or_die(
topsrcdir / "toolkit" / "components" / "glean" / "api" / "Cargo.toml",
r'^glean = "[0-9.]+"',
f'glean = "{version}"',
)
replace_in_file_or_die(
topsrcdir / "gfx" / "wr" / "webrender" / "Cargo.toml",
r'^glean = { version = "[0-9.]+"(.+)}',
f'glean = {{ version = "{version}"\\1}}',
)
replace_in_file_or_die(
topsrcdir / "gfx" / "wr" / "wr_glyph_rasterizer" / "Cargo.toml",
r'^glean = { version = "[0-9.]+"(.+)}',
f'glean = {{ version = "{version}"\\1}}',
)
replace_in_file_or_die(
topsrcdir / "python" / "sites" / "mach.txt",
r"glean-sdk==[0-9.]+",
f"glean-sdk=={version}",
)
instructions = f"""
We've edited the necessary files to require Glean SDK {version}.
To ensure Glean and Firefox's other Rust dependencies are appropriately vendored,
please run the following commands:
cargo update -p glean
./mach vendor rust --ignore-modified
`./mach vendor rust` may identify version mismatches.
Please consult the Updating the Glean SDK docs for assistance:
The Glean SDK is already vetted and no additional vetting for it is necessary.
To prune the configuration file after vendoring run:
./mach cargo vet prune
Then, to update webrender which independently relies on the Glean SDK, run:
cd gfx/wr
cargo update -p glean
Then, to ensure all is well, build Firefox and run the FOG tests.
Instructions can be found here:
"""
print(textwrap.dedent(instructions))
@Command(
"event-into-legacy",
category="misc",
description="Create a Legacy Telemetry compatible event definition from an existing Glean Event metric.",
)
@CommandArgument(
"--append",
"-a",
action="store_true",
help="Append to toolkit/components/telemetry/Events.yaml (note: verify and make any necessary modifications before landing).",
)
@CommandArgument("event", default=None, nargs="?", type=str, help="Event name.")
def event_into_legacy(command_context, event=None, append=False):
# Get the metrics_index's list of metrics indices
# by loading the index as a module.
import sys
from os import path
sys.path.append(path.join(path.dirname(__file__), path.pardir))
from metrics_index import metrics_yamls
sys.path.append(path.dirname(__file__))
from pathlib import Path
from translate_events import translate_event
legacy_yaml_path = path.join(
Path(command_context.topsrcdir),
"toolkit",
"components",
"telemetry",
"Events.yaml",
)
return translate_event(
event,
append,
[Path(command_context.topsrcdir) / x for x in metrics_yamls],
legacy_yaml_path,
)