Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 1 | # Copyright (C) 2010 Google Inc. All rights reserved. |
| 2 | # |
| 3 | # Redistribution and use in source and binary forms, with or without |
| 4 | # modification, are permitted provided that the following conditions are |
| 5 | # met: |
| 6 | # |
| 7 | # * Redistributions of source code must retain the above copyright |
| 8 | # notice, this list of conditions and the following disclaimer. |
| 9 | # * Redistributions in binary form must reproduce the above |
| 10 | # copyright notice, this list of conditions and the following disclaimer |
| 11 | # in the documentation and/or other materials provided with the |
| 12 | # distribution. |
| 13 | # * Neither the name of Google Inc. nor the names of its |
| 14 | # contributors may be used to endorse or promote products derived from |
| 15 | # this software without specific prior written permission. |
| 16 | # |
| 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 21 | # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 22 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 23 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | |
| 29 | """Factory method to retrieve the appropriate port implementation.""" |
| 30 | |
| 31 | import fnmatch |
| 32 | import optparse |
| 33 | import re |
| 34 | |
| 35 | from webkitpy.layout_tests.port import builders |
| 36 | |
| 37 | |
| 38 | def platform_options(use_globs=False): |
| 39 | return [ |
| 40 | optparse.make_option('--platform', action='store', |
| 41 | help=('Glob-style list of platform/ports to use (e.g., "mac*")' if use_globs else 'Platform to use (e.g., "mac-lion")')), |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 42 | |
| 43 | # FIXME: Update run_webkit_tests.sh, any other callers to no longer pass --chromium, then remove this flag. |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 44 | optparse.make_option('--chromium', action='store_const', dest='platform', |
| 45 | const=('chromium*' if use_globs else 'chromium'), |
| 46 | help=('Alias for --platform=chromium*' if use_globs else 'Alias for --platform=chromium')), |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 47 | |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 48 | optparse.make_option('--android', action='store_const', dest='platform', |
| 49 | const=('android*' if use_globs else 'android'), |
| 50 | help=('Alias for --platform=android*' if use_globs else 'Alias for --platform=android')), |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 51 | ] |
| 52 | |
| 53 | |
| 54 | def configuration_options(): |
| 55 | return [ |
Torne (Richard Coles) | 5267f70 | 2013-06-11 10:57:24 +0100 | [diff] [blame] | 56 | optparse.make_option("-t", "--target", dest="configuration", |
| 57 | help="specify the target configuration to use (Debug/Release)"), |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 58 | optparse.make_option('--debug', action='store_const', const='Debug', dest="configuration", |
| 59 | help='Set the configuration to Debug'), |
| 60 | optparse.make_option('--release', action='store_const', const='Release', dest="configuration", |
| 61 | help='Set the configuration to Release'), |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 62 | ] |
| 63 | |
| 64 | |
| 65 | |
| 66 | def _builder_options(builder_name): |
| 67 | configuration = "Debug" if re.search(r"[d|D](ebu|b)g", builder_name) else "Release" |
| 68 | is_webkit2 = builder_name.find("WK2") != -1 |
| 69 | builder_name = builder_name |
Torne (Richard Coles) | 53e740f | 2013-05-09 18:38:43 +0100 | [diff] [blame] | 70 | return optparse.Values({'builder_name': builder_name, 'configuration': configuration}) |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 71 | |
| 72 | |
| 73 | class PortFactory(object): |
| 74 | PORT_CLASSES = ( |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 75 | 'android.AndroidPort', |
Ben Murdoch | 591b958 | 2013-07-10 11:41:44 +0100 | [diff] [blame] | 76 | 'linux.LinuxPort', |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 77 | 'mac.MacPort', |
Ben Murdoch | 591b958 | 2013-07-10 11:41:44 +0100 | [diff] [blame] | 78 | 'win.WinPort', |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 79 | 'mock_drt.MockDRTPort', |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 80 | 'test.TestPort', |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 81 | ) |
| 82 | |
| 83 | def __init__(self, host): |
| 84 | self._host = host |
| 85 | |
| 86 | def _default_port(self, options): |
| 87 | platform = self._host.platform |
| 88 | if platform.is_linux() or platform.is_freebsd(): |
Ben Murdoch | 591b958 | 2013-07-10 11:41:44 +0100 | [diff] [blame] | 89 | return 'linux' |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 90 | elif platform.is_mac(): |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 91 | return 'mac' |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 92 | elif platform.is_win(): |
Ben Murdoch | 591b958 | 2013-07-10 11:41:44 +0100 | [diff] [blame] | 93 | return 'win' |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 94 | raise NotImplementedError('unknown platform: %s' % platform) |
| 95 | |
| 96 | def get(self, port_name=None, options=None, **kwargs): |
| 97 | """Returns an object implementing the Port interface. If |
| 98 | port_name is None, this routine attempts to guess at the most |
| 99 | appropriate port on this platform.""" |
| 100 | port_name = port_name or self._default_port(options) |
| 101 | |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 102 | # FIXME(steveblock): There's no longer any need to pass '--platform |
| 103 | # chromium' on the command line so we can remove this logic. |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 104 | if port_name == 'chromium': |
Ben Murdoch | e69819b | 2013-07-17 14:56:49 +0100 | [diff] [blame] | 105 | port_name = self._host.platform.os_name |
Torne (Richard Coles) | 5c87bf8 | 2012-11-14 11:46:17 +0000 | [diff] [blame] | 106 | |
| 107 | for port_class in self.PORT_CLASSES: |
| 108 | module_name, class_name = port_class.rsplit('.', 1) |
| 109 | module = __import__(module_name, globals(), locals(), [], -1) |
| 110 | cls = module.__dict__[class_name] |
| 111 | if port_name.startswith(cls.port_name): |
| 112 | port_name = cls.determine_full_port_name(self._host, options, port_name) |
| 113 | return cls(self._host, port_name, options=options, **kwargs) |
| 114 | raise NotImplementedError('unsupported platform: "%s"' % port_name) |
| 115 | |
| 116 | def all_port_names(self, platform=None): |
| 117 | """Return a list of all valid, fully-specified, "real" port names. |
| 118 | |
| 119 | This is the list of directories that are used as actual baseline_paths() |
| 120 | by real ports. This does not include any "fake" names like "test" |
| 121 | or "mock-mac", and it does not include any directories that are not. |
| 122 | |
| 123 | If platform is not specified, we will glob-match all ports""" |
| 124 | platform = platform or '*' |
| 125 | return fnmatch.filter(builders.all_port_names(), platform) |
| 126 | |
| 127 | def get_from_builder_name(self, builder_name): |
| 128 | port_name = builders.port_name_for_builder_name(builder_name) |
| 129 | assert port_name, "unrecognized builder name '%s'" % builder_name |
| 130 | return self.get(port_name, _builder_options(builder_name)) |