2 # Copyright (C) 2010 Google Inc. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 """Factory method to retrieve the appropriate port implementation."""
35 from webkitpy.layout_tests.port import builders
38 class BuilderOptions(object):
39 def __init__(self, builder_name):
40 self.configuration = "Debug" if re.search(r"[d|D](ebu|b)g", builder_name) else "Release"
41 self.builder_name = builder_name
44 class PortFactory(object):
45 def __init__(self, host=None):
48 def _port_name_from_arguments_and_options(self, **kwargs):
49 port_to_use = kwargs.get('port_name', None)
50 options = kwargs.get('options', None)
51 if port_to_use is None:
52 if sys.platform == 'win32' or sys.platform == 'cygwin':
53 if options and hasattr(options, 'chromium') and options.chromium:
54 port_to_use = 'chromium-win'
57 elif sys.platform.startswith('linux'):
58 port_to_use = 'chromium-linux'
59 elif sys.platform == 'darwin':
60 if options and hasattr(options, 'chromium') and options.chromium:
61 port_to_use = 'chromium-cg-mac'
62 # FIXME: Add a way to select the chromium-mac port.
66 if port_to_use is None:
67 raise NotImplementedError('unknown port; sys.platform = "%s"' % sys.platform)
70 def _set_default_overriding_none(self, dictionary, key, default):
71 # dict.setdefault almost works, but won't actually override None values, which we want.
72 if not dictionary.get(key):
73 dictionary[key] = default
74 return dictionary[key]
76 def _get_kwargs(self, host=None, **kwargs):
77 port_to_use = self._port_name_from_arguments_and_options(**kwargs)
79 if port_to_use.startswith('test'):
82 # FIXME: This is a hack to override the "default" filesystem
83 # provided to the port. The unit_test_filesystem has an extra
84 # _tests attribute which a bunch of unittests depend on.
85 from .test import unit_test_filesystem
86 self._set_default_overriding_none(kwargs, 'filesystem', unit_test_filesystem())
87 elif port_to_use.startswith('dryrun'):
89 maker = dryrun.DryRunPort
90 elif port_to_use.startswith('mock-'):
92 maker = mock_drt.MockDRTPort
93 elif port_to_use.startswith('mac'):
96 elif port_to_use.startswith('win'):
99 elif port_to_use.startswith('gtk'):
102 elif port_to_use.startswith('qt'):
105 elif port_to_use.startswith('chromium-gpu'):
107 maker = chromium_gpu.get
108 elif port_to_use.startswith('chromium-mac') or port_to_use.startswith('chromium-cg-mac'):
110 maker = chromium_mac.ChromiumMacPort
111 elif port_to_use.startswith('chromium-linux'):
112 import chromium_linux
113 maker = chromium_linux.ChromiumLinuxPort
114 elif port_to_use.startswith('chromium-win'):
116 maker = chromium_win.ChromiumWinPort
117 elif port_to_use.startswith('google-chrome'):
119 maker = google_chrome.GetGoogleChromePort
120 elif port_to_use.startswith('efl'):
124 raise NotImplementedError('unsupported port: %s' % port_to_use)
126 host = host or self._host
127 return maker(host, **kwargs)
129 def all_port_names(self):
130 """Return a list of all valid, fully-specified, "real" port names.
132 This is the list of directories that are used as actual baseline_paths()
133 by real ports. This does not include any "fake" names like "test"
134 or "mock-mac", and it does not include any directories that are not ."""
135 # FIXME: There's probably a better way to generate this list ...
136 return builders.all_port_names()
138 def get(self, port_name=None, options=None, **kwargs):
139 """Returns an object implementing the Port interface. If
140 port_name is None, this routine attempts to guess at the most
141 appropriate port on this platform."""
142 # Wrapped for backwards-compatibility
144 kwargs['port_name'] = port_name
146 kwargs['options'] = options
147 return self._get_kwargs(**kwargs)
149 def get_from_builder_name(self, builder_name):
150 port_name = builders.port_name_for_builder_name(builder_name)
151 assert(port_name) # Need to update port_name_for_builder_name
152 port = self.get(port_name, BuilderOptions(builder_name))
153 assert(port) # Need to update port_name_for_builder_name