initial import
[vuplus_webkit] / Tools / Scripts / webkitpy / layout_tests / port / factory.py
1 #!/usr/bin/env python
2 # Copyright (C) 2010 Google Inc. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
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
13 # distribution.
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.
17 #
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.
29
30 """Factory method to retrieve the appropriate port implementation."""
31
32 import re
33 import sys
34
35 from webkitpy.layout_tests.port import builders
36
37
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
42
43
44 class PortFactory(object):
45     def __init__(self, host=None):
46         self._host = host
47
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'
55                 else:
56                     port_to_use = '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.
63                 else:
64                     port_to_use = 'mac'
65
66         if port_to_use is None:
67             raise NotImplementedError('unknown port; sys.platform = "%s"' % sys.platform)
68         return port_to_use
69
70     def _get_kwargs(self, **kwargs):
71         port_to_use = self._port_name_from_arguments_and_options(**kwargs)
72
73         if port_to_use.startswith('test'):
74             import test
75             maker = test.TestPort
76         elif port_to_use.startswith('dryrun'):
77             import dryrun
78             maker = dryrun.DryRunPort
79         elif port_to_use.startswith('mock-'):
80             import mock_drt
81             maker = mock_drt.MockDRTPort
82         elif port_to_use.startswith('mac'):
83             import mac
84             maker = mac.MacPort
85         elif port_to_use.startswith('win'):
86             import win
87             maker = win.WinPort
88         elif port_to_use.startswith('gtk'):
89             import gtk
90             maker = gtk.GtkPort
91         elif port_to_use.startswith('qt'):
92             import qt
93             maker = qt.QtPort
94         elif port_to_use.startswith('chromium-gpu'):
95             import chromium_gpu
96             maker = chromium_gpu.get
97         elif port_to_use.startswith('chromium-mac') or port_to_use.startswith('chromium-cg-mac'):
98             import chromium_mac
99             maker = chromium_mac.ChromiumMacPort
100         elif port_to_use.startswith('chromium-linux'):
101             import chromium_linux
102             maker = chromium_linux.ChromiumLinuxPort
103         elif port_to_use.startswith('chromium-win'):
104             import chromium_win
105             maker = chromium_win.ChromiumWinPort
106         elif port_to_use.startswith('google-chrome'):
107             import google_chrome
108             maker = google_chrome.GetGoogleChromePort
109         else:
110             raise NotImplementedError('unsupported port: %s' % port_to_use)
111
112         # Make sure that any Ports created by this factory inherit
113         # the executive/user/filesystem from the provided host.
114         # FIXME: Eventually NRWT will use a Host object and Port will no longer store these pointers.
115         if self._host:
116             kwargs.setdefault('executive', self._host.executive)
117             kwargs.setdefault('user', self._host.user)
118             kwargs.setdefault('filesystem', self._host.filesystem)
119
120         return maker(**kwargs)
121
122     def all_port_names(self):
123         """Return a list of all valid, fully-specified, "real" port names.
124
125         This is the list of directories that are used as actual baseline_paths()
126         by real ports. This does not include any "fake" names like "test"
127         or "mock-mac", and it does not include any directories that are not ."""
128         # FIXME: There's probably a better way to generate this list ...
129         return builders.all_port_names()
130
131     def get(self, port_name=None, options=None, **kwargs):
132         """Returns an object implementing the Port interface. If
133         port_name is None, this routine attempts to guess at the most
134         appropriate port on this platform."""
135         # Wrapped for backwards-compatibility
136         if port_name:
137             kwargs['port_name'] = port_name
138         if options:
139             kwargs['options'] = options
140         return self._get_kwargs(**kwargs)
141
142     def get_from_builder_name(self, builder_name):
143         port_name = builders.port_name_for_builder_name(builder_name)
144         assert(port_name)  # Need to update port_name_for_builder_name
145         port = self.get(port_name, BuilderOptions(builder_name))
146         assert(port)  # Need to update port_name_for_builder_name
147         return port
148
149
150
151 # FIXME: These free functions are all deprecated.  Callers should be using PortFactory instead.
152 def all_port_names():
153     return PortFactory().all_port_names()
154
155 def get(port_name=None, options=None, **kwargs):
156     return PortFactory().get(port_name, options, **kwargs)
157
158 def get_from_builder_name(builder_name):
159     return PortFactory().get_from_builder_name(builder_name)