Commit b561400d authored by henry's avatar henry Committed by Pier Angelo Vendrame
Browse files

BB 41803: Add some developer tools for working on tor-browser.

parent 411fd8bd
Loading
Loading
Loading
Loading
+95 −0
Original line number Diff line number Diff line
#!/usr/bin/python
"""
Pre-process a git todo file before passing it on to an editor.
"""

import sys
import os
import subprocess
import re

EDITOR_ENV_NAME = "GIT_REBASE_FIXUP_PREPROCESSOR_USER_EDITOR"

try:
    editor = os.environ[EDITOR_ENV_NAME]
except KeyError:
    print(f"Missing {EDITOR_ENV_NAME} in environment", file=sys.stderr)
    exit(1)

if len(sys.argv) < 2:
    print("Missing filename argument", file=sys.stderr)
    exit(1)

filename = sys.argv[1]


class TodoLine:
    """
    Represents a line in the git todo file.
    """

    # git 2.50 adds a '#' between the commit hash and the commit subject.
    # Keep this '#' optional for previous git versions.
    _PICK_REGEX = re.compile(r"^pick [a-f0-9]+ +(?:# +)?(?P<fixups>(fixup! )*)(?P<title>.*)")

    def __init__(self, line):
        """
        Create a new line with the given text content.
        """
        self._line = line
        self._make_fixup = False

        match = self._PICK_REGEX.match(line)
        if match:
            self._is_pick = True
            self._num_fixups = len(match.group("fixups")) / len("fixup! ")
            self._title = match.group("title")
        else:
            self._is_pick = False
            self._num_fixups = False
            self._title = None

    def add_to_list_try_fixup(self, existing_lines):
        """
        Add the TodoLine to the given list of other TodoLine, trying to fix up
        one of the existing lines.
        """
        if not self._num_fixups:  # Not a fixup line.
            existing_lines.append(self)
            return

        # Search from the end of the list upwards.
        for index in reversed(range(len(existing_lines))):
            other = existing_lines[index]
            if (
                other._is_pick
                and self._num_fixups == other._num_fixups + 1
                and other._title == self._title
            ):
                self._make_fixup = True
                existing_lines.insert(index + 1, self)
                return

        # No line found to fixup.
        existing_lines.append(self)

    def get_text(self):
        """
        Get the text for the line to save.
        """
        line = self._line
        if self._make_fixup:
            line = line.replace("pick", "fixup", 1)
        return line


todo_lines = []
with open(filename, "r", encoding="utf8") as todo_file:
    for line in todo_file:
        TodoLine(line).add_to_list_try_fixup(todo_lines)

with open(filename, "w", encoding="utf8") as todo_file:
    for line in todo_lines:
        todo_file.write(line.get_text())

exit(subprocess.run([editor, *sys.argv[1:]], check=False).returncode)
+88 −0
Original line number Diff line number Diff line
"""
Simple tool for checking for missing CSS declarations.

Should be run from the root directory and passed a single CSS file path to
check the variables for.

Missing variables will be printed to stdout, if any. Variables are considered
missing if they are not declared in the same file or in one of the expected
CSS files. CSS variables that are declared in javascript an unexpected CSS file
will not be found.

Exits with 0 if no variables are missing. Otherwise exits with 1.
"""

import re
import sys
from pathlib import Path

declare_dirs = [
    Path("browser/branding"),
    Path("browser/themes"),
    Path("toolkit/themes"),
]

var_dec_regex = re.compile(r"^\s*(?P<name>--[\w_-]+)\s*:")
var_use_regex = re.compile(r":.*(?P<name>--[\w_-]+)")


def remove_vars_in_file(var_set: set[str], file_path: Path) -> bool:
    """
    Checks the CSS file for declarations of the given variables and removes
    them.

    :param var_set: The set of CSS variables to check and remove.
    :param file_path: The path to a CSS file to check within.
    :returns: Whether the variable set is now empty.
    """
    with file_path.open() as file:
        for line in file:
            var_dec_match = var_dec_regex.match(line)
            if not var_dec_match:
                continue
            var_name = var_dec_match.group("name")
            if var_name in var_set:
                print(f"{var_name} declared in {file_path}", file=sys.stderr)
                var_set.remove(var_name)
                if not var_set:
                    return True
    return False


def find_missing(file_path: Path) -> set[str]:
    """
    Search for CSS variables in the CSS file and check whether any are missing
    known declarations.

    :param file_path: The path of the CSS file to check.
    :returns: The names of the missing variables.
    """
    used_vars: set[str] = set()

    with open(file_path) as file:
        for line in file:
            for match in var_use_regex.finditer(line):
                used_vars.add(match.group("name"))

    if not used_vars:
        print("No CSS variables found", file=sys.stderr)
        return used_vars

    # Remove any CSS variables that are declared within the same file.
    if remove_vars_in_file(used_vars, file_path):
        return used_vars

    # And remove any that are in the expected declaration files.
    for top_dir in declare_dirs:
        for css_file_path in top_dir.rglob("*.css"):
            if remove_vars_in_file(used_vars, css_file_path):
                return used_vars

    return used_vars


missing_vars = find_missing(Path(sys.argv[1]))
for var_name in missing_vars:
    print(var_name)

sys.exit(1 if missing_vars else 0)
+819 −0

File added.

Preview size limit exceeded, changes collapsed.