542379cb58d35eae603ba1ae094ff4da8bf61d7d
[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-sim', action='store_const', dest='platform',
48             const=('ios-simulator'),
49             help=('Alias for --platform=ios-sim*' if use_globs else 'Alias for --platform=ios-simulator')),
50         optparse.make_option('--ios-simulator', action='store_const', dest='platform',
51             const=('ios-simulator'),
52             help=('Alias for --platform=ios-sim*' if use_globs else '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         ]
60
61
62 def configuration_options():
63     return [
64         optparse.make_option("-t", "--target", default=config.Config(executive.Executive(), filesystem.FileSystem()).default_configuration(), dest="configuration", help="(DEPRECATED) (default: %default)"),
65         optparse.make_option('--debug', action='store_const', const='Debug', dest="configuration",
66             help='Set the configuration to Debug'),
67         optparse.make_option('--release', action='store_const', const='Release', dest="configuration",
68             help='Set the configuration to Release'),
69         optparse.make_option('--32-bit', action='store_const', const='x86', default=None, dest="architecture",
70             help='use 32-bit binaries by default (x86 instead of x86_64)'),
71         ]
72
73
74
75 def _builder_options(builder_name):
76     configuration = "Debug" if re.search(r"[d|D](ebu|b)g", builder_name) else "Release"
77     is_webkit2 = builder_name.find("WK2") != -1
78     builder_name = builder_name
79     return optparse.Values({'builder_name': builder_name, 'configuration': configuration, 'webkit_test_runner': is_webkit2})
80
81
82 class PortFactory(object):
83     PORT_CLASSES = (
84         'efl.EflPort',
85         'gtk.GtkPort',
86         'ios.IOSPort',
87         'ios.IOSSimulatorPort',
88         'mac.MacPort',
89         'mock_drt.MockDRTPort',
90         'test.TestPort',
91         'win.WinPort',
92     )
93
94     def __init__(self, host):
95         self._host = host
96
97     def _default_port(self, options):
98         platform = self._host.platform
99         if platform.is_linux() or platform.is_freebsd():
100             return 'gtk'
101         elif platform.is_mac():
102             return 'mac'
103         elif platform.is_win():
104             return 'win'
105         raise NotImplementedError('unknown platform: %s' % platform)
106
107     def get(self, port_name=None, options=None, **kwargs):
108         """Returns an object implementing the Port interface. If
109         port_name is None, this routine attempts to guess at the most
110         appropriate port on this platform."""
111         port_name = port_name or self._default_port(options)
112
113         for port_class in self.PORT_CLASSES:
114             module_name, class_name = port_class.rsplit('.', 1)
115             module = __import__(module_name, globals(), locals(), [], -1)
116             cls = module.__dict__[class_name]
117             if port_name.startswith(cls.port_name):
118                 port_name = cls.determine_full_port_name(self._host, options, port_name)
119                 return cls(self._host, port_name, options=options, **kwargs)
120         raise NotImplementedError('unsupported platform: "%s"' % port_name)
121
122     def all_port_names(self, platform=None):
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
129         If platform is not specified, we will glob-match all ports"""
130         platform = platform or '*'
131         return fnmatch.filter(builders.all_port_names(), platform)
132
133     def get_from_builder_name(self, builder_name):
134         port_name = builders.port_name_for_builder_name(builder_name)
135         assert port_name, "unrecognized builder name '%s'" % builder_name
136         return self.get(port_name, _builder_options(builder_name))