blob: dd4586ce31686d36057b9373512ade9c27b0cd33 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2010 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.
"""Bugdroid Git implementation for the Skia repositories.
Execute the script with the following command:
python bugdroid_git.py --repo /storage/skia-repos/skia \
--log-file-name skia-bugdroid-log.txt
"""
import logging
import optparse
import os
import sys
import time
import traceback
from bugdroid import Bugdroid
# Set the PYTHONPATH for this script to include skia_slave_scripts.utils.
sys.path.append(
os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir,
os.pardir, 'slave', 'skia_slave_scripts', 'utils'))
import shell_utils
# Time to sleep between repository polls.
SLEEP_BETWEEN_POLLS = 60
# The user BugDroid is run as
BUGDROID_USER = 'skia-commit-bot@chromium.org'
# The number of times to retry the git fetch command if it fails.
RETRY_FETCH_COUNT = 5
def main():
parser = optparse.OptionParser()
parser.add_option('-a', '--allowed-projects', action='append',
default=['skia'],
dest='trackers',
help='issue trackers that can be updated')
parser.add_option('-e', '--default-project', dest='default_tracker',
help='the issue tracker to update if no project name is '
'given in the BUG= line', default='skia')
parser.add_option('-c', '--rev-link', dest='rev_link',
help='the link to the committed revision in the repository '
'Eg: https://skia.googlesource.com/skia/+/')
parser.add_option('-v', '--version', dest='version_string',
help='the version string to be printed in the log.',
default='1.0')
parser.add_option('-r', '--repo', dest='repo_location',
help='the complete path to the git repository bugdroid '
'should track.')
parser.add_option('-l', '--log-file-name', dest='log_file_name',
help='the name of the bugdroid log file, it will be '
'created in the same directory as this file.')
(options, _args) = parser.parse_args()
# Validate arguments.
repo_location = options.repo_location
if not repo_location or not os.path.exists(repo_location):
raise Exception('Must specify a valid path to a repository using --repo')
# Configure the logger
folder_path = os.path.dirname(os.path.abspath(__file__))
log_file_path = os.path.join(folder_path, options.log_file_name)
logging.basicConfig(filename=log_file_path, level=logging.DEBUG, maxBytes=10)
logging.debug('===========================================')
logging.debug(time.strftime('Bugdroid starting: %Y-%m-%d %H:%M:%S'))
logging.debug('Current bugdroid version %s' % options.version_string)
# Find and use the .bugdroid_password file from the toplevel buildbot dir.
parent = os.path.dirname(os.path.abspath(__file__))
password_path = os.path.join(parent, os.pardir, os.pardir,
'.bugdroid_password')
if os.path.exists(password_path):
logging.debug('Using the local password file: %s' % password_path)
password = open(password_path, 'r').readline().strip()
else:
logging.debug('No password file present, aborting!')
return 1
bugger = Bugdroid(BUGDROID_USER, password)
if not bugger.login():
logging.debug('Login failed, aborting.')
return 1
# Keep going till the process is killed by a Keyboard Interrupt.
try:
while True:
# Change cwd to the repo_location.
os.chdir(repo_location)
# Do a git fetch on the specified repository.
git_fetch_cmd = ['git', 'fetch']
for _ in range(RETRY_FETCH_COUNT):
try:
shell_utils.run(git_fetch_cmd)
break
except shell_utils.CommandFailedException:
# git fetch in bugdroid sometimes seems to fail with a 406. Retry when
# this happens.
traceback.print_exc()
else:
# If we get here then the git fetch command did not succeed and thus did
# not break out of the loop.
raise Exception('git fetch failed!')
# Find all new commits.
git_rev_list_cmd = [
'git',
'rev-list',
'--topo-order',
'HEAD..origin/master',
]
remaining_hashes = shell_utils.run(git_rev_list_cmd)
if remaining_hashes:
remaining_hashes = remaining_hashes.split()
while remaining_hashes:
next_hash = remaining_hashes.pop()
# Checkout the next commit hash.
git_checkout_cmd = [
'git',
'checkout',
next_hash
]
shell_utils.run(git_checkout_cmd)
# Run Bugdroid using the content_info of the hash.
get_content_info = [
'git',
'show',
'--pretty=format:Commit: ' +
options.rev_link + '%h%n Email: %ae%n%n%s%n%n%b%n%ad',
'--name-status'
]
content = shell_utils.run(get_content_info)
if not bugger.process_all_bugs(content, options.trackers,
options.default_tracker):
logging.debug('No bug ID was found in %s.', next_hash)
# Wait for a minute before trying everything again
logging.debug('Sleeping %s seconds before trying again.',
SLEEP_BETWEEN_POLLS)
time.sleep(SLEEP_BETWEEN_POLLS)
except KeyboardInterrupt as e:
logging.exception(e)
logging.debug(time.strftime('Bugdroid exiting: %Y-%m-%d %H:%M:%S'))
if __name__ == '__main__':
main()