Revert "Always activate MojoApplicationHost"
[chromium-blink-merge.git] / tools / findit / match_set.py
blobcdb2c8c8e113d31440138e77eb73f49f44731b21
1 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import re
7 from threading import Lock
9 import crash_utils
12 REVIEW_URL_PATTERN = re.compile(r'Review URL:( *)(.*?)/(\d+)')
15 class Match(object):
16 """Represents a match entry.
18 A match is a CL that is suspected to have caused the crash. A match object
19 contains information about files it changes, their authors, etc.
21 Attributes:
22 is_revert: True if this CL is reverted by other CL.
23 revert_of: If this CL is a revert of some other CL, a revision number/
24 git hash of that CL.
25 crashed_line_numbers: The list of lines that caused crash for this CL.
26 function_list: The list of functions that caused the crash.
27 min_distance: The minimum distance between the lines that CL changed and
28 lines that caused the crash.
29 changed_files: The list of files that the CL changed.
30 changed_file_urls: The list of URLs for the file.
31 author: The author of the CL.
32 component_name: The name of the component that this CL belongs to.
33 stack_frame_indices: For files that caused crash, list of where in the
34 stackframe they occur.
35 priorities: A list of priorities for each of the changed file. A priority
36 is 1 if the file changes a crashed line, and 2 if it changes
37 the file but not the crashed line.
38 reivision_url: The revision URL of the CL.
39 review_url: The codereview URL that reviews this CL.
40 reviewers: The list of people that reviewed this CL.
41 reason: The reason why this CL is suspected.
42 """
43 REVERT_PATTERN = re.compile(r'(revert\w*) r?(\d+)', re.I)
45 def __init__(self, revision, component_name):
46 self.is_revert = False
47 self.revert_of = None
48 self.message = None
49 self.crashed_line_numbers = []
50 self.function_list = []
51 self.min_distance = crash_utils.INFINITY
52 self.min_distance_info = None
53 self.changed_files = []
54 self.changed_file_urls = []
55 self.author = revision['author']
56 self.component_name = component_name
57 self.stack_frame_indices = []
58 self.priorities = []
59 self.revision_url = revision['url']
60 self.review_url = ''
61 self.reviewers = []
62 self.reason = None
64 def ParseMessage(self, message, codereview_api_url):
65 """Parses the message.
67 It checks the message to extract the code review website and list of
68 reviewers, and it also checks if the CL is a revert of another CL.
70 Args:
71 message: The message to parse.
72 codereview_api_url: URL to retrieve codereview data from.
73 """
74 self.message = message
75 for line in message.splitlines():
76 line = line.strip()
77 review_url_line_match = REVIEW_URL_PATTERN.match(line)
79 # Check if the line has the code review information.
80 if review_url_line_match:
82 # Get review number for the code review site from the line.
83 issue_number = review_url_line_match.group(3)
85 # Get JSON from the code review site, ignore the line if it fails.
86 url = codereview_api_url % issue_number
87 json_string = crash_utils.GetDataFromURL(url)
88 if not json_string:
89 continue
91 # Load the JSON from the string, and get the list of reviewers.
92 code_review = crash_utils.LoadJSON(json_string)
93 if code_review:
94 self.reviewers = code_review['reviewers']
96 # Check if this CL is a revert of other CL.
97 if line.lower().startswith('revert'):
98 self.is_revert = True
100 # Check if the line says what CL this CL is a revert of.
101 revert = self.REVERT_PATTERN.match(line)
102 if revert:
103 self.revert_of = revert.group(2)
104 return
107 class MatchSet(object):
108 """Represents a set of matches.
110 Attributes:
111 matches: A map from CL to a match object.
112 cls_to_ignore: A set of CLs to ignore.
113 matches_lock: A lock guarding matches dictionary.
116 def __init__(self, codereview_api_url):
117 self.codereview_api_url = codereview_api_url
118 self.matches = {}
119 self.cls_to_ignore = set()
120 self.matches_lock = Lock()
122 def RemoveRevertedCLs(self):
123 """Removes CLs that are revert."""
124 for cl in self.matches:
125 if cl in self.cls_to_ignore:
126 del self.matches[cl]