blob: b443b2aa1b487d7d29b6b62197750a1ef98f49b3 [file] [log] [blame]
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from blinkpy.common.system.executive import ScriptError
from blinkpy.w3c.chromium_finder import absolute_chromium_dir, absolute_chromium_wpt_dir
from blinkpy.w3c.common import is_file_exportable
class ChromiumCommit(object):
def __init__(self, host, sha=None, position=None):
"""Initializes a ChomiumCommit object, given a sha or commit position.
Args:
host: A Host object.
sha: A Chromium commit SHA hash.
position: A commit position footer string of the form:
'Cr-Commit-Position: refs/heads/master@{#431915}'
or just the commit position string:
'refs/heads/master@{#431915}'
"""
self.host = host
self.absolute_chromium_dir = absolute_chromium_dir(host)
self.absolute_chromium_wpt_dir = absolute_chromium_wpt_dir(host)
assert sha or position, 'requires sha or position'
assert not (sha and position), 'cannot accept both sha and position'
if position:
if position.startswith('Cr-Commit-Position: '):
position = position[len('Cr-Commit-Position: '):]
sha = self.position_to_sha(position)
else:
position = self.sha_to_position(sha)
assert len(sha) == 40, 'Expected SHA-1 hash, got {}'.format(sha)
assert sha and position, 'ChromiumCommit should have sha and position after __init__'
self.sha = sha
self.position = position
def __str__(self):
return '{} "{}"'.format(self.short_sha, self.subject())
@property
def short_sha(self):
return self.sha[0:10]
def num_behind_master(self):
"""Returns the number of commits this commit is behind origin/master.
It is inclusive of this commit and of the latest commit.
"""
return len(
self.host.executive.run_command(
['git', 'rev-list', '{}..origin/master'.format(self.sha)],
cwd=self.absolute_chromium_dir).splitlines())
def position_to_sha(self, commit_position):
return self.host.executive.run_command(
['git', 'crrev-parse', commit_position],
cwd=self.absolute_chromium_dir).strip()
def sha_to_position(self, sha):
try:
return self.host.executive.run_command(
['git', 'footers', '--position', sha],
cwd=self.absolute_chromium_dir).strip()
except ScriptError as e:
# Commits from Gerrit CLs that have not yet been committed in
# Chromium do not have a commit position.
if 'Unable to infer commit position from footers' in e.message:
return 'no-commit-position-yet'
else:
raise
def subject(self):
return self.host.executive.run_command(
['git', 'show', '--format=%s', '--no-patch', self.sha],
cwd=self.absolute_chromium_dir).strip()
def body(self):
return self.host.executive.run_command(
['git', 'show', '--format=%b', '--no-patch', self.sha],
cwd=self.absolute_chromium_dir)
def author(self):
return self.host.executive.run_command(
['git', 'show', '--format=%aN <%aE>', '--no-patch', self.sha],
cwd=self.absolute_chromium_dir).strip()
def message(self):
"""Returns a string with a commit's subject and body."""
return self.host.executive.run_command(
['git', 'show', '--format=%B', '--no-patch', self.sha],
cwd=self.absolute_chromium_dir)
def change_id(self):
"""Returns the Change-Id footer if it is present."""
return self.host.executive.run_command(
['git', 'footers', '--key', 'Change-Id', self.sha],
cwd=self.absolute_chromium_dir).strip()
def filtered_changed_files(self):
"""Returns a list of modified exportable files."""
changed_files = self.host.executive.run_command(
[
'git', 'diff-tree', '--name-only', '--no-commit-id', '-r',
self.sha, '--', self.absolute_chromium_wpt_dir
],
cwd=self.absolute_chromium_dir).splitlines()
return [f for f in changed_files if is_file_exportable(f)]
def format_patch(self):
"""Makes a patch with only exportable changes."""
filtered_files = self.filtered_changed_files()
if not filtered_files:
return ''
return self.host.executive.run_command(
['git', 'format-patch', '-1', '--stdout', self.sha, '--'] +
filtered_files,
cwd=self.absolute_chromium_dir)
def url(self):
"""Returns a URL to view more information about this commit."""
return 'https://chromium.googlesource.com/chromium/src/+/%s' % self.short_sha