You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.2 KiB
122 lines
3.2 KiB
4 months ago
|
#!/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'])
|
||
|
|
||
|
subprocess.check_output(['repo', 'start', branch], cwd=repo)
|
||
|
|
||
|
|
||
|
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'])
|
||
|
|
||
|
subprocess.check_output(['git', '-C', repo, 'reset', 'HEAD', '--hard'])
|
||
|
|
||
|
subprocess.check_output(['git', '-C', repo, 'branch', '-D', branch])
|
||
|
|
||
|
|
||
|
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)
|
||
|
|
||
|
# Upload the changes for review.
|
||
|
out = subprocess.check_output(
|
||
|
['repo', 'upload', '--yes', '--ne', '--no-verify',
|
||
|
'--br=%s' % branch],
|
||
|
stderr=subprocess.STDOUT,
|
||
|
cwd=repo,
|
||
|
encoding='utf-8')
|
||
|
|
||
|
print(out)
|
||
|
|
||
|
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)))
|