Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # -*- coding: utf-8 -*-" |
| 3 | # |
| 4 | # Copyright 2020 The Chromium OS Authors. All rights reserved. |
| 5 | # Use of this source code is governed by a BSD-style license that can be |
| 6 | # found in the LICENSE file. |
| 7 | |
| 8 | """Module containing methods interfacing with git |
| 9 | |
| 10 | i.e Parsing git logs for change-id, full commit sha's, etc. |
| 11 | """ |
| 12 | |
| 13 | from __future__ import print_function |
| 14 | import os |
| 15 | import re |
| 16 | import subprocess |
| 17 | import common |
| 18 | |
| 19 | |
| 20 | def get_upstream_fullsha(abbrev_sha): |
| 21 | """Returns the full upstream sha for an abbreviated 12 digit sha using git cli""" |
| 22 | upstream_absolute_path = common.get_kernel_absolute_path(common.UPSTREAM_PATH) |
| 23 | try: |
| 24 | cmd = ['git', '-C', upstream_absolute_path, 'rev-parse', abbrev_sha] |
Hirthanan Subenderan | affcc4a | 2020-03-25 14:42:33 -0700 | [diff] [blame] | 25 | full_sha = subprocess.check_output(cmd, encoding='utf-8') |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 26 | return full_sha.rstrip() |
| 27 | except subprocess.CalledProcessError as e: |
| 28 | raise type(e)('Could not find full upstream sha for %s' % abbrev_sha, e.cmd) from e |
| 29 | |
| 30 | |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 31 | def get_commit_message(kernel_path, sha): |
| 32 | """Returns the commit message for a sha in a given local path to kernel.""" |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 33 | try: |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 34 | cmd = ['git', '-C', kernel_path, 'log', |
| 35 | '--format=%B', '-n', '1', sha] |
Hirthanan Subenderan | affcc4a | 2020-03-25 14:42:33 -0700 | [diff] [blame] | 36 | commit_message = subprocess.check_output(cmd, encoding='utf-8', errors='ignore') |
Hirthanan Subenderan | 3450f51 | 2020-04-09 22:36:50 -0700 | [diff] [blame^] | 37 | |
| 38 | # Single newline following commit message |
| 39 | return commit_message.rstrip() + '\n' |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 40 | except subprocess.CalledProcessError as e: |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 41 | raise type(e)('Couldnt retrieve commit in kernel path %s for sha %s' |
| 42 | % (kernel_path, sha), e.cmd) from e |
| 43 | |
| 44 | |
| 45 | def get_upstream_commit_message(upstream_sha): |
| 46 | """Returns the commit message for a given upstream sha using git cli.""" |
| 47 | upstream_absolute_path = common.get_kernel_absolute_path(common.UPSTREAM_PATH) |
| 48 | return get_commit_message(upstream_absolute_path, upstream_sha) |
| 49 | |
| 50 | |
| 51 | def get_chrome_commit_message(chrome_sha): |
| 52 | """Returns the commit message for a given chrome sha using git cli.""" |
| 53 | chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH) |
| 54 | return get_commit_message(chrome_absolute_path, chrome_sha) |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 55 | |
| 56 | |
| 57 | def get_commit_changeid_linux_chrome(kernel_sha): |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 58 | """Returns the changeid of the kernel_sha commit by parsing linux_chrome git log. |
| 59 | |
| 60 | kernel_sha will be one of linux_stable or linux_chrome commits. |
| 61 | """ |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 62 | chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH) |
| 63 | try: |
| 64 | cmd = ['git', '-C', chrome_absolute_path, 'log', '--format=%B', '-n', '1', kernel_sha] |
Hirthanan Subenderan | affcc4a | 2020-03-25 14:42:33 -0700 | [diff] [blame] | 65 | commit_message = subprocess.check_output(cmd, encoding='utf-8', errors='ignore') |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 66 | |
| 67 | m = re.findall('^Change-Id: (I[a-z0-9]{40})$', commit_message, re.M) |
| 68 | |
| 69 | # Get last change-id in case chrome sha cherry-picked/reverted into new commit |
| 70 | return m[-1] |
| 71 | except subprocess.CalledProcessError as e: |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 72 | raise type(e)('Couldnt retrieve changeid for commit %s' % kernel_sha, e.cmd) from e |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 73 | except IndexError as e: |
Hirthanan Subenderan | d6922c3 | 2020-03-23 14:17:40 -0700 | [diff] [blame] | 74 | # linux_stable kernel_sha's do not have an associated ChangeID |
| 75 | return None |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 76 | |
| 77 | |
| 78 | def get_last_commit_sha_linux_chrome(): |
| 79 | """Retrieves the last SHA in linux_chrome repository.""" |
| 80 | chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH) |
| 81 | try: |
| 82 | cmd = ['git', '-C', chrome_absolute_path, 'rev-parse', 'HEAD'] |
Hirthanan Subenderan | affcc4a | 2020-03-25 14:42:33 -0700 | [diff] [blame] | 83 | last_commit = subprocess.check_output(cmd, encoding='utf-8') |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 84 | return last_commit.rstrip() |
| 85 | except subprocess.CalledProcessError as e: |
| 86 | raise type(e)('Couldnt retrieve most recent commit in linux_chrome', e.cmd) from e |
| 87 | |
| 88 | |
Hirthanan Subenderan | bbafac4 | 2020-04-10 16:18:16 -0700 | [diff] [blame] | 89 | def get_git_push_cmd(chromeos_branch, reviewers): |
| 90 | """Generates git push command with added reviewers and autogenerated tag. |
| 91 | |
| 92 | Read more about gerrit tags here: |
| 93 | https://gerrit-review.googlesource.com/Documentation/cmd-receive-pack.html |
| 94 | """ |
| 95 | git_push_head = 'git push origin HEAD:refs/for/%s' % chromeos_branch |
| 96 | reviewers_tag = ['r=%s'% r for r in reviewers] |
| 97 | autogenerated_tag = ['t=autogenerated'] |
| 98 | tags = ','.join(reviewers_tag + autogenerated_tag) |
| 99 | return git_push_head + '%' + tags |
| 100 | |
| 101 | |
| 102 | def cherry_pick_and_push_fix(fixer_upstream_sha, chromeos_branch, |
| 103 | fix_commit_message, reviewers): |
| 104 | """Cherry picks upstream commit into chrome repo. |
| 105 | |
| 106 | Adds reviewers and autogenerated tag with the pushed commit. |
| 107 | """ |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 108 | cwd = os.getcwd() |
| 109 | chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH) |
| 110 | |
| 111 | # reset linux_chrome repo to remove local changes |
| 112 | try: |
| 113 | os.chdir(chrome_absolute_path) |
Hirthanan Subenderan | bbafac4 | 2020-04-10 16:18:16 -0700 | [diff] [blame] | 114 | subprocess.run(['git', 'checkout', chromeos_branch], check=True) |
| 115 | subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True) |
| 116 | subprocess.run(['git', 'cherry-pick', '-n', fixer_upstream_sha], check=True) |
| 117 | subprocess.run(['git', 'commit', '-s', '-m', fix_commit_message], check=True) |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 118 | |
| 119 | # commit has been cherry-picked and committed locally, precommit hook |
| 120 | # in git repository adds changeid to the commit message |
| 121 | last_commit = get_last_commit_sha_linux_chrome() |
| 122 | fixer_changeid = get_commit_changeid_linux_chrome(last_commit) |
| 123 | |
Hirthanan Subenderan | bbafac4 | 2020-04-10 16:18:16 -0700 | [diff] [blame] | 124 | git_push_cmd = get_git_push_cmd(chromeos_branch, reviewers) |
| 125 | subprocess.run(git_push_cmd.split(' '), check=True) |
| 126 | subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True) |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 127 | |
| 128 | return fixer_changeid |
| 129 | except subprocess.CalledProcessError as e: |
| 130 | raise ValueError('Failed to cherrypick and push upstream fix %s on branch %s' |
| 131 | % (fixer_upstream_sha, chromeos_branch)) from e |
| 132 | finally: |
Hirthanan Subenderan | 41ac082 | 2020-04-07 21:29:31 -0700 | [diff] [blame] | 133 | subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True) |
Hirthanan Subenderan | b186655 | 2020-03-20 14:01:14 -0700 | [diff] [blame] | 134 | os.chdir(cwd) |