Skip to content

Commit 5328d5a

Browse files
author
Beatriz Rizental
authored
Bug 1707896 - Transform generated folder into QML Module when building for Qt (#342)
1 parent 39cfdd8 commit 5328d5a

File tree

5 files changed

+89
-30
lines changed

5 files changed

+89
-30
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Unreleased
44

5+
- Transform generated folder into QML Module when building Javascript templates for the Qt platform. ([bug 1707896](https://bugzilla.mozilla.org/show_bug.cgi?id=1707896)
6+
- Import the Glean QML module from inside each generated file, removing the requirement to import Glean before importing any of the generated files;
7+
- Prodive a `qmldir` file exposing all generated files;
8+
- Drop the `namespace` option for Javascript templates;
9+
- Add a new `version` option for Javascript templates, required when building for Qt, which expected the Glean QML module version.
10+
511
## 3.4.0 (2021-05-28)
612

713
- Add missing import for Kotlin code ([#339](https://github.com/mozilla/glean_parser/pull/341))

glean_parser/javascript.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def iterencode(self, value):
4141
return "".join(JavascriptEncoder().iterencode(value))
4242

4343

44-
def class_name_factory(platform: str, namespace: str) -> Callable[[str], str]:
44+
def class_name_factory(platform: str) -> Callable[[str], str]:
4545
"""
4646
Returns a function that receives an obj_type and
4747
returns the correct class name for that time in the current platform.
@@ -56,7 +56,7 @@ def class_name(obj_type: str) -> str:
5656
class_name = util.Camelize(obj_type) + "MetricType"
5757

5858
if platform == "qt":
59-
return namespace + ".Glean.default._private." + class_name
59+
return "Glean.Glean._private." + class_name
6060

6161
return class_name
6262

@@ -101,24 +101,32 @@ def output(
101101
`parser.parse_objects`.
102102
:param output_dir: Path to an output directory to write to.
103103
:param options: options dictionary, with the following optional keys:
104-
105-
- `namespace`: The identifier of the global variable Glean was assigned to.
106-
This will only have and effect for Qt and static web sites.
107-
Default is `Glean`.
108104
- `platform`: Which platform are we building for. Options are `webext` and `qt`.
109105
Default is `webext`.
106+
- `version`: The version of the Glean.js Qt library being used.
107+
This option is mandatory when targeting Qt. Note that the version
108+
string must only contain the major and minor version i.e. 0.14.
109+
110110
"""
111111

112112
if options is None:
113113
options = {}
114114

115-
namespace = options.get("namespace", "Glean")
116115
platform = options.get("platform", "webext")
116+
if platform not in ["qt", "webext"]:
117+
raise ValueError(
118+
f"Unknown platform: {platform}. Accepted platforms are qt and webext."
119+
)
120+
version = options.get("version")
121+
if platform == "qt" and version is None:
122+
raise ValueError(
123+
"'version' option is required when building for the 'qt' platform."
124+
)
117125

118126
template = util.get_jinja2_template(
119127
"javascript.jinja2",
120128
filters=(
121-
("class_name", class_name_factory(platform, namespace)),
129+
("class_name", class_name_factory(platform)),
122130
("import_path", import_path),
123131
("js", javascript_datatypes_filter),
124132
("args", args),
@@ -151,8 +159,8 @@ def output(
151159
category_name=category_key,
152160
objs=category_val,
153161
extra_args=util.extra_args,
154-
namespace=namespace,
155162
platform=platform,
163+
version=version,
156164
has_labeled_metrics=has_labeled_metrics,
157165
types=types,
158166
lang=lang,
@@ -161,6 +169,16 @@ def output(
161169
# Jinja2 squashes the final newline, so we explicitly add it
162170
fd.write("\n")
163171

172+
if platform == "qt":
173+
# Explicitly create a qmldir file when building for Qt
174+
template = util.get_jinja2_template("qmldir.jinja2")
175+
filepath = output_dir / "qmldir"
176+
177+
with filepath.open("w", encoding="utf-8") as fd:
178+
fd.write(template.render(categories=objs.keys(), version=version))
179+
# Jinja2 squashes the final newline, so we explicitly add it
180+
fd.write("\n")
181+
164182

165183
def output_javascript(
166184
objs: metrics.ObjectTree, output_dir: Path, options: Optional[Dict[str, Any]] = None

glean_parser/templates/javascript.jinja2

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@ new {{ "labeled"|class_name }}({
1212
{{ arg_name|camelize }}: {{ obj[arg_name]|js }},
1313
{% endfor %}
1414
}, {{ obj.type|class_name }}{% if obj.labels is not none %}, {{ obj.labels|js }}{% endif %}){% endmacro %}
15-
{% if lang == "javascript" %}
16-
"use strict";
17-
18-
{% endif %}
19-
/* eslint-disable */
20-
2115
/* This Source Code Form is subject to the terms of the Mozilla Public
2216
* License, v. 2.0. If a copy of the MPL was not distributed with this
2317
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -31,6 +25,8 @@ import LabeledMetricType from "@mozilla/glean/{{ platform }}/private/metrics/lab
3125
{% for type in types %}
3226
import {{ type|class_name }} from "@mozilla/glean/{{ platform }}/private/{{ type|import_path }}";
3327
{% endfor %}
28+
{% else %}
29+
.import org.mozilla.Glean {{ version }} as Glean
3430
{% endif %}
3531
{% for obj in objs.values() %}
3632
/**
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{% for category in categories|sort %}
2+
{{ category|Camelize }} {{ version }} {{ category|camelize }}.js
3+
{% endfor %}
4+
depends org.mozilla.Glean {{ version }}

tests/test_javascript.py

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,14 @@ def test_parser_js(tmpdir):
3939
# Make sure descriptions made it in
4040
with (tmpdir / "corePing.js").open("r", encoding="utf-8") as fd:
4141
content = fd.read()
42-
assert "use strict" in content
4342
assert "True if the user has set Firefox as the default browser." in content
4443

4544
with (tmpdir / "telemetry.js").open("r", encoding="utf-8") as fd:
4645
content = fd.read()
47-
assert "use strict" in content
4846
assert "جمع 搜集" in content
4947

5048
with (tmpdir / "gleanInternalMetrics.js").open("r", encoding="utf-8") as fd:
5149
content = fd.read()
52-
assert "use strict" in content
5350
assert 'category: ""' in content
5451

5552

@@ -129,11 +126,11 @@ def test_metric_class_name():
129126
extra_keys={"my_extra": {"description": "an extra"}},
130127
)
131128

132-
webext_class_name = javascript.class_name_factory("webext", "Glean")
133-
qt_class_name = javascript.class_name_factory("qt", "Glean")
129+
webext_class_name = javascript.class_name_factory("webext")
130+
qt_class_name = javascript.class_name_factory("qt")
134131

135132
assert webext_class_name(event.type) == "EventMetricType"
136-
assert qt_class_name(event.type) == "Glean.Glean.default._private.EventMetricType"
133+
assert qt_class_name(event.type) == "Glean.Glean._private.EventMetricType"
137134

138135
boolean = metrics.Boolean(
139136
type="boolean",
@@ -145,9 +142,7 @@ def test_metric_class_name():
145142
expires="never",
146143
)
147144
assert webext_class_name(boolean.type) == "BooleanMetricType"
148-
assert (
149-
qt_class_name(boolean.type) == "Glean.Glean.default._private.BooleanMetricType"
150-
)
145+
assert qt_class_name(boolean.type) == "Glean.Glean._private.BooleanMetricType"
151146

152147
ping = pings.Ping(
153148
name="custom",
@@ -157,7 +152,7 @@ def test_metric_class_name():
157152
notification_emails=["nobody@nowhere.com"],
158153
)
159154
assert webext_class_name(ping.type) == "PingType"
160-
assert qt_class_name(ping.type) == "Glean.Glean.default._private.PingType"
155+
assert qt_class_name(ping.type) == "Glean.Glean._private.PingType"
161156

162157

163158
def test_import_path():
@@ -300,21 +295,61 @@ def test_arguments_are_generated_in_deterministic_order(tmpdir):
300295
assert expected in content
301296

302297

303-
def test_qt_platform_template_does_not_include_import_export_statements(tmpdir):
298+
def test_qt_platform_template_includes_expected_imports(tmpdir):
304299
"""
305-
Test when the platform is Qt, the template does not contain
300+
Assert that when the platform is Qt, the template does not contain
306301
import/export statements.
307302
"""
308303

309304
tmpdir = Path(str(tmpdir))
310305

311306
translate.translate(
312-
ROOT / "data" / "single_labeled.yaml", "javascript", tmpdir, {"platform": "qt"}
307+
ROOT / "data" / "single_labeled.yaml",
308+
"javascript",
309+
tmpdir,
310+
{"platform": "qt", "version": "0.14"},
313311
)
314312

315-
assert set(x.name for x in tmpdir.iterdir()) == set(["category.js"])
313+
assert set(x.name for x in tmpdir.iterdir()) == set(["category.js", "qmldir"])
316314

317315
with (tmpdir / "category.js").open("r", encoding="utf-8") as fd:
318316
content = fd.read()
319-
assert content.count("import") == 0
317+
assert content.count(".import org.mozilla.Glean 0.14") == 1
320318
assert content.count("export") == 0
319+
320+
321+
def test_qt_platform_generated_correct_qmldir_file(tmpdir):
322+
"""
323+
Assert that when the platform is Qt, a qmldir is also generated
324+
with the expected files listed in it.
325+
"""
326+
327+
tmpdir = Path(str(tmpdir))
328+
329+
translate.translate(
330+
ROOT / "data" / "core.yaml",
331+
"javascript",
332+
tmpdir,
333+
{"platform": "qt", "version": "0.14"},
334+
{"allow_reserved": True},
335+
)
336+
337+
assert set(x.name for x in tmpdir.iterdir()) == set(
338+
[
339+
"corePing.js",
340+
"telemetry.js",
341+
"environment.js",
342+
"dottedCategory.js",
343+
"gleanInternalMetrics.js",
344+
"qmldir",
345+
]
346+
)
347+
348+
with (tmpdir / "qmldir").open("r", encoding="utf-8") as fd:
349+
content = fd.read()
350+
assert content.count("CorePing 0.14 corePing.js") == 1
351+
assert content.count("Telemetry 0.14 telemetry.js") == 1
352+
assert content.count("Environment 0.14 environment.js") == 1
353+
assert content.count("DottedCategory 0.14 dottedCategory.js") == 1
354+
assert content.count("GleanInternalMetrics 0.14 gleanInternalMetrics.js") == 1
355+
assert content.count("depends org.mozilla.Glean 0.14") == 1

0 commit comments

Comments
 (0)