Last active
August 11, 2018 11:45
-
-
Save chrmoritz/ba453f27676da13928e237010491b0af to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| import re | |
| import base64 | |
| import hashlib | |
| from jinja2 import Environment | |
| from urllib2 import urlopen | |
| from threading import Thread | |
| def getV8TarballSha256(v8_tag, v8_sha256): | |
| sha256 = hashlib.sha256() | |
| sha256.update(urlopen("https://github.com/v8/v8/archive/{}.tar.gz".format(v8_tag)).read()) | |
| v8_sha256[0] = sha256.hexdigest() | |
| def main(): | |
| # get latest stable v8_tag from omahaproxy | |
| omahaproxy = urlopen("https://omahaproxy.appspot.com/all?os=mac&channel=stable").read() | |
| v8_tag = re.search("mac,stable,.*,(.*)", omahaproxy).group(1) | |
| # calculate tarball sha256 in another thread, becausing doenloading it takes the longest time | |
| v8_sha256 = [''] | |
| sha_thread = Thread(target=getV8TarballSha256, args=(v8_tag, v8_sha256)) | |
| sha_thread.start() | |
| # read main DEPS file from v8 github repo via raw.githubusercontent.com | |
| V8_DEPS = urlopen("https://raw.githubusercontent.com/v8/v8/{}/DEPS".format(v8_tag)).read() | |
| dep_locals = {'Var': lambda x: dep_locals['vars'][x], 'False': False, 'True': True} | |
| exec(V8_DEPS, {"__builtins__": None}, dep_locals) | |
| # throw if recursedeps array in main DEPS file changed | |
| # TODO: handle recursedeps properly | |
| if dep_locals['recursedeps'] != ['v8/buildtools', 'v8/third_party/android_tools']: | |
| raise Exception("incompatible recuredeps array found") | |
| # parse deps from main DEPS file | |
| deps = {} | |
| for d, r in dep_locals['deps'].items(): | |
| # blacklisting target os here instead of whitelisting checkout_mac, TODO: handle target cpu conditions? | |
| if isinstance(r, dict): | |
| if r['condition'] in ['checkout_android', 'checkout_chromeos', | |
| 'checkout_fuchsia', 'checkout_ios', 'checkout_linux', 'checkout_win']: | |
| continue | |
| r = r['url'] | |
| repo = re.search("(.*)@(.*)", r) | |
| deps[d] = {'path': d, 'url': repo.group(1), 'rev': repo.group(2)} | |
| # parse hooks from main DEPS file | |
| hooks = [] | |
| for h in dep_locals['hooks']: | |
| if 'condition' in h: | |
| c_locals = { | |
| 'host_os': 'mac', | |
| 'build_for_node': False, | |
| 'checkout_android': False, | |
| 'checkout_fuchsia': False, | |
| 'checkout_win': False, | |
| 'checkout_linux': False, | |
| 'False': False, | |
| 'True': True} | |
| c_locals.update(dep_locals['vars']) | |
| exec('condition_result = ' + h['condition'], {"__builtins__": None}, c_locals) | |
| if not c_locals['condition_result']: | |
| continue | |
| hooks.append('system "' + '", "'.join(h['action']) + '"') | |
| # read recursive DEPS file for buildtools from chromium.googlesource.com (base64 encoded) | |
| BT_DEPS = base64.standard_b64decode(urlopen( | |
| "https://chromium.googlesource.com/chromium/buildtools.git/+/{}/DEPS?format=TEXT".format(deps['v8/buildtools']['rev'])).read()) | |
| bt_dep_locals = {'Var': lambda x: bt_dep_locals['vars'][x], 'False': False, 'True': True} | |
| exec(BT_DEPS, {"__builtins__": None}, bt_dep_locals) | |
| # parse deps from buildtools recursice DEPS file | |
| for d, r in bt_dep_locals['deps'].items(): | |
| if isinstance(r, dict): # shouldn't be needed here, just in case they use it in the future | |
| if r['condition'] in ['checkout_android', 'checkout_chromeos', | |
| 'checkout_fuchsia', 'checkout_ios', 'checkout_linux', 'checkout_win']: | |
| continue | |
| r = r['url'] | |
| repo = re.search("(.*)@(.*)", r) | |
| deps[d] = {'path': d, 'url': repo.group(1), 'rev': repo.group(2)} | |
| env = Environment(trim_blocks=True) | |
| FORMULA_TEMPLATE = env.from_string("""\ | |
| class V8 < Formula | |
| desc "Google's JavaScript engine" | |
| homepage "https://github.com/v8/v8/wiki" | |
| url "https://github.com/v8/v8/archive/{{ v8_tag }}.tar.gz" | |
| sha256 "{{ v8_sha256 }}" | |
| bottle do | |
| cellar :any | |
| sha256 "179a8442510eb0a022ea6823cd6a76044c14c4fe18415710cac3d746d432020e" => :high_sierra | |
| sha256 "8106efc14371982af11a66d8db533dc0589bc240950e0e445467cf6ce8871393" => :sierra | |
| sha256 "487f2ca72096ee27d13533a6dad2d472a92ba40ef518a45226f19e94d4a79242" => :el_capitan | |
| sha256 "dc9af3e08eda8a4acd1ff3c6b47a4c5170a92dbab7d2d79958a14d8aa42eefac" => :yosemite | |
| sha256 "7bcd1bbd66c11305eeea0c36ca472de8a639f511abe0909c8815b1208dbce7b6" => :mavericks | |
| end | |
| # https://bugs.chromium.org/p/chromium/issues/detail?id=620127 | |
| depends_on :macos => :el_capitan | |
| # depot_tools/GN require Python 2.7+ | |
| depends_on "python@2" => :build | |
| needs :cxx11 | |
| {% for d in deps.values() %} | |
| {% include ResourceTemplate %} | |
| {% endfor %} | |
| def install | |
| (buildpath/"v8").install Dir.glob("*", File::FNM_DOTMATCH) - %w[. .. .brew_home] | |
| # autogenerated installing resources to paths according to DEPS file | |
| {% for d in deps.values() %} | |
| (buildpath/"{{ d.path }}").install resource("{{ d.path }}") | |
| {% endfor %} | |
| # add depot_tools to PATH (for download_from_google_storage tool) | |
| ENV.prepend_path "PATH", buildpath/"v8/third_party/depot_tools" | |
| # autogenerated system calls for hooks in DEPS file | |
| {% for h in hooks %} | |
| {{ h }} | |
| {% endfor %} | |
| cd "v8" do | |
| output_path = "out.gn/x64.release" | |
| gn_args = { | |
| :is_debug => false, | |
| :is_component_build => true, | |
| :v8_use_external_startup_data => false, | |
| :v8_enable_i18n_support => true, | |
| } | |
| # Transform to args string | |
| gn_args_string = gn_args.map { |k, v| "#{k}=#{v}" }.join(" ") | |
| # Build with gn + ninja | |
| system "gn", | |
| "gen", | |
| "--args=#{gn_args_string}", | |
| output_path | |
| system "ninja", | |
| "-j", ENV.make_jobs, | |
| "-C", output_path, | |
| "-v", | |
| "d8" | |
| # Install all the things | |
| include.install Dir["include/*"] | |
| cd output_path do | |
| lib.install Dir["lib*.dylib"] | |
| # Install d8 and icudtl.dat in libexec and symlink | |
| # because they need to be in the same directory. | |
| libexec.install Dir["d8", "icudt*.dat"] | |
| (bin/"d8").write <<~EOS | |
| #!/bin/bash | |
| exec "#{libexec}/d8" --icu-data-file="#{libexec}/icudtl.dat" "$@" | |
| EOS | |
| end | |
| end | |
| end | |
| test do | |
| assert_equal "Hello World!", shell_output("#{bin}/d8 -e 'print(\\"Hello World!\\");'").chomp | |
| assert_match %r{12/\\d{2}/2012}, shell_output("#{bin}/d8 -e 'print(new Intl.DateTimeFormat(\\"en-US\\").format(new Date(Date.UTC(2012, 11, 20, 3, 0, 0))));'").chomp | |
| end | |
| end | |
| """) | |
| RESOURCE_TEMPLATE = env.from_string("""\ | |
| resource "{{ d.path }}" do | |
| url "{{ d.url }}", | |
| :revision => "{{ d.rev }}" | |
| end | |
| """) | |
| sha_thread.join() # waiting for v8 tarball hasher thread | |
| formula = FORMULA_TEMPLATE.render( | |
| v8_tag=v8_tag, | |
| v8_sha256=v8_sha256[0], | |
| deps=deps, | |
| hooks=hooks, | |
| ResourceTemplate=RESOURCE_TEMPLATE) | |
| print(formula) | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment