[tools] add script to simplify backporting patch to Node.js
usage: backport_node.py <v8 dir> <node dir> <commit hash> [--no-review] R=franzih@chromium.org, machenbach@chromium.org Review-Url: https://codereview.chromium.org/2838843002 Cr-Commit-Position: refs/heads/master@{#44853}
This commit is contained in:
parent
e671ed3610
commit
fed3e09356
96
tools/release/backport_node.py
Executable file
96
tools/release/backport_node.py
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2017 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""
|
||||
Use this script to cherry-pick a V8 commit to backport to a Node.js checkout.
|
||||
|
||||
Requirements:
|
||||
- Node.js checkout to backport to.
|
||||
- V8 checkout that contains the commit to cherry-pick.
|
||||
|
||||
Usage:
|
||||
$ backport_node.py <path_to_v8> <path_to_node> <commit-hash>
|
||||
|
||||
This will apply the commit to <path_to_node>/deps/v8 and create a commit in
|
||||
the Node.js checkout and copy over the original commit message.
|
||||
|
||||
Optional flags:
|
||||
--no-review Run `gclient sync` on the V8 checkout before updating.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
TARGET_SUBDIR = os.path.join("deps", "v8")
|
||||
|
||||
def CherryPick(options):
|
||||
print ">> Apply patch."
|
||||
patch = subprocess.Popen(["git", "diff-tree", "-p", options.commit],
|
||||
stdout=subprocess.PIPE, cwd=options.v8_path)
|
||||
patch.wait()
|
||||
try:
|
||||
subprocess.check_output(["git", "apply", "-3", "--directory=%s" % TARGET_SUBDIR],
|
||||
stdin=patch.stdout, cwd=options.node_path)
|
||||
except:
|
||||
print ">> In another shell, please resolve patch conflicts"
|
||||
print ">> and `git add` affected files."
|
||||
print ">> Finally continue by entering RESOLVED."
|
||||
while raw_input("[RESOLVED]") != "RESOLVED":
|
||||
print ">> You need to type RESOLVED"
|
||||
|
||||
def CreateCommit(options):
|
||||
print ">> Creating commit."
|
||||
# Find short hash from source.
|
||||
shorthash = subprocess.check_output(
|
||||
["git", "rev-parse", "--short", options.commit],
|
||||
cwd=options.v8_path).strip()
|
||||
|
||||
# Commit message
|
||||
title = "deps: backport %s from upstream V8" % shorthash
|
||||
body = subprocess.check_output(
|
||||
["git", "log", options.commit, "-1", "--format=%B"],
|
||||
cwd=options.v8_path).strip()
|
||||
body = '\n'.join(" " + line for line in body.splitlines())
|
||||
|
||||
message = title + "\n\nOriginal commit message:\n\n" + body
|
||||
|
||||
# Create commit at target.
|
||||
review_message = "" if options.no_review else "-e"
|
||||
git_commands = [
|
||||
["git", "checkout", "-b", "backport_%s" % shorthash], # new branch
|
||||
["git", "add", TARGET_SUBDIR], # add files
|
||||
["git", "commit", "-m", message, review_message] # new commit
|
||||
]
|
||||
for command in git_commands:
|
||||
subprocess.check_call(command, cwd=options.node_path)
|
||||
|
||||
def ParseOptions(args):
|
||||
parser = argparse.ArgumentParser(description="Backport V8 commit to Node.js")
|
||||
parser.add_argument("v8_path", help="Path to V8 checkout")
|
||||
parser.add_argument("node_path", help="Path to Node.js checkout")
|
||||
parser.add_argument("commit", help="Commit to backport")
|
||||
parser.add_argument("--no-review", action="store_true",
|
||||
help="Skip editing commit message")
|
||||
options = parser.parse_args(args)
|
||||
options.v8_path = os.path.abspath(options.v8_path)
|
||||
assert os.path.isdir(options.v8_path)
|
||||
options.node_path = os.path.abspath(options.node_path)
|
||||
assert os.path.isdir(options.node_path)
|
||||
return options
|
||||
|
||||
def Main(args):
|
||||
options = ParseOptions(args)
|
||||
try:
|
||||
CherryPick(options)
|
||||
CreateCommit(options)
|
||||
except:
|
||||
print ">> Failed. Resetting."
|
||||
subprocess.check_output(["git", "reset", "--hard"], cwd=options.node_path)
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
Main(sys.argv[1:])
|
66
tools/release/test_backport_node.py
Executable file
66
tools/release/test_backport_node.py
Executable file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2017 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import backport_node
|
||||
|
||||
# Base paths.
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
TEST_DATA = os.path.join(BASE_DIR, 'testdata')
|
||||
|
||||
def gitify(path):
|
||||
files = os.listdir(path)
|
||||
subprocess.check_call(['git', 'init'], cwd=path)
|
||||
subprocess.check_call(['git', 'add'] + files, cwd=path)
|
||||
subprocess.check_call(['git', 'commit', '-m', 'Initial'], cwd=path)
|
||||
|
||||
class TestUpdateNode(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.workdir = tempfile.mkdtemp(prefix='tmp_test_node_')
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.workdir)
|
||||
|
||||
def testUpdate(self):
|
||||
v8_cwd = os.path.join(self.workdir, 'v8')
|
||||
node_cwd = os.path.join(self.workdir, 'node')
|
||||
|
||||
# Set up V8 test fixture.
|
||||
shutil.copytree(src=os.path.join(TEST_DATA, 'v8'), dst=v8_cwd)
|
||||
gitify(v8_cwd)
|
||||
|
||||
# Set up node test fixture.
|
||||
shutil.copytree(src=os.path.join(TEST_DATA, 'node'), dst=node_cwd)
|
||||
gitify(os.path.join(node_cwd))
|
||||
|
||||
# Add a patch.
|
||||
with open(os.path.join(v8_cwd, 'v8_foo'), 'w') as f:
|
||||
f.write('zonk')
|
||||
subprocess.check_call(['git', 'add', 'v8_foo'], cwd=v8_cwd)
|
||||
subprocess.check_call(['git', 'commit', '-m', "Title\n\nBody"], cwd=v8_cwd)
|
||||
commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=v8_cwd).strip()
|
||||
|
||||
# Run update script.
|
||||
backport_node.Main([v8_cwd, node_cwd, commit, "--no-review"])
|
||||
|
||||
# Check message.
|
||||
message = subprocess.check_output(['git', 'log', '-1', '--format=%B'], cwd=node_cwd)
|
||||
self.assertIn('Original commit message:\n\n Title\n\n Body', message)
|
||||
|
||||
# Check patch.
|
||||
gitlog = subprocess.check_output(
|
||||
['git', 'diff', 'master', '--cached', '--', 'deps/v8/v8_foo'],
|
||||
cwd=node_cwd,
|
||||
)
|
||||
self.assertIn('+zonk', gitlog.strip())
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -3,6 +3,26 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
"""
|
||||
Use this script to update V8 in a Node.js checkout.
|
||||
|
||||
Requirements:
|
||||
- Node.js checkout in which V8 should be updated.
|
||||
- V8 checkout at the commit to which Node.js should be updated.
|
||||
|
||||
Usage:
|
||||
$ update_node.py <path_to_v8> <path_to_node>
|
||||
|
||||
This will synchronize the content of <path_to_node>/deps/v8 with <path_to_v8>,
|
||||
and a few V8 dependencies require in Node.js. It will also update .gitignore
|
||||
appropriately.
|
||||
|
||||
Optional flags:
|
||||
--gclient Run `gclient sync` on the V8 checkout before updating.
|
||||
--commit Create commit with the updated V8 in the Node.js checkout.
|
||||
--with-patch Also include currently staged files in the V8 checkout.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
|
Loading…
Reference in New Issue
Block a user