Home | History | Annotate | Download | only in port
      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