tor-browser

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

sparse_profiles.py (2290B)


      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 functools
      6 from pathlib import Path
      7 
      8 from gecko_taskgraph import GECKO
      9 
     10 
     11 @functools.cache
     12 def _get_taskgraph_sparse_profile():
     13    """
     14    Parse the taskgraph sparse profile and return the paths and globs it includes.
     15    """
     16 
     17    # We need this nested function to handle %include directives recursively
     18    def parse(profile_path):
     19        paths = set()
     20        globs = set()
     21 
     22        full_path = Path(GECKO) / profile_path
     23        if not full_path.exists():
     24            raise FileNotFoundError(
     25                f"Sparse profile '{full_path.stem}' not found at {full_path}"
     26            )
     27 
     28        for raw_line in full_path.read_text().splitlines():
     29            line = raw_line.strip()
     30            if not line or line.startswith("#") or line.startswith("["):
     31                continue
     32            if line.startswith("%include "):
     33                included_profile = line[len("%include ") :].strip()
     34                included_paths, included_globs = parse(included_profile)
     35                paths.update(included_paths)
     36                globs.update(included_globs)
     37            elif line.startswith("path:"):
     38                path = line[len("path:") :].strip()
     39                paths.add(Path(path))
     40            elif line.startswith("glob:"):
     41                glob = line[len("glob:") :].strip()
     42                globs.add(glob)
     43 
     44        return paths, globs
     45 
     46    return parse("build/sparse-profiles/taskgraph")
     47 
     48 
     49 @functools.cache
     50 def is_path_covered_by_taskgraph_sparse_profile(path):
     51    """
     52    Check if a given path would be included in the taskgraph sparse checkout.
     53    """
     54    profile_paths, profile_globs = _get_taskgraph_sparse_profile()
     55    path = Path(path)
     56 
     57    for profile_path in profile_paths:
     58        if path == profile_path or profile_path in path.parents:
     59            return True
     60 
     61    # Path.match requires at least one directory for ** patterns to match
     62    # root-level files, so we prepend a fake parent directory
     63    path_with_parent = Path("_", path)
     64    for pattern in profile_globs:
     65        if path_with_parent.match(pattern):
     66            return True
     67 
     68    return False