| #!/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()) |