OLD | NEW |
1 # Copyright 2013 The LUCI Authors. All rights reserved. | 1 # Copyright 2013 The LUCI Authors. All rights reserved. |
2 # Use of this source code is governed under the Apache License, Version 2.0 | 2 # Use of this source code is governed under the Apache License, Version 2.0 |
3 # that can be found in the LICENSE file. | 3 # that can be found in the LICENSE file. |
4 | 4 |
| 5 import collections |
5 import contextlib | 6 import contextlib |
6 import datetime | 7 import datetime |
7 import functools | 8 import functools |
8 import logging | 9 import logging |
9 import os | 10 import os |
| 11 import platform |
10 import sys | 12 import sys |
11 import traceback | 13 import traceback |
12 import time | 14 import time |
13 import urllib | 15 import urllib |
14 | 16 |
15 from cStringIO import StringIO | 17 from cStringIO import StringIO |
16 | 18 |
17 class RecipeAbort(Exception): | 19 class RecipeAbort(Exception): |
18 pass | 20 pass |
19 | 21 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 Args: | 86 Args: |
85 presentation (StepPresentation) - for the current step. | 87 presentation (StepPresentation) - for the current step. |
86 test (PlaceholderTestData) - test data for this placeholder. | 88 test (PlaceholderTestData) - test data for this placeholder. |
87 | 89 |
88 May optionally modify presentation as a side-effect. | 90 May optionally modify presentation as a side-effect. |
89 Returned value will be added to the step result. | 91 Returned value will be added to the step result. |
90 """ | 92 """ |
91 pass | 93 pass |
92 | 94 |
93 | 95 |
| 96 class Platform(collections.namedtuple('Platform', ('name', 'arch', 'bits'))): |
| 97 """Normalized operating system platform information.""" |
| 98 |
| 99 @staticmethod |
| 100 def norm_plat(plat): |
| 101 if plat.startswith('linux'): |
| 102 return 'linux' |
| 103 elif plat.startswith(('win', 'cygwin')): |
| 104 return 'win' |
| 105 elif plat.startswith(('darwin', 'mac')): |
| 106 return 'mac' |
| 107 else: # pragma: no cover |
| 108 raise ValueError('Don\'t understand platform "%s"' % plat) |
| 109 |
| 110 @staticmethod |
| 111 def norm_bits(arch): |
| 112 return 64 if '64' in str(arch) else 32 |
| 113 |
| 114 @classmethod |
| 115 def probe(cls): |
| 116 name = cls.norm_plat(sys.platform) |
| 117 bits = cls.norm_bits(platform.machine()) |
| 118 |
| 119 # platform.machine is based on running kernel. It's possible to use 64-bit |
| 120 # kernel with 32-bit userland, e.g. to give linker slightly more memory. |
| 121 # Distinguish between different userland bitness by querying the python |
| 122 # binary. |
| 123 architecture = platform.architecture()[0] |
| 124 if (name == 'linux' and |
| 125 bits == 64 and |
| 126 architecture == '32bit'): |
| 127 bits = 32 |
| 128 # On Mac, the inverse of the above is true: the kernel is 32-bit but the |
| 129 # CPU and userspace both are capable of running 64-bit programs. |
| 130 elif (name == 'mac' and |
| 131 bits == 32 and |
| 132 architecture == '64bit'): |
| 133 bits = 64 |
| 134 |
| 135 return cls(name=name, arch='intel', bits=bits) |
| 136 |
| 137 def is_win(self): |
| 138 return self.name == 'win' |
| 139 |
| 140 def is_mac(self): |
| 141 return self.name == 'mac' |
| 142 |
| 143 def is_linux(self): |
| 144 return self.name == 'linux' |
| 145 |
| 146 def is_posix(self): |
| 147 return self.name in ('mac', 'linux') |
| 148 |
| 149 |
94 def static_wraps(func): | 150 def static_wraps(func): |
95 wrapped_fn = func | 151 wrapped_fn = func |
96 if isinstance(func, staticmethod): | 152 if isinstance(func, staticmethod): |
97 # __get__(obj) is the way to get the function contained in the staticmethod. | 153 # __get__(obj) is the way to get the function contained in the staticmethod. |
98 # python 2.7+ has a __func__ member, but previous to this the attribute | 154 # python 2.7+ has a __func__ member, but previous to this the attribute |
99 # doesn't exist. It doesn't matter what the obj is, as long as it's not | 155 # doesn't exist. It doesn't matter what the obj is, as long as it's not |
100 # None. | 156 # None. |
101 wrapped_fn = func.__get__(object) | 157 wrapped_fn = func.__get__(object) |
102 return functools.wraps(wrapped_fn) | 158 return functools.wraps(wrapped_fn) |
103 | 159 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 it (iterable): An iterable to traverse. | 366 it (iterable): An iterable to traverse. |
311 exc_types (list): An optional list of specific exception types to defer. | 367 exc_types (list): An optional list of specific exception types to defer. |
312 If empty, Exception will be used. Any Exceptions not referenced by this | 368 If empty, Exception will be used. Any Exceptions not referenced by this |
313 list will skip deferring and be immediately raised. | 369 list will skip deferring and be immediately raised. |
314 """ | 370 """ |
315 mexc_builder = MultiException.Builder() | 371 mexc_builder = MultiException.Builder() |
316 for e in it: | 372 for e in it: |
317 with mexc_builder.catch(*exc_types): | 373 with mexc_builder.catch(*exc_types): |
318 fn(e) | 374 fn(e) |
319 mexc_builder.raise_if_any() | 375 mexc_builder.raise_if_any() |
OLD | NEW |