blob: 08b5c8092021b9faea6dd40d549e604f5f4f41dd [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2017 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
### view commits not yet rolled to a layer
import argparse
from argparse import RawTextHelpFormatter
import base64
import json
import requests
import sys
import xml.etree.ElementTree as xml
LAYERS = [
'vendor', # For checkouts building on top of Topaz.
'topaz',
'peridot',
'garnet',
'zircon',
]
def get_lower_layer(layer):
"""Returns the layer immediately below the given layer."""
index = LAYERS.index(layer)
if index == len(LAYERS) - 1:
return None
return LAYERS[index + 1]
def get_lower_layer_commit(layer, at):
"""Returns the pinned revision of the layer below the given layer."""
lower_layer = get_lower_layer(layer)
if not lower_layer:
return (None, None)
url = ('https://fuchsia.googlesource.com/%s/+/%s/manifest/%s?format=TEXT'
% (layer, at, layer))
content = requests.get(url).content
content = base64.b64decode(content)
manifest = xml.fromstring(content)
nodes = manifest.findall('./imports/import[@name="%s"]' % lower_layer)
return (lower_layer, nodes[0].get('revision'))
def get_commits(layer, revision):
"""Returns the commits in the given layer up to a given commit."""
url = 'https://fuchsia.googlesource.com/%s/+log/master?format=JSON' % layer
def get_more(result, start=None):
get_url = url
if start:
get_url = '%s&s=%s' % (url, start)
content = requests.get(url).content
# Remove the anti-XSSI header.
content = content[5:]
data = json.loads(content)
for commit in data['log']:
if commit['commit'] == revision:
return
result.append(commit)
get_more(result, start=content['next'])
result = []
get_more(result)
return result
def filter_commit(commit):
"""Returns True if a commit should be listed."""
author = commit['author']['name']
if author == 'skia-deps-roller@chromium.org':
return False
for layer in LAYERS:
if author == '%s-roller' % layer:
return False
return True
def print_commits(layer, commits):
"""Prints the given commits in a user=pleasing format."""
commits = [c for c in commits if filter_commit(c)]
print('')
print(' --------------')
print(' | %s |' % '{:^10}'.format(layer))
print(' --------------')
for commit in commits:
print('%s | %s | %s' % (commit['commit'][:7],
commit['author']['name'][:15].ljust(15),
commit['message'].splitlines()[0]))
if not commits:
print('None')
def main():
parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter,
description="""Displays the commits not yet rolled to a given layer.
For vendor layers, specify the Topaz revision with --topaz-revision.""")
parser.add_argument('--layer',
help='Name of the layer to inspect',
choices=LAYERS,
default='topaz')
parser.add_argument('--topaz-revision',
help='(vendor only) revision of the Topaz layer')
args = parser.parse_args()
layer = args.layer
revision = args.topaz_revision
if layer != 'vendor' and revision:
print('Warning: Topaz revision only used with vendor layers.')
if layer == 'vendor' and not revision:
print('Error: vendor layers require a Topaz revision.')
return 1
if layer == 'vendor':
commits = get_commits('topaz', revision)
print_commits('topaz', commits)
layer = 'topaz'
else:
revision = 'master'
while True:
(lower_layer, lower_revision) = get_lower_layer_commit(layer, revision)
if not lower_layer:
break
commits = get_commits(lower_layer, lower_revision)
print_commits(lower_layer, commits)
layer = lower_layer
revision = lower_revision
return 0
if __name__ == "__main__":
sys.exit(main())