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('--android', action='store_const', dest='platform', 41 const=('android*' if use_globs else 'android'), 42 help=('Alias for --platform=android*' if use_globs else 'Alias for --platform=android')), 43 44 # FIXME: Update run_webkit_tests.sh, any other callers to no longer pass --chromium, then remove this flag. 45 optparse.make_option('--chromium', action='store_const', dest='platform', 46 const=('chromium*' if use_globs else 'chromium'), 47 help=('Alias for --platform=chromium*' if use_globs else 'Alias for --platform=chromium')), 48 49 optparse.make_option('--platform', action='store', 50 help=('Glob-style list of platform/ports to use (e.g., "mac*")' if use_globs else 'Platform to use (e.g., "mac-lion")')), 51 ] 52 53 54 def configuration_options(): 55 return [ 56 optparse.make_option('--debug', action='store_const', const='Debug', dest="configuration", 57 help='Set the configuration to Debug'), 58 optparse.make_option("-t", "--target", dest="configuration", 59 help="specify the target configuration to use (Debug/Release)"), 60 optparse.make_option('--release', action='store_const', const='Release', dest="configuration", 61 help='Set the configuration to Release'), 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 70 return optparse.Values({'builder_name': builder_name, 'configuration': configuration}) 71 72 73 class PortFactory(object): 74 PORT_CLASSES = ( 75 'android.AndroidPort', 76 'linux.LinuxPort', 77 'mac.MacPort', 78 'win.WinPort', 79 'mock_drt.MockDRTPort', 80 'test.TestPort', 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(): 89 return 'linux' 90 elif platform.is_mac(): 91 return 'mac' 92 elif platform.is_win(): 93 return 'win' 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 102 # FIXME(steveblock): There's no longer any need to pass '--platform 103 # chromium' on the command line so we can remove this logic. 104 if port_name == 'chromium': 105 port_name = self._host.platform.os_name 106 107 if 'browser_test' in port_name: 108 module_name, class_name = port_name.rsplit('.', 1) 109 module = __import__(module_name, globals(), locals(), [], -1) 110 port_class_name = module.get_port_class_name(class_name) 111 if port_class_name != None: 112 cls = module.__dict__[port_class_name] 113 port_name = cls.determine_full_port_name(self._host, options, class_name) 114 return cls(self._host, port_name, options=options, **kwargs) 115 else: 116 for port_class in self.PORT_CLASSES: 117 module_name, class_name = port_class.rsplit('.', 1) 118 module = __import__(module_name, globals(), locals(), [], -1) 119 cls = module.__dict__[class_name] 120 if port_name.startswith(cls.port_name): 121 port_name = cls.determine_full_port_name(self._host, options, port_name) 122 return cls(self._host, port_name, options=options, **kwargs) 123 raise NotImplementedError('unsupported platform: "%s"' % port_name) 124 125 def all_port_names(self, platform=None): 126 """Return a list of all valid, fully-specified, "real" port names. 127 128 This is the list of directories that are used as actual baseline_paths() 129 by real ports. This does not include any "fake" names like "test" 130 or "mock-mac", and it does not include any directories that are not. 131 132 If platform is not specified, we will glob-match all ports""" 133 platform = platform or '*' 134 return fnmatch.filter(builders.all_port_names(), platform) 135 136 def get_from_builder_name(self, builder_name): 137 port_name = builders.port_name_for_builder_name(builder_name) 138 assert port_name, "unrecognized builder name '%s'" % builder_name 139 return self.get(port_name, _builder_options(builder_name)) 140