OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """ | 7 """ |
8 Provides read access to buildbot's global_variables.json . | 8 Provides read access to buildbot's global_variables.json . |
9 """ | 9 """ |
10 | 10 |
11 | 11 |
12 from contextlib import closing | 12 from contextlib import closing |
13 | 13 |
14 import HTMLParser | 14 import HTMLParser |
15 import json | 15 import json |
16 import re | 16 import re |
17 import svn | 17 import svn |
18 import sys | 18 import sys |
19 import urllib2 | 19 import urllib2 |
20 | 20 |
21 | 21 |
22 _global_vars = None | 22 _global_vars = None |
23 | 23 |
24 | 24 |
25 GLOBAL_VARS_JSON_URL = ('https://skia.googlesource.com/buildbot/+' | 25 GLOBAL_VARS_JSON_URL = ('http://skia-tree-status.appspot.com/repo-serving/' |
26 '/master/site_config/global_variables.json') | 26 'buildbot/site_config/global_variables.json') |
27 | 27 |
28 | 28 |
29 class GlobalVarsRetrievalError(Exception): | 29 class GlobalVarsRetrievalError(Exception): |
30 """Exception which is raised when the global_variables.json file cannot be | 30 """Exception which is raised when the global_variables.json file cannot be |
31 retrieved from the Skia buildbot repository.""" | 31 retrieved from the Skia buildbot repository.""" |
32 pass | 32 pass |
33 | 33 |
34 | 34 |
35 class JsonDecodeError(Exception): | 35 class JsonDecodeError(Exception): |
36 """Exception which is raised when the global_variables.json file cannot be | 36 """Exception which is raised when the global_variables.json file cannot be |
37 interpreted as JSON. This may be due to the file itself being incorrectly | 37 interpreted as JSON. This may be due to the file itself being incorrectly |
38 formatted or due to an incomplete or corrupted downloaded version of the file. | 38 formatted or due to an incomplete or corrupted downloaded version of the file. |
39 """ | 39 """ |
40 pass | 40 pass |
41 | 41 |
42 | 42 |
43 class NoSuchGlobalVariable(KeyError): | 43 class NoSuchGlobalVariable(KeyError): |
44 """Exception which is raised when a given variable is not found in the | 44 """Exception which is raised when a given variable is not found in the |
45 global_variables.json file.""" | 45 global_variables.json file.""" |
46 pass | 46 pass |
47 | 47 |
48 | 48 |
49 def retrieve_from_googlesource(url): | 49 def retrieve_from_mirror(url): |
50 """Retrieve the given file from GoogleSource's HTTP interface, trimming the | 50 """Retrieve the given file from the Skia Buildbot repo mirror. |
51 extraneous HTML. Intended to be a GoogleSource equivalent of "svn cat". | |
52 | |
53 This just returns the unescaped contents of the first <pre> tag which matches | |
54 our expectations for GoogleSource's HTTP interface. If that interface changes, | |
55 this function will almost surely break. | |
56 | 51 |
57 Args: | 52 Args: |
58 url: string; the URL of the file to retrieve. | 53 url: string; the URL of the file to retrieve. |
59 Returns: | 54 Returns: |
60 The contents of the file in GoogleSource, stripped of the extra HTML from | 55 The contents of the file in the repository. |
61 the HTML interface. | |
62 """ | 56 """ |
63 with closing(urllib2.urlopen(url)) as f: | 57 with closing(urllib2.urlopen(url)) as f: |
64 contents = f.read() | 58 return f.read() |
65 pre_open = '<pre class="git-blob prettyprint linenums lang-(\w+)">' | |
66 pre_close = '</pre>' | |
67 matched_tag = re.search(pre_open, contents).group() | |
68 start_index = contents.find(matched_tag) | |
69 end_index = contents.find(pre_close) | |
70 parser = HTMLParser.HTMLParser() | |
71 return parser.unescape(contents[start_index + len(matched_tag):end_index]) | |
72 | 59 |
73 | 60 |
74 def Get(var_name): | 61 def Get(var_name): |
75 """Return the value associated with this name in global_variables.json. | 62 """Return the value associated with this name in global_variables.json. |
76 | 63 |
77 Args: | 64 Args: |
78 var_name: string; the variable to look up. | 65 var_name: string; the variable to look up. |
79 Returns: | 66 Returns: |
80 The value of the variable. | 67 The value of the variable. |
81 Raises: | 68 Raises: |
82 NoSuchGlobalVariable if there is no variable with that name. | 69 NoSuchGlobalVariable if there is no variable with that name. |
83 """ | 70 """ |
84 global _global_vars | 71 global _global_vars |
85 if not _global_vars: | 72 if not _global_vars: |
86 try: | 73 try: |
87 global_vars_text = retrieve_from_googlesource(GLOBAL_VARS_JSON_URL) | 74 global_vars_text = retrieve_from_mirror(GLOBAL_VARS_JSON_URL) |
88 except Exception: | 75 except Exception as e: |
89 raise GlobalVarsRetrievalError('Failed to retrieve %s.' % | 76 raise GlobalVarsRetrievalError('Failed to retrieve %s:\n%s' % |
90 GLOBAL_VARS_JSON_URL) | 77 (GLOBAL_VARS_JSON_URL, str(e))) |
91 try: | 78 try: |
92 _global_vars = json.loads(global_vars_text) | 79 _global_vars = json.loads(global_vars_text) |
93 except ValueError as e: | 80 except ValueError as e: |
94 raise JsonDecodeError(e.message + '\n' + global_vars_text) | 81 raise JsonDecodeError(e.message + '\n' + global_vars_text) |
95 try: | 82 try: |
96 return _global_vars[var_name]['value'] | 83 return _global_vars[var_name]['value'] |
97 except KeyError: | 84 except KeyError: |
98 raise NoSuchGlobalVariable(var_name) | 85 raise NoSuchGlobalVariable(var_name) |
99 | 86 |
100 | 87 |
101 if __name__ == '__main__': | 88 if __name__ == '__main__': |
102 print Get(sys.argv[1]) | 89 print Get(sys.argv[1]) |
OLD | NEW |