aboutsummaryrefslogtreecommitdiff
path: root/llvm_tools/git.py
blob: f38d5e72c81d5f0fb862a8b6f29c47d73c7ef1c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/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)))