| #!/usr/bin/env python |
| # Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. |
| # |
| # Use of this source code is governed by a BSD-style license |
| # that can be found in the LICENSE file in the root of the source |
| # tree. An additional intellectual property rights grant can be found |
| # in the file PATENTS. All contributing project authors may |
| # be found in the AUTHORS file in the root of the source tree. |
| |
| """Script to auto-update the WebRTC source version in call/version.cc""" |
| |
| import argparse |
| import datetime |
| import logging |
| import os |
| import re |
| import subprocess |
| import sys |
| |
| |
| def FindSrcDirPath(): |
| """Returns the abs path to the src/ dir of the project.""" |
| src_dir = os.path.dirname(os.path.abspath(__file__)) |
| while os.path.basename(src_dir) != 'src': |
| src_dir = os.path.normpath(os.path.join(src_dir, os.pardir)) |
| return src_dir |
| |
| |
| UPDATE_BRANCH_NAME = 'webrtc_version_update' |
| CHECKOUT_SRC_DIR = FindSrcDirPath() |
| |
| |
| def _RemovePreviousUpdateBranch(): |
| active_branch, branches = _GetBranches() |
| if active_branch == UPDATE_BRANCH_NAME: |
| active_branch = 'master' |
| if UPDATE_BRANCH_NAME in branches: |
| logging.info('Removing previous update branch (%s)', |
| UPDATE_BRANCH_NAME) |
| subprocess.check_call(['git', 'checkout', active_branch]) |
| subprocess.check_call(['git', 'branch', '-D', UPDATE_BRANCH_NAME]) |
| logging.info('No branch to remove') |
| |
| |
| def _GetLastAuthor(): |
| """Returns a string with the author of the last commit.""" |
| author = subprocess.check_output(['git', 'log', |
| '-1', |
| '--pretty=format:"%an"']).splitlines() |
| return author |
| |
| |
| def _GetBranches(): |
| """Returns a tuple (active, branches). |
| |
| 'active' is a string with name of the currently active branch, while |
| 'branches' is the list of all branches. |
| """ |
| lines = subprocess.check_output(['git', 'branch']).splitlines() |
| branches = [] |
| active = '' |
| for line in lines: |
| if '*' in line: |
| # The assumption is that the first char will always be the '*'. |
| active = line[1:].strip() |
| branches.append(active) |
| else: |
| branch = line.strip() |
| if branch: |
| branches.append(branch) |
| return active, branches |
| |
| |
| def _CreateUpdateBranch(): |
| logging.info('Creating update branch: %s', UPDATE_BRANCH_NAME) |
| subprocess.check_call(['git', 'checkout', '-b', UPDATE_BRANCH_NAME]) |
| |
| |
| def _UpdateWebRTCVersion(filename): |
| with open(filename) as f: |
| content = f.read() |
| d = datetime.datetime.utcnow() |
| # pylint: disable=line-too-long |
| new_content = re.sub( |
| r'WebRTC source stamp [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}', |
| r'WebRTC source stamp %02d-%02d-%02dT%02d:%02d:%02d' % (d.year, |
| d.month, |
| d.day, |
| d.hour, |
| d.minute, |
| d.second), |
| content, |
| flags=re.MULTILINE) |
| # pylint: enable=line-too-long |
| with open(filename, 'w') as f: |
| f.write(new_content) |
| |
| |
| def _IsTreeClean(): |
| stdout = subprocess.check_output(['git', 'status', '--porcelain']) |
| if len(stdout) == 0: |
| return True |
| return False |
| |
| |
| def _LocalCommit(): |
| logging.info('Committing changes locally.') |
| d = datetime.datetime.utcnow() |
| |
| git_author = subprocess.check_output(['git', 'config', |
| 'user.email']).strip() |
| commit_msg = ('Update WebRTC code version (%02d-%02d-%02dT%02d:%02d:%02d).' |
| '\n\nBug: None') |
| commit_msg = commit_msg % (d.year, d.month, d.day, d.hour, d.minute, |
| d.second) |
| subprocess.check_call(['git', 'add', '--update', '.']) |
| subprocess.check_call(['git', 'commit', '-m', commit_msg]) |
| |
| |
| def _UploadCL(commit_queue_mode): |
| """Upload the committed changes as a changelist to Gerrit. |
| |
| commit_queue_mode: |
| - 2: Submit to commit queue. |
| - 1: Run trybots but do not submit to CQ. |
| - 0: Skip CQ, upload only. |
| """ |
| cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks', |
| '--cc=""', '--bypass-watchlist'] |
| if commit_queue_mode >= 2: |
| logging.info('Sending the CL to the CQ...') |
| cmd.extend(['-o', 'label=Bot-Commit+1']) |
| cmd.extend(['-o', 'label=Commit-Queue+2']) |
| elif commit_queue_mode >= 1: |
| logging.info('Starting CQ dry run...') |
| cmd.extend(['-o', 'label=Commit-Queue+1']) |
| subprocess.check_call(cmd) |
| |
| |
| def main(): |
| logging.basicConfig(level=logging.INFO) |
| p = argparse.ArgumentParser() |
| p.add_argument('--clean', |
| action='store_true', |
| default=False, |
| help='Removes any previous local update branch.') |
| opts = p.parse_args() |
| |
| if opts.clean: |
| _RemovePreviousUpdateBranch() |
| |
| if _GetLastAuthor() == 'webrtc-version-updater': |
| logging.info('Last commit is a version change, skipping CL.') |
| return 0 |
| |
| version_filename = os.path.join(CHECKOUT_SRC_DIR, 'call', 'version.cc') |
| _CreateUpdateBranch() |
| _UpdateWebRTCVersion(version_filename) |
| if _IsTreeClean(): |
| logging.info('No WebRTC version change detected, skipping CL.') |
| else: |
| _LocalCommit() |
| logging.info('Uploading CL...') |
| _UploadCL(2) |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |