no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / js / src / irregexp / import-irregexp.py
blob523276e7b38ed641d31c286a643afe9bb75075d8
1 #!/usr/bin/env python3
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 # You can obtain one at http://mozilla.org/MPL/2.0/.
7 # This script handles all the mechanical steps of importing irregexp from v8:
9 # 1. Acquire the source: either from github, or optionally from a local copy of v8.
10 # 2. Copy the contents of v8/src/regexp into js/src/irregexp/imported
11 # - Exclude files that we have chosen not to import.
12 # 3. While doing so, update #includes:
13 # - Change "src/regexp/*" to "irregexp/imported/*".
14 # - Remove other v8-specific headers completely.
15 # 4. Add '#include "irregexp/RegExpShim.h" in the necessary places.
16 # 5. Update the IRREGEXP_VERSION file to include the correct git hash.
18 # Usage:
19 # cd path/to/js/src/irregexp
20 # ./import-irregexp.py --path path/to/v8/src/regexp
22 # Alternatively, without the --path argument, import-irregexp.py will
23 # clone v8 from github into a temporary directory.
25 # After running this script, changes to the shim code may be necessary
26 # to account for changes in upstream irregexp.
28 import os
29 import re
30 import subprocess
31 import sys
32 from pathlib import Path
35 def copy_and_update_includes(src_path, dst_path):
36 # List of header files that need to include the shim header
37 need_shim = [
38 "property-sequences.h",
39 "regexp-ast.h",
40 "regexp-bytecode-peephole.h",
41 "regexp-bytecodes.h",
42 "regexp-dotprinter.h",
43 "regexp-error.h",
44 "regexp.h",
45 "regexp-macro-assembler.h",
46 "regexp-parser.h",
47 "regexp-stack.h",
48 "special-case.h",
51 src = open(str(src_path), "r")
52 dst = open(str(dst_path), "w")
54 # 1. Rewrite includes of V8 regexp headers:
55 # Note that we exclude regexp-flags.h and provide our own definition.
56 regexp_include = re.compile('#include "src/regexp(?!/regexp-flags.h)')
57 regexp_include_new = '#include "irregexp/imported'
59 # 2. Remove includes of other V8 headers
60 other_include = re.compile('#include "src/')
62 # 3. If needed, add '#include "irregexp/RegExpShim.h"'.
63 # Note: We get a little fancy to ensure that header files are
64 # in alphabetic order. `need_to_add_shim` is true if we still
65 # have to add the shim header in this file. `adding_shim_now`
66 # is true if we have found a '#include "src/*' and we are just
67 # waiting to find an empty line so that we can insert the shim
68 # header in the right place.
69 need_to_add_shim = src_path.name in need_shim
70 adding_shim_now = False
72 for line in src:
73 if adding_shim_now:
74 if line == "\n":
75 dst.write('#include "irregexp/RegExpShim.h"\n')
76 need_to_add_shim = False
77 adding_shim_now = False
79 if regexp_include.search(line):
80 dst.write(re.sub(regexp_include, regexp_include_new, line))
81 elif other_include.search(line):
82 if need_to_add_shim:
83 adding_shim_now = True
84 else:
85 dst.write(line)
88 def import_from(srcdir, dstdir):
89 excluded = [
90 "DIR_METADATA",
91 "OWNERS",
92 "regexp.cc",
93 "regexp-flags.h",
94 "regexp-utils.cc",
95 "regexp-utils.h",
96 "regexp-macro-assembler-arch.h",
99 for file in srcdir.iterdir():
100 if file.is_dir():
101 continue
102 if str(file.name) in excluded:
103 continue
104 copy_and_update_includes(file, dstdir / "imported" / file.name)
107 if __name__ == "__main__":
108 import argparse
109 import tempfile
111 # This script should be run from js/src/irregexp to work correctly.
112 current_path = Path(os.getcwd())
113 expected_path = "js/src/irregexp"
114 if not current_path.match(expected_path):
115 raise RuntimeError("%s must be run from %s" % (sys.argv[0], expected_path))
117 parser = argparse.ArgumentParser(description="Import irregexp from v8")
118 parser.add_argument("-p", "--path", help="path to v8/src/regexp", required=False)
119 args = parser.parse_args()
121 if args.path:
122 src_path = Path(args.path)
123 provided_path = "the command-line"
124 elif "TASK_ID" in os.environ:
125 src_path = Path("/builds/worker/v8/")
126 subprocess.run("git pull origin master", shell=True, cwd=src_path)
128 src_path = Path("/builds/worker/v8/src/regexp")
129 provided_path = "the hardcoded path in the taskcluster image"
130 elif "V8_GIT" in os.environ:
131 src_path = Path(os.environ["V8_GIT"])
132 provided_path = "the V8_GIT environment variable"
133 else:
134 tempdir = tempfile.TemporaryDirectory()
135 v8_git = "https://github.com/v8/v8.git"
136 clone = "git clone --depth 1 %s %s" % (v8_git, tempdir.name)
137 os.system(clone)
138 src_path = Path(tempdir.name) / "src/regexp"
139 provided_path = "the temporary git checkout"
141 if not (src_path / "regexp.h").exists():
142 print("Could not find regexp.h in the path provided from", provided_path)
143 print("Usage:\n import-irregexp.py [--path <path/to/v8/src/regexp>]")
144 sys.exit(1)
146 if "MACH_VENDOR" not in os.environ:
147 print(
148 "Running this script outside ./mach vendor is not recommended - ",
149 "You will need to update moz.yaml manually",
151 print("We recommend instead `./mach vendor js/src/irregexp/moz.yaml`")
152 response = input("Type Y to continue... ")
153 if response.lower() != "y":
154 sys.exit(1)
156 import_from(src_path, current_path)