tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mozlint.py (3357B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import logging
      6 from pathlib import Path
      7 from typing import Union
      8 
      9 from mozlint.parser import Parser
     10 from mozlint.pathutils import filterpaths
     11 from taskgraph.optimize.base import OptimizationStrategy
     12 from taskgraph.util.path import match as match_path
     13 
     14 from gecko_taskgraph import GECKO
     15 
     16 logger = logging.getLogger(__name__)
     17 
     18 
     19 class TGMozlintParser(Parser):
     20    """
     21    Mozlint Parser that skips validation. This is needed because decision
     22    tasks use sparse clones and the files themselves are not present.
     23    """
     24 
     25    def _validate(self, linter):
     26        pass
     27 
     28 
     29 class SkipUnlessMozlint(OptimizationStrategy):
     30    """
     31    Optimization strategy for mozlint tests.
     32 
     33    Uses the mozlint YAML file for each test to determine whether or not a test
     34    should run.
     35 
     36    Using:
     37        - The optimization relies on having `files_changed` set in the decision task
     38          parameters.
     39        - Register with register_strategy. The argument is the path to MozLint YAML
     40          configuration files ("/tools/lint" for mozilla-central):
     41        - In source-test/mozlint.yml, set the optimization strategy for each job by filename:
     42        - For Mozlint jobs that run multiple linters at once use a list of filenames:
     43    """
     44 
     45    def __init__(self, linters_path: str):
     46        self.mozlint_parser = TGMozlintParser(GECKO)
     47        self.linters_path = Path(GECKO) / linters_path
     48 
     49    def should_remove_task(
     50        self, task, params, mozlint_confs: Union[str, list[str]]
     51    ) -> bool:
     52        include = []
     53        exclude = []
     54        extensions = []
     55        exclude_extensions = []
     56        support_files = ["python/mozlint/**", "tools/lint/**"]
     57 
     58        files_changed = params["files_changed"]
     59 
     60        if isinstance(mozlint_confs, str):
     61            mozlint_confs = [mozlint_confs]
     62 
     63        for mozlint_conf in mozlint_confs:
     64            mozlint_yaml = str(self.linters_path / mozlint_conf)
     65            logger.info(f"Loading file patterns for {task.label} from {mozlint_yaml}.")
     66            linter_config = self.mozlint_parser(mozlint_yaml)
     67 
     68            for config in linter_config:
     69                include += config.get("include", [])
     70                exclude += config.get("exclude", [])
     71                extensions += [e.strip(".") for e in config.get("extensions", [])]
     72                exclude_extensions += [
     73                    e.strip(".") for e in config.get("exclude_extensions", [])
     74                ]
     75                support_files += config.get("support-files", [])
     76 
     77        # Support files may not be part of "include" patterns, so check first
     78        # Do not remove (return False) if any changed
     79        for pattern in set(support_files):
     80            for path in files_changed:
     81                if match_path(path, pattern):
     82                    return False
     83 
     84        to_lint, to_exclude = filterpaths(
     85            GECKO,
     86            list(files_changed),
     87            include=include,
     88            exclude=exclude,
     89            extensions=extensions,
     90            exclude_extensions=exclude_extensions,
     91        )
     92 
     93        # to_lint should be an empty list if there is nothing to check
     94        if not to_lint:
     95            return True
     96        return False