Commit 2d85581b authored by Francesco Lodolo (:flod)'s avatar Francesco Lodolo (:flod)
Browse files

Bug 1781010: Fluent linter, add checks for hard-coded brand...

Bug 1781010: Fluent linter, add checks for hard-coded brand names,r=gregtatum,linter-reviewers,sylvestre

Differential Revision: https://phabricator.services.mozilla.com/D152718
parent 8d60992f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -171,6 +171,11 @@ In this document, we try to list these all tools.
     -
     - :ref:`Codespell`
     - https://github.com/codespell-project/codespell
   * - Fluent Lint
     - No
     -
     - :ref:`Fluent Lint`
     -
   * - YAML linter
     -
     -
+6 −2
Original line number Diff line number Diff line
Fluent Lint
===========

Fluent lint is a linter for Fluent files. Currently, it checks for invalid strings in messages
and enforces the preferred style for identifiers.
Fluent lint is a linter for Fluent files (.ftl). Currently, it includes:

* Checks for invalid typography in messages (e.g. straight single or double quotes).
* Checks for comments layout.
* Checks for identifiers (minimum length, allowed characters).
* Hard-coded brand names.


Run Locally
+26 −1
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ class Linter(visitor.Visitor):
        self.double_quote_re = re.compile(r"\".+\"")
        self.ellipsis_re = re.compile(r"\.\.\.")

        self.brand_names = ["Firefox", "Mozilla"]
        self.minimum_id_length = 9

        self.state = {
@@ -103,11 +104,15 @@ class Linter(visitor.Visitor):
    def visit_Message(self, node):
        # There must be at least one message or term between group comments.
        self.state["can_have_group_comment"] = True
        self.last_message_id = node.id.name

        super().generic_visit(node)

    def visit_Term(self, node):
        # There must be at least one message or term between group comments.
        self.state["can_have_group_comment"] = True
        self.last_message_id = None

        super().generic_visit(node)

    def visit_MessageReference(self, node):
@@ -122,7 +127,9 @@ class Linter(visitor.Visitor):
            and not self.identifier_re.fullmatch(node.name)
        ):
            self.add_error(
                node, "ID01", "Identifiers may only contain lowercase characters and -"
                node,
                "ID01",
                "Identifiers may only contain lowercase characters and -",
            )
        if (
            len(node.name) < self.minimum_id_length
@@ -174,6 +181,24 @@ class Linter(visitor.Visitor):
                    " instead of three periods",
                )

            # If part of a message, check for brand names
            if (
                self.last_message_id is not None
                and self.path not in self.exclusions["CO01"]["files"]
                and self.last_message_id not in self.exclusions["CO01"]["messages"]
            ):
                found_brands = []
                for brand in self.brand_names:
                    if brand in text:
                        found_brands.append(brand)
                if found_brands:
                    self.add_error(
                        node,
                        "CO01",
                        "Strings should use the corresponding terms instead of"
                        f" hard-coded brand names ({', '.join(found_brands)})",
                    )

    def visit_ResourceComment(self, node):
        # This node is a comment with: "###"
        if not self.state["node_can_be_resource_comment"]:
+56 −0
Original line number Diff line number Diff line
@@ -135,3 +135,59 @@ ID02:
        - hf-url
        - hf-page
    files: []
# Hard-coded brand names like Firefox or Mozilla should be used only in
# specific cases, in all other cases the corresponding terms should be used.
# Check with the localization team for advice.
CO01:
    messages:
        # browser/branding/official/locales/en-US/brand.ftl
        # browser/locales/en-US/browser/branding/brandings.ftl
        - trademarkInfo
        # browser/locales/en-US/browser/aboutCertError.ftl
        - cert-error-mitm-mozilla
        - cert-error-mitm-connection
        # browser/locales/en-US/browser/appExtensionFields.ftl
        - extension-firefox-alpenglow-name
        # browser/locales/en-US/browser/browser.ftl
        - identity-custom-root
        - identity-description-custom-root
        # browser/locales/en-US/browser/migration.ftl
        - import-from-firefox
        # browser/locales/en-US/browser/newtab/onboarding.ftl
        - mr1-onboarding-welcome-image-caption
        # browser/locales/en-US/browser/policies/policies-descriptions.ftl
        - policy-DisableFirefoxScreenshots
        # browser/locales/en-US/browser/preferences/preferences.ftl
        - sync-engine-addons
        - sync-mobile-promo
        # browser/locales/en-US/browser/protectionsPanel.ftl
        - protections-panel-content-blocking-breakage-report-view-description
        # devtools/client/locales/en-US/aboutdebugging.ftl
        - about-debugging-setup-usb-step-enable-debug-firefox2
        - about-debugging-browser-version-too-old-fennec
        - about-debugging-browser-version-too-recent
        # devtools/client/locales/en-US/application.ftl
        - manifest-loaded-devtools-error
        # toolkit/locales/en-US/toolkit/about/aboutAddons.ftl
        - addon-badge-line3
        - recommended-theme-1
        # toolkit/locales/en-US/toolkit/about/aboutGlean.ftl
        - about-glean-description
        # toolkit/locales/en-US/toolkit/about/aboutPlugins.ftl
        - plugins-openh264-description
        # toolkit/locales/en-US/toolkit/about/aboutRights.ftl
        - rights-intro-point-1
        - rights-intro-point-2
        # toolkit/locales/en-US/toolkit/about/aboutSupport.ftl
        - app-basics-key-mozilla
        # toolkit/locales/en-US/toolkit/about/aboutTelemetry.ftl
        - about-telemetry-firefox-data-doc
        - about-telemetry-origins-explanation
        - about-telemetry-telemetry-client-doc
        - about-telemetry-telemetry-dashboard
        # toolkit/locales/en-US/toolkit/global/processTypes.ftl
        - process-type-privilegedmozilla
    files:
        - browser/components/ion/content/ion.ftl
        - browser/locales/en-US/browser/profile/default-bookmarks.ftl
        - toolkit/locales/en-US/toolkit/about/aboutMozilla.ftl
+2 −0
Original line number Diff line number Diff line
# Comment
bad-firefox1 = Welcome to Firefox
Loading