blob: efc1e5722d1257d1f9d12bb4835057713cd62050 [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 webkitpy.w3c.chromium_finder import absolute_chromium_dir, absolute_chromium_wpt_dir
CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/external/wpt/'
class ChromiumCommit(object):
def __init__(self, host, sha=None, position=None):
"""
Args:
host: A Host object
sha: A Chromium commit SHA
position: A string of the form:
'Cr-Commit-Position: refs/heads/master@{#431915}'
or just:
'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 and not sha:
if position.startswith('Cr-Commit-Position: '):
position = position[len('Cr-Commit-Position: '):]
sha = self.position_to_sha(position)
assert len(sha) == 40, 'Expected SHA-1 hash, got {}'.format(sha)
self.sha = sha
self.position = position
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 subject(self):
return self.host.executive.run_command([
'git', 'show', '--format=%s', '--no-patch', self.sha
], cwd=self.absolute_chromium_dir)
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)
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 filtered_changed_files(self):
"""Makes a patch with just changes in files in the WPT dir for a given commit."""
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()
blacklist = [
'MANIFEST.json',
self.host.filesystem.join('resources', 'testharnessreport.js'),
]
qualified_blacklist = [CHROMIUM_WPT_DIR + f for f in blacklist]
return [f for f in changed_files if f not in qualified_blacklist and not self.is_baseline(f)]
@staticmethod
def is_baseline(basename):
# TODO(qyearsley): Find a better, centralized place for this.
return basename.endswith('-expected.txt')
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)