OLD | NEW |
---|---|
1 # Copyright (c) 2014 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import cgi | 5 import cgi |
6 import ConfigParser | 6 import ConfigParser |
7 import json | 7 import json |
8 import logging | 8 import logging |
9 import os | 9 import os |
10 import time | 10 import time |
11 import urllib2 | 11 import urllib2 |
12 | 12 |
13 from result import Result | 13 from result import Result |
14 | 14 |
15 | 15 |
16 INFINITY = float('inf') | 16 INFINITY = float('inf') |
17 | 17 |
18 | 18 |
19 def ParseURLsFromConfig(file_name): | 19 def ParseURLsFromConfig(file_name): |
20 """Parses URLS from the config file. | 20 """Parses URLS from the config file. |
21 | 21 |
22 The file should be in python config format, where svn section is in the | 22 The file should be in python config format, where svn section is in the |
23 format "svn:component_path", except for git URLs and codereview URL. | 23 format "svn:component_path". |
24 Each of the section for svn should contain changelog_url, revision_url, | 24 Each of the section for svn should contain changelog_url, revision_url, |
25 diff_url and blame_url. | 25 diff_url and blame_url. |
26 | 26 |
27 Args: | 27 Args: |
28 file_name: The name of the file that contains URL information. | 28 file_name: The name of the file that contains URL information. |
29 | 29 |
30 Returns: | 30 Returns: |
31 A dictionary that maps repository type to list of URLs. For svn, it maps | 31 A dictionary that maps repository type to list of URLs. For svn, it maps |
32 key 'svn' to another dictionary, which maps component path to the URLs | 32 key 'svn' to another dictionary, which maps component path to the URLs |
33 as explained above. For git, it maps to the URLs as explained above. | 33 as explained above. For git, it maps to the URLs as explained above. |
34 Codereview maps to codereview API url. | |
35 """ | 34 """ |
36 config = ConfigParser.ConfigParser() | 35 config = ConfigParser.ConfigParser() |
37 | 36 |
38 # Get the absolute path of the config file, and read the file. If it fails, | 37 # Get the absolute path of the config file, and read the file. If it fails, |
39 # return none. | 38 # return none. |
40 config_file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), | 39 config_file_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), |
41 file_name) | 40 file_name) |
42 config.read(config_file_path) | 41 config.read(config_file_path) |
43 if not config: | 42 if not config: |
44 logging.error('Config file with URLs does not exist.') | 43 logging.error('Config file with URLs does not exist.') |
45 return None | 44 return None |
46 | 45 |
47 # Iterate through the config file, check for sections. | 46 # Iterate through the config file, check for sections. |
48 repository_type_to_url_map = {} | 47 parsed_config = {} |
49 for section in config.sections(): | 48 for section in config.sections(): |
50 # These two do not need another layer of dictionary, so add it and go | 49 # These two do not need another layer of dictionary, so add it and go |
51 # to next section. | 50 # to next section. |
52 if section == 'git' or section == 'codereview': | 51 if ':' not in section: |
53 for option in config.options(section): | 52 for option in config.options(section): |
54 if section not in repository_type_to_url_map: | 53 if section not in parsed_config: |
55 repository_type_to_url_map[section] = {} | 54 parsed_config[section] = {} |
56 | 55 |
57 url = config.get(section, option) | 56 url = config.get(section, option) |
58 repository_type_to_url_map[section][option] = url | 57 parsed_config[section][option] = url |
59 | 58 |
60 continue | 59 continue |
61 | 60 |
62 # Get repository type and component name from the section name. | 61 # Get repository type and component name from the section name. |
63 repository_type_and_component = section.split(':') | 62 repository_type_and_component = section.split(':') |
64 repository_type = repository_type_and_component[0] | 63 repository_type = repository_type_and_component[0] |
65 component_path = repository_type_and_component[1] | 64 component_path = repository_type_and_component[1] |
66 | 65 |
67 # Add 'svn' as the key, if it is not already there. | 66 # Add 'svn' as the key, if it is not already there. |
68 if repository_type not in repository_type_to_url_map: | 67 if repository_type not in parsed_config: |
69 repository_type_to_url_map[repository_type] = {} | 68 parsed_config[repository_type] = {} |
70 url_map_for_repository = repository_type_to_url_map[repository_type] | 69 url_map_for_repository = parsed_config[repository_type] |
71 | 70 |
72 # Add the path to the 'svn', if it is not already there. | 71 # Add the path to the 'svn', if it is not already there. |
73 if component_path not in url_map_for_repository: | 72 if component_path not in url_map_for_repository: |
74 url_map_for_repository[component_path] = {} | 73 url_map_for_repository[component_path] = {} |
75 type_to_url = url_map_for_repository[component_path] | 74 type_to_url = url_map_for_repository[component_path] |
76 | 75 |
77 # Add all URLs to this map. | 76 # Add all URLs to this map. |
78 for option in config.options(section): | 77 for option in config.options(section): |
79 url = config.get(section, option) | 78 url = config.get(section, option) |
80 type_to_url[option] = url | 79 type_to_url[option] = url |
81 | 80 |
82 return repository_type_to_url_map | 81 return parsed_config |
83 | 82 |
84 | 83 |
85 def NormalizePathLinux(path, parsed_deps): | 84 def NormalizePathLinux(path, parsed_deps): |
86 """Normalizes linux path. | 85 """Normalizes linux path. |
87 | 86 |
88 Args: | 87 Args: |
89 path: A string representing a path. | 88 path: A string representing a path. |
90 parsed_deps: A map from component path to its component name, repository, | 89 parsed_deps: A map from component path to its component name, repository, |
91 etc. | 90 etc. |
92 | 91 |
(...skipping 23 matching lines...) Expand all Loading... | |
116 | 115 |
117 # Normalize the path by stripping everything off the component's relative | 116 # Normalize the path by stripping everything off the component's relative |
118 # path. | 117 # path. |
119 normalized_path = normalized_path.split(new_path,1)[1] | 118 normalized_path = normalized_path.split(new_path,1)[1] |
120 | 119 |
121 # Add 'src/' or 'Source/' at the front of the normalized path, depending | 120 # Add 'src/' or 'Source/' at the front of the normalized path, depending |
122 # on what prefix the component path uses. For example, blink uses | 121 # on what prefix the component path uses. For example, blink uses |
123 # 'Source' but chromium uses 'src/', and blink component path is | 122 # 'Source' but chromium uses 'src/', and blink component path is |
124 # 'src/third_party/WebKit/Source', so add 'Source/' in front of the | 123 # 'src/third_party/WebKit/Source', so add 'Source/' in front of the |
125 # normalized path. | 124 # normalized path. |
126 if not normalized_path.startswith('src/') or \ | 125 if not (normalized_path.startswith('src/') or \ |
stgao
2014/08/15 19:42:38
Ending \ could be removed.
| |
127 normalized_path.startswith('Source/'): | 126 normalized_path.startswith('Source/')): |
128 | 127 |
129 if (new_path.lower().endswith('src/') or | 128 if (new_path.lower().endswith('src/') or |
130 new_path.lower().endswith('source/')): | 129 new_path.lower().endswith('source/')): |
131 normalized_path = new_path.split('/')[-2] + '/' + normalized_path | 130 normalized_path = new_path.split('/')[-2] + '/' + normalized_path |
132 | 131 |
133 else: | 132 else: |
134 normalized_path = 'src/' + normalized_path | 133 normalized_path = 'src/' + normalized_path |
135 | 134 |
136 component_name = parsed_deps[component_path]['name'] | 135 component_name = parsed_deps[component_path]['name'] |
137 | 136 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 JSON object if the string represents a JSON object, None otherwise. | 176 JSON object if the string represents a JSON object, None otherwise. |
178 """ | 177 """ |
179 try: | 178 try: |
180 data = json.loads(json_string) | 179 data = json.loads(json_string) |
181 except ValueError: | 180 except ValueError: |
182 data = None | 181 data = None |
183 | 182 |
184 return data | 183 return data |
185 | 184 |
186 | 185 |
187 def GetDataFromURL(url, retries=10, sleep_time=0.1, timeout=10): | 186 def GetDataFromURL(url, retries=10, sleep_time=0.1, timeout=5): |
188 """Retrieves raw data from URL, tries 10 times. | 187 """Retrieves raw data from URL, tries 10 times. |
189 | 188 |
190 Args: | 189 Args: |
191 url: URL to get data from. | 190 url: URL to get data from. |
192 retries: Number of times to retry connection. | 191 retries: Number of times to retry connection. |
193 sleep_time: Time in seconds to wait before retrying connection. | 192 sleep_time: Time in seconds to wait before retrying connection. |
194 timeout: Time in seconds to wait before time out. | 193 timeout: Time in seconds to wait before time out. |
195 | 194 |
196 Returns: | 195 Returns: |
197 None if the data retrieval fails, or the raw data. | 196 None if the data retrieval fails, or the raw data. |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
433 suspected_cl = blame.revision | 432 suspected_cl = blame.revision |
434 revision_url = blame.url | 433 revision_url = blame.url |
435 component_name = blame.component_name | 434 component_name = blame.component_name |
436 author = blame.author | 435 author = blame.author |
437 reason = ( | 436 reason = ( |
438 'The CL changes line %s of file %s from stack %d.' % | 437 'The CL changes line %s of file %s from stack %d.' % |
439 (blame.line_number, blame.file, blame.stack_frame_index)) | 438 (blame.line_number, blame.file, blame.stack_frame_index)) |
440 # Blame object does not have review url and reviewers. | 439 # Blame object does not have review url and reviewers. |
441 review_url = None | 440 review_url = None |
442 reviewers = None | 441 reviewers = None |
443 line_content = blame.content | 442 line_content = blame.line_content |
444 | 443 |
445 result = Result(suspected_cl, revision_url, component_name, author, reason, | 444 result = Result(suspected_cl, revision_url, component_name, author, reason, |
446 review_url, reviewers, line_content) | 445 review_url, reviewers, line_content) |
447 result_list.append(result) | 446 result_list.append(result) |
448 | 447 |
449 return result_list | 448 return result_list |
450 | |
451 | |
452 def ResultListToJSON(result_list): | |
453 """Converts result list to JSON format. | |
454 | |
455 Args: | |
456 result_list: A list of result objects | |
457 | |
458 Returns: | |
459 A string, JSON format of the result_list. | |
460 | |
461 """ | |
462 return json.dumps([result.ToDictionary() for result in result_list]) | |
OLD | NEW |