aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/git.py
diff options
context:
space:
mode:
authorJian Cai <jiancai@google.com>2020-04-15 17:53:41 -0700
committerJian Cai <jiancai@google.com>2020-04-17 01:17:18 +0000
commitc16daa1eb92cba9781a557798b065747128acfb1 (patch)
tree66b489e45c1227bc89be29a6fc20bee885e3256f /llvm_tools/git.py
parent9258b055847fcefb635c0aa74d5be08e699ab37c (diff)
downloadtoolchain-utils-c16daa1eb92cba9781a557798b065747128acfb1.tar.gz
llvm_tools: move common functions into standalone modules
Move common functions into separate modules and update dependencies accordingly. BUG=chromium:1057428 TEST=local tests. Change-Id: I40f1b613f0a41f1fc478c811379c851479aff7c3 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2151708 Reviewed-by: Manoj Gupta <manojgupta@chromium.org> Reviewed-by: George Burgess <gbiv@chromium.org> Tested-by: Jian Cai <jiancai@google.com>
Diffstat (limited to 'llvm_tools/git.py')
-rwxr-xr-xllvm_tools/git.py136
1 files changed, 136 insertions, 0 deletions
diff --git a/llvm_tools/git.py b/llvm_tools/git.py
new file mode 100755
index 00000000..778d9695
--- /dev/null
+++ b/llvm_tools/git.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+# Copyright 2020 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Git helper functions."""
+
+from __future__ import print_function
+
+import collections
+import os
+import re
+import subprocess
+import tempfile
+
+CommitContents = collections.namedtuple('CommitContents', ['url', 'cl_number'])
+
+
+def InChroot():
+ """Returns True if currently in the chroot."""
+ return 'CROS_WORKON_SRCROOT' in os.environ
+
+
+def VerifyOutsideChroot():
+ """Checks whether the script invoked was executed in the chroot.
+
+ Raises:
+ AssertionError: The script was run inside the chroot.
+ """
+
+ assert not InChroot(), 'Script should be run outside the chroot.'
+
+
+def CreateBranch(repo, branch):
+ """Creates a branch in the given repo.
+
+ Args:
+ repo: The absolute path to the repo.
+ branch: The name of the branch to create.
+
+ Raises:
+ ValueError: Failed to create a repo in that directory.
+ """
+
+ if not os.path.isdir(repo):
+ raise ValueError('Invalid directory path provided: %s' % repo)
+
+ subprocess.check_output(['git', '-C', repo, 'reset', 'HEAD', '--hard'],
+ encoding='utf-8')
+
+ subprocess.check_output(['repo', 'start', branch], cwd=repo, encoding='utf-8')
+
+
+def DeleteBranch(repo, branch):
+ """Deletes a branch in the given repo.
+
+ Args:
+ repo: The absolute path of the repo.
+ branch: The name of the branch to delete.
+
+ Raises:
+ ValueError: Failed to delete the repo in that directory.
+ """
+
+ if not os.path.isdir(repo):
+ raise ValueError('Invalid directory path provided: %s' % repo)
+
+ subprocess.check_output(['git', '-C', repo, 'checkout', 'cros/master'],
+ encoding='utf-8')
+
+ subprocess.check_output(['git', '-C', repo, 'reset', 'HEAD', '--hard'],
+ encoding='utf-8')
+
+ subprocess.check_output(['git', '-C', repo, 'branch', '-D', branch],
+ encoding='utf-8')
+
+
+def UploadChanges(repo, branch, commit_messages):
+ """Uploads the changes in the specifed branch of the given repo for review.
+
+ Args:
+ repo: The absolute path to the repo where changes were made.
+ branch: The name of the branch to upload.
+ commit_messages: A string of commit message(s) (i.e. '[message]'
+ of the changes made.
+
+ Returns:
+ A nametuple that has two (key, value) pairs, where the first pair is the
+ Gerrit commit URL and the second pair is the change list number.
+
+ Raises:
+ ValueError: Failed to create a commit or failed to upload the
+ changes for review.
+ """
+
+ if not os.path.isdir(repo):
+ raise ValueError('Invalid path provided: %s' % repo)
+
+ # Create a git commit.
+ with tempfile.NamedTemporaryFile(mode='w+t') as f:
+ f.write('\n'.join(commit_messages))
+ f.flush()
+
+ subprocess.check_output(['git', 'commit', '-F', f.name],
+ cwd=repo,
+ encoding='utf-8')
+
+ # Upload the changes for review.
+ # Pylint currently doesn't lint things in py3 mode, and py2 didn't allow
+ # users to specify `encoding`s for Popen. Hence, pylint is "wrong" here.
+ # pylint: disable=unexpected-keyword-arg
+ # The CL URL is sent to 'stderr', so need to redirect 'stderr' to 'stdout'.
+ upload_changes_obj = subprocess.Popen(
+ ['repo', 'upload', '--yes', '--ne', '--no-verify',
+ '--br=%s' % branch],
+ cwd=repo,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ encoding='utf-8')
+
+ out, _ = upload_changes_obj.communicate()
+
+ if upload_changes_obj.returncode: # Failed to upload changes.
+ print(out)
+ raise ValueError('Failed to upload changes for review')
+
+ found_url = re.search(
+ r'https://chromium-review.googlesource.com/c/'
+ r'chromiumos/overlays/chromiumos-overlay/\+/([0-9]+)', out.rstrip())
+
+ if not found_url:
+ raise ValueError('Failed to find change list URL.')
+
+ return CommitContents(
+ url=found_url.group(0), cl_number=int(found_url.group(1)))