tor-browser

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

build.py (3947B)


      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 https://mozilla.org/MPL/2.0/.
      4 
      5 import json
      6 import os.path
      7 import re
      8 import sys
      9 
     10 BASE = os.path.dirname(__file__.replace("\\", "/"))
     11 sys.path.insert(0, BASE)  # For importing `data.py`
     12 
     13 from mako import exceptions
     14 from mako.lookup import TemplateLookup
     15 from mako.template import Template
     16 
     17 import data
     18 
     19 RE_PYTHON_ADDR = re.compile(r"<.+? object at 0x[0-9a-fA-F]+>")
     20 
     21 OUT_DIR = os.environ.get("OUT_DIR", "")
     22 
     23 
     24 def main():
     25    usage = (
     26        "Usage: %s [ servo | gecko ] [ style-crate | geckolib <template> ]"
     27        % sys.argv[0]
     28    )
     29    if len(sys.argv) < 3:
     30        abort(usage)
     31    engine = sys.argv[1]
     32    output = sys.argv[2]
     33 
     34    if engine not in ["servo", "gecko"] or output not in [
     35        "style-crate",
     36        "geckolib",
     37    ]:
     38        abort(usage)
     39 
     40    properties = data.PropertiesData(engine=engine)
     41    properties_template = os.path.join(BASE, "properties.mako.rs")
     42    properties_file = render(
     43        properties_template,
     44        engine=engine,
     45        data=properties,
     46        __file__=properties_template,
     47        OUT_DIR=OUT_DIR,
     48    )
     49    if output == "style-crate":
     50        write(OUT_DIR, "properties.rs", properties_file)
     51 
     52        if engine == "servo":
     53            properties_dict = {
     54                kind: {
     55                    p.name: {"pref": getattr(p, "servo_pref")}
     56                    for prop in properties_list
     57                    if prop.enabled_in_content()
     58                    for p in [prop] + prop.aliases
     59                }
     60                for kind, properties_list in [
     61                    ("longhands", properties.longhands),
     62                    ("shorthands", properties.shorthands),
     63                ]
     64            }
     65            as_html = render(
     66                os.path.join(BASE, "properties.html.mako"), properties=properties_dict
     67            )
     68            as_json = json.dumps(properties_dict, indent=4, sort_keys=True)
     69 
     70            # Four dotdots: /path/to/target(4)/debug(3)/build(2)/style-*(1)/out
     71            # Do not ascend above the target dir, because it may not be called target
     72            # or even have a parent (see CARGO_TARGET_DIR).
     73            doc_servo = os.path.join(OUT_DIR, "..", "..", "..", "..", "doc", "stylo")
     74 
     75            write(doc_servo, "css-properties.html", as_html)
     76            write(doc_servo, "css-properties.json", as_json)
     77            write(OUT_DIR, "css-properties.json", as_json)
     78    elif output == "geckolib":
     79        if len(sys.argv) < 4:
     80            abort(usage)
     81        template = sys.argv[3]
     82        header = render(template, data=properties)
     83        sys.stdout.write(header)
     84 
     85 
     86 def abort(message):
     87    print(message, file=sys.stderr)
     88    sys.exit(1)
     89 
     90 
     91 def render(filename, **context):
     92    try:
     93        lookup = TemplateLookup(
     94            directories=[BASE], input_encoding="utf8", strict_undefined=True
     95        )
     96        template = Template(
     97            open(filename, "rb").read(),
     98            filename=filename,
     99            input_encoding="utf8",
    100            lookup=lookup,
    101            strict_undefined=True,
    102        )
    103        # Uncomment to debug generated Python code:
    104        # write("/tmp", "mako_%s.py" % os.path.basename(filename), template.code)
    105        return template.render(**context)
    106    except Exception:
    107        # Uncomment to see a traceback in generated Python code:
    108        # raise
    109        abort(exceptions.text_error_template().render())
    110 
    111 
    112 def write(directory, filename, content):
    113    if not os.path.exists(directory):
    114        os.makedirs(directory)
    115    full_path = os.path.join(directory, filename)
    116    open(full_path, "w", encoding="utf-8", newline="").write(content)
    117 
    118    python_addr = RE_PYTHON_ADDR.search(content)
    119    if python_addr:
    120        abort('Found "{}" in {} ({})'.format(python_addr.group(0), filename, full_path))
    121 
    122 
    123 if __name__ == "__main__":
    124    main()