webkitpy: Provide option to skip install
[WebKit-https.git] / Tools / Scripts / webkitpy / port / factory.py
1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 # Copyright (C) 2013 Apple Inc. All rights reserved.
3 # Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 #     * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 #     * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 #     * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 """Factory method to retrieve the appropriate port implementation."""
32
33 import fnmatch
34 import optparse
35 import re
36
37 from webkitpy.port import builders
38 from webkitpy.port import config
39 from webkitpy.common.system import executive
40 from webkitpy.common.system import filesystem
41
42
43 def platform_options(use_globs=False):
44     return [
45         optparse.make_option('--platform', action='store',
46             help=('Glob-style list of platform/ports to use (e.g., "mac*")' if use_globs else 'Platform to use (e.g., "mac-lion")')),
47         optparse.make_option('--ios-simulator', action='store_const', dest='platform',
48             const=('ios-simulator'),
49             help=('Alias for --platform=ios-simulator')),
50         optparse.make_option('--simulator', action='store_const', dest='platform',
51             const=('ios-simulator'),
52             help=('DEPRECATED alias for --platform=ios-simulator')),
53         optparse.make_option('--efl', action='store_const', dest='platform',
54             const=('efl*' if use_globs else 'efl'),
55             help=('Alias for --platform=efl*' if use_globs else 'Alias for --platform=efl')),
56         optparse.make_option('--gtk', action='store_const', dest='platform',
57             const=('gtk*' if use_globs else 'gtk'),
58             help=('Alias for --platform=gtk*' if use_globs else 'Alias for --platform=gtk')),
59         optparse.make_option('--no-install', action='store_const',
60             const=False, default=True, dest='install',
61             help='Skip install step for device and simulator testing'),
62         ]
63
64
65 def configuration_options():
66     return [
67         optparse.make_option("-t", "--target", default=config.Config(executive.Executive(), filesystem.FileSystem()).default_configuration(), dest="configuration", help="(DEPRECATED) (default: %default)"),
68         optparse.make_option('--debug', action='store_const', const='Debug', dest="configuration",
69             help='Set the configuration to Debug'),
70         optparse.make_option('--release', action='store_const', const='Release', dest="configuration",
71             help='Set the configuration to Release'),
72         optparse.make_option('--64-bit', action='store_const', const='x86_64', default=None, dest="architecture",
73             help='use 64-bit binaries by default (x86_64 instead of x86)'),
74         optparse.make_option('--32-bit', action='store_const', const='x86', default=None, dest="architecture",
75             help='use 32-bit binaries by default (x86 instead of x86_64)'),
76         ]
77
78
79 def _builder_options(builder_name):
80     configuration = "Debug" if re.search(r"[d|D](ebu|b)g", builder_name) else "Release"
81     is_webkit2 = builder_name.find("WK2") != -1
82     builder_name = builder_name
83     return optparse.Values({'builder_name': builder_name, 'configuration': configuration, 'webkit_test_runner': is_webkit2})
84
85
86 class PortFactory(object):
87     # Order matters.  For port classes that have a port_name with a
88     # common prefix, the more specific port class should be listed
89     # first.
90     PORT_CLASSES = (
91         'efl.EflPort',
92         'gtk.GtkPort',
93         'ios_simulator.IOSSimulatorPort',
94         'ios_device.IOSDevicePort',
95         'mac.MacPort',
96         'mock_drt.MockDRTPort',
97         'test.TestPort',
98         'win.WinCairoPort',
99         'win.WinPort',
100     )
101
102     def __init__(self, host):
103         self._host = host
104
105     def _default_port(self, options):
106         platform = self._host.platform
107         if platform.is_linux() or platform.is_freebsd():
108             return 'gtk'
109         elif platform.is_mac():
110             return 'mac'
111         elif platform.is_win():
112             return 'win'
113         raise NotImplementedError('unknown platform: %s' % platform)
114
115     def get(self, port_name=None, options=None, **kwargs):
116         """Returns an object implementing the Port interface. If
117         port_name is None, this routine attempts to guess at the most
118         appropriate port on this platform."""
119         port_name = port_name or self._default_port(options)
120
121         for port_class in self.PORT_CLASSES:
122             module_name, class_name = port_class.rsplit('.', 1)
123             module = __import__(module_name, globals(), locals(), [], -1)
124             cls = module.__dict__[class_name]
125             if port_name.startswith(cls.port_name):
126                 port_name = cls.determine_full_port_name(self._host, options, port_name)
127                 return cls(self._host, port_name, options=options, **kwargs)
128         raise NotImplementedError('unsupported platform: "%s"' % port_name)
129
130     def all_port_names(self, platform=None):
131         """Return a list of all valid, fully-specified, "real" port names.
132
133         This is the list of directories that are used as actual baseline_paths()
134         by real ports. This does not include any "fake" names like "test"
135         or "mock-mac", and it does not include any directories that are not.
136
137         If platform is not specified, we will glob-match all ports"""
138         platform = platform or '*'
139         return fnmatch.filter(builders.all_port_names(), platform)
140
141     def get_from_builder_name(self, builder_name):
142         port_name = builders.port_name_for_builder_name(builder_name)
143         assert port_name, "unrecognized builder name '%s'" % builder_name
144         return self.get(port_name, _builder_options(builder_name))