diff options
author | Jian Cai <jiancai@google.com> | 2020-04-15 17:53:41 -0700 |
---|---|---|
committer | Jian Cai <jiancai@google.com> | 2020-04-17 01:17:18 +0000 |
commit | c16daa1eb92cba9781a557798b065747128acfb1 (patch) | |
tree | 66b489e45c1227bc89be29a6fc20bee885e3256f /llvm_tools/git.py | |
parent | 9258b055847fcefb635c0aa74d5be08e699ab37c (diff) | |
download | toolchain-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-x | llvm_tools/git.py | 136 |
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))) |