blob: a2153eb0cd0d3532ca7140e6de822838d97f46f8 [file] [log] [blame]
# Copyright (c) 2013 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.
"""Handler for chrome/app/policy/policy_templates.json
This handler examines changes to the policy_templates.json file and posts
comments with checklists for the patch author and reviewer to go through to
avoid common pitfalls.
"""
import os
import jinja2
import model.app_config
import util
import handlers.policy_checklist.parser
POLICY_TEMPLATES_FILE = 'chrome/app/policy/policy_templates.json'
MAX_INLINE_COMMENTS = 10
REVIEW_MESSAGE_TEMPLATE = 'review_message.txt'
ADDITION_COMMENT_TEMPLATE = 'addition_comment.txt'
MODIFICATION_COMMENT_TEMPLATE = 'modification_comment.txt'
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
def prepare_address_list(addr, email_list):
"""Prepares |email_list| for use as rietveld query parameter.
Canonicalizes the entries in |email_list|, removes any occurrences of |addr|,
joins the entries with commas and returns the result.
"""
return ','.join([util.canonicalize_email(entry)
for entry in email_list if entry != addr])
def process(addr, message, review, rietveld):
"""Handles reviews for chrome/app/policy/policy_templates.json.
This looks at the patch to identify additions/modifications to policy
definitions and posts comments with a checklist intended for the author and
reviewer to go through in order to catch common mistakes.
"""
if POLICY_TEMPLATES_FILE not in review.latest_patchset.files:
return
# Only process the change if the mail is directly to us or we haven't
# processed this review yet.
client_id = model.app_config.get().client_id
if (not addr in util.get_emails(getattr(message, 'to', '')) and
client_id in [m.sender for m in review.issue_data.messages]):
return
# Don't process reverts.
if 'revert' in review.issue_data.description.lower():
return
# Parse the patch, look at the chunks and generate inline comments.
chunks = handlers.policy_checklist.parser.parse(
review.latest_patchset.files[POLICY_TEMPLATES_FILE].patch.lines)
for chunk in chunks[0:MAX_INLINE_COMMENTS]:
if chunk.additions and not chunk.removals:
template = JINJA_ENVIRONMENT.get_template(ADDITION_COMMENT_TEMPLATE)
else:
template = JINJA_ENVIRONMENT.get_template(MODIFICATION_COMMENT_TEMPLATE)
if chunk.comment_pos[1] is not None:
line, side = chunk.comment_pos[1], 'b'
elif chunk.comment_pos[0] is not None:
line, side = chunk.comment_pos[0], 'a'
else:
# No suitable position?
continue
rietveld.add_inline_comment(
review.issue_id, review.latest_patchset.patchset,
review.latest_patchset.files[POLICY_TEMPLATES_FILE].id,
line, side, template.render(review=review, chunk=chunk))
# Finally, post all inline comments.
if len(chunks) > 0:
template = JINJA_ENVIRONMENT.get_template(REVIEW_MESSAGE_TEMPLATE)
rietveld.publish_inline_comments(
review.issue_id, template.render(review=review),
prepare_address_list(addr, review.issue_data.reviewers),
prepare_address_list(addr, review.issue_data.cc))