Title: [101107] trunk/Tools
Revision
101107
Author
e...@webkit.org
Date
2011-11-23 15:23:21 -0800 (Wed, 23 Nov 2011)

Log Message

Add Environment object to Host and fix the GCC smartquotes trouble seen on the commit-queue
https://bugs.webkit.org/show_bug.cgi?id=71983

Reviewed by Adam Barth.

We'll add more code to Environment overtime,
allowing us to mock out more of our direct interactions with os.environ.

This patch also makes run_command print the passed in environment.

* Scripts/webkitpy/common/host_mock.py:
* Scripts/webkitpy/common/system/environment.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
* Scripts/webkitpy/common/system/environment_mock.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
* Scripts/webkitpy/common/system/environment_unittest.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
* Scripts/webkitpy/common/system/executive.py:
* Scripts/webkitpy/common/system/executive_mock.py:
* Scripts/webkitpy/layout_tests/port/webkit.py:
* Scripts/webkitpy/layout_tests/port/webkit_unittest.py:
* Scripts/webkitpy/tool/commands/download_unittest.py:
* Scripts/webkitpy/tool/steps/build.py:

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (101106 => 101107)


--- trunk/Tools/ChangeLog	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/ChangeLog	2011-11-23 23:23:21 UTC (rev 101107)
@@ -1,3 +1,26 @@
+2011-11-23  Eric Seidel  <e...@webkit.org>
+
+        Add Environment object to Host and fix the GCC smartquotes trouble seen on the commit-queue
+        https://bugs.webkit.org/show_bug.cgi?id=71983
+
+        Reviewed by Adam Barth.
+
+        We'll add more code to Environment overtime,
+        allowing us to mock out more of our direct interactions with os.environ.
+
+        This patch also makes run_command print the passed in environment.
+
+        * Scripts/webkitpy/common/host_mock.py:
+        * Scripts/webkitpy/common/system/environment.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
+        * Scripts/webkitpy/common/system/environment_mock.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
+        * Scripts/webkitpy/common/system/environment_unittest.py: Copied from Tools/Scripts/webkitpy/tool/steps/build.py.
+        * Scripts/webkitpy/common/system/executive.py:
+        * Scripts/webkitpy/common/system/executive_mock.py:
+        * Scripts/webkitpy/layout_tests/port/webkit.py:
+        * Scripts/webkitpy/layout_tests/port/webkit_unittest.py:
+        * Scripts/webkitpy/tool/commands/download_unittest.py:
+        * Scripts/webkitpy/tool/steps/build.py:
+
 2011-11-23  Tor Arne Vestbø  <tor.arne.ves...@nokia.com>
 
         [Qt] Re-generate QtWebKit API forwarding headers when API changes

Modified: trunk/Tools/Scripts/webkitpy/common/host.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/host.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/common/host.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -28,6 +28,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 import logging
+import os
 import sys
 
 from webkitpy.common.checkout import Checkout
@@ -94,6 +95,9 @@
             except OSError, e:
                 _log.debug('Failed to engage svn.bat Windows hack.')
 
+    def copy_current_environment(self):
+        return Environment(os.environ.copy())
+
     def _initialize_scm(self, patch_directories=None):
         if sys.platform == "win32":
             self._engage_awesome_windows_hacks()

Modified: trunk/Tools/Scripts/webkitpy/common/host_mock.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/host_mock.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/common/host_mock.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -31,6 +31,7 @@
 from webkitpy.common.net.bugzilla.bugzilla_mock import MockBugzilla
 from webkitpy.common.net.buildbot.buildbot_mock import MockBuildBot
 from webkitpy.common.net.web_mock import MockWeb
+from webkitpy.common.system.environment import Environment
 from webkitpy.common.system.executive_mock import MockExecutive
 from webkitpy.common.system.filesystem_mock import MockFileSystem
 from webkitpy.common.system.platforminfo_mock import MockPlatformInfo
@@ -66,6 +67,9 @@
 
         self._watch_list = MockWatchList()
 
+    def copy_current_environment(self):
+        return Environment({"MOCK_ENVIRON_COPY": '1'})
+
     def _initialize_scm(self, patch_directories=None):
         pass
 

Copied: trunk/Tools/Scripts/webkitpy/common/system/environment.py (from rev 101104, trunk/Tools/Scripts/webkitpy/tool/steps/build.py) (0 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/system/environment.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/system/environment.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -0,0 +1,41 @@
+# Copyright (C) 2011 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+class Environment(object):
+    def __init__(self, env=None):
+        self.env = env or {}
+
+    def to_dictionary(self):
+        return self.env
+
+    def disable_gcc_smartquotes(self):
+        # Technically we only need to set LC_CTYPE to disable current
+        # smartquote behavior: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38363
+        # Apple's XCode sets LC_ALL instead, probably to be future-proof.
+        self.env['LC_ALL'] = 'C'

Copied: trunk/Tools/Scripts/webkitpy/common/system/environment_unittest.py (from rev 101104, trunk/Tools/Scripts/webkitpy/tool/steps/build.py) (0 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/system/environment_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/webkitpy/common/system/environment_unittest.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -0,0 +1,39 @@
+# Copyright (C) 2011 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#    * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#    * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+from .environment import Environment
+
+
+class EnvironmentTest(unittest.TestCase):
+    def test_disable_gcc_smartquotes(self):
+        environment = Environment({})
+        environment.disable_gcc_smartquotes()
+        env = environment.to_dictionary()
+        self.assertEqual(env['LC_ALL'], 'C')

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/system/executive.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -108,7 +108,7 @@
         # shows up on Mac and Linux.
         return sys.platform not in ('win32', 'cygwin')
 
-    def _run_command_with_teed_output(self, args, teed_output, cwd=None):
+    def _run_command_with_teed_output(self, args, teed_output, **kwargs):
         args = map(unicode, args)  # Popen will throw an exception if args are non-strings (like int())
         args = map(self._encode_argument_if_needed, args)
 
@@ -116,7 +116,7 @@
                                    stdout=self.PIPE,
                                    stderr=self.STDOUT,
                                    close_fds=self._should_close_fds(),
-                                   cwd=cwd)
+                                   **kwargs)
 
         # Use our own custom wait loop because Popen ignores a tee'd
         # stderr/stdout.
@@ -136,7 +136,7 @@
     # capture their output and print out to stdin.  Useful for things
     # like "build-webkit" where we want to display to the user that we're building
     # but still have the output to stuff into a log file.
-    def run_and_throw_if_fail(self, args, quiet=False, decode_output=True, cwd=None):
+    def run_and_throw_if_fail(self, args, quiet=False, decode_output=True, **kwargs):
         # Cache the child's output locally so it can be used for error reports.
         child_out_file = StringIO.StringIO()
         tee_stdout = sys.stdout
@@ -144,7 +144,7 @@
             dev_null = open(os.devnull, "w")  # FIXME: Does this need an encoding?
             tee_stdout = dev_null
         child_stdout = tee(child_out_file, tee_stdout)
-        exit_code = self._run_command_with_teed_output(args, child_stdout, cwd=cwd)
+        exit_code = self._run_command_with_teed_output(args, child_stdout, **kwargs)
         if quiet:
             dev_null.close()
 

Modified: trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/common/system/executive_mock.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -44,9 +44,12 @@
     def check_running_pid(self, pid):
         return pid in self._running_pids
 
-    def run_and_throw_if_fail(self, args, quiet=False, cwd=None):
+    def run_and_throw_if_fail(self, args, quiet=False, cwd=None, env=None):
         if self._should_log:
-            log("MOCK run_and_throw_if_fail: %s, cwd=%s" % (args, cwd))
+            env_string = ""
+            if env:
+                env_string = ", env=%s" % env
+            log("MOCK run_and_throw_if_fail: %s, cwd=%s%s" % (args, cwd, env_string))
         if self._should_throw_when_run.intersection(args):
             raise ScriptError("Exception for %s" % args)
         return "MOCK output of child process"
@@ -58,10 +61,14 @@
                     error_handler=None,
                     return_exit_code=False,
                     return_stderr=True,
-                    decode_output=False):
+                    decode_output=False,
+                    env=None):
         assert(isinstance(args, list) or isinstance(args, tuple))
         if self._should_log:
-            log("MOCK run_command: %s, cwd=%s" % (args, cwd))
+            env_string = ""
+            if env:
+                env_string = ", env=%s" % env
+            log("MOCK run_command: %s, cwd=%s%s" % (args, cwd, env_string))
         if self._should_throw:
             raise ScriptError("MOCK ScriptError")
         return "MOCK output of child process"
@@ -92,7 +99,8 @@
                     error_handler=None,
                     return_exit_code=False,
                     return_stderr=True,
-                    decode_output=False):
+                    decode_output=False,
+                    env=None):
         assert(isinstance(args, list) or isinstance(args, tuple))
         if self._exception:
             raise self._exception

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -41,6 +41,7 @@
 
 from webkitpy.common.memoized import memoized
 from webkitpy.common.net.buildbot import BuildBot
+from webkitpy.common.system.environment import Environment
 from webkitpy.common.system.executive import Executive, ScriptError
 from webkitpy.layout_tests.port import builders, server_process, Port, Driver, DriverOutput
 
@@ -80,11 +81,6 @@
         expectations_directory = self._wk2_port_name() if self.get_option('webkit_test_runner') else self.port_name
         return self._filesystem.join(self._webkit_baseline_path(expectations_directory), 'test_expectations.txt')
 
-    def _driver_build_script_name(self):
-        if self.get_option('webkit_test_runner'):
-            return "build-webkittestrunner"
-        return "build-dumprendertree"
-
     def _port_flag_for_scripts(self):
         # This is overrriden by ports which need a flag passed to scripts to distinguish the use of that port.
         # For example --qt on linux, since a user might have both Gtk and Qt libraries installed.
@@ -101,24 +97,28 @@
             config_args.append(port_flag)
         return config_args
 
-    def _run_script(self, script_name, args=None, include_configuration_arguments=True, decode_output=True):
+    def _run_script(self, script_name, args=None, include_configuration_arguments=True, decode_output=True, env=None):
         run_script_command = [self._config.script_path(script_name)]
         if include_configuration_arguments:
             run_script_command.extend(self._arguments_for_configuration())
         if args:
             run_script_command.extend(args)
-        return self._executive.run_command(run_script_command, cwd=self._config.webkit_base_dir(), decode_output=decode_output)
+        return self._executive.run_command(run_script_command, cwd=self._config.webkit_base_dir(), decode_output=decode_output, env=env)
 
     def _build_driver(self):
+        environment = self.host.copy_current_environment()
+        environment.disable_gcc_smartquotes()
+        env = environment.to_dictionary()
+
         # FIXME: We build both DumpRenderTree and WebKitTestRunner for
         # WebKitTestRunner runs because DumpRenderTree still includes
         # the DumpRenderTreeSupport module and the TestNetscapePlugin.
         # These two projects should be factored out into their own
         # projects.
         try:
-            self._run_script("build-dumprendertree")
+            self._run_script("build-dumprendertree", env=env)
             if self.get_option('webkit_test_runner'):
-                self._run_script("build-webkittestrunner")
+                self._run_script("build-webkittestrunner", env=env)
         except ScriptError:
             _log.error("Failed to build %s" % self.driver_name())
             return False

Modified: trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/layout_tests/port/webkit_unittest.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -177,18 +177,18 @@
         # Delay setting _executive to avoid logging during construction
         port._executive = MockExecutive(should_log=True)
         port._options = MockOptions(configuration="Release")  # This should not be necessary, but I think TestWebKitPort is actually reading from disk (and thus detects the current configuration).
-        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout\n"
+        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}\n"
         self.assertTrue(output.assert_outputs(self, port._build_driver, expected_stderr=expected_stderr))
 
         # Make sure when passed --webkit-test-runner web build the right tool.
         port._options = MockOptions(webkit_test_runner=True, configuration="Release")
-        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout\nMOCK run_command: ['Tools/Scripts/build-webkittestrunner', '--release'], cwd=/mock-checkout\n"
+        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}\nMOCK run_command: ['Tools/Scripts/build-webkittestrunner', '--release'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}\n"
         self.assertTrue(output.assert_outputs(self, port._build_driver, expected_stderr=expected_stderr))
 
         # Make sure that failure to build returns False.
         port._executive = MockExecutive(should_log=True, should_throw=True)
         # Because WK2 currently has to build both webkittestrunner and DRT, if DRT fails, that's the only one it tries.
-        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout\n"
+        expected_stderr = "MOCK run_command: ['Tools/Scripts/build-dumprendertree', '--release'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}\n"
         self.assertFalse(output.assert_outputs(self, port._build_driver, expected_stderr=expected_stderr))
 
     def _assert_config_file_for_platform(self, port, platform, config_file):

Modified: trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/download_unittest.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -132,7 +132,7 @@
 MOCK: user.open_url: file://...
 Was that diff correct?
 Building WebKit
-MOCK run_and_throw_if_fail: ['mock-build-webkit'], cwd=/mock-checkout
+MOCK run_and_throw_if_fail: ['mock-build-webkit'], cwd=/mock-checkout, env={'LC_ALL': 'C', 'MOCK_ENVIRON_COPY': '1'}
 Running Python unit tests
 MOCK run_and_throw_if_fail: ['mock-test-webkitpy'], cwd=/mock-checkout
 Running Perl unit tests

Modified: trunk/Tools/Scripts/webkitpy/tool/steps/build.py (101106 => 101107)


--- trunk/Tools/Scripts/webkitpy/tool/steps/build.py	2011-11-23 23:11:39 UTC (rev 101106)
+++ trunk/Tools/Scripts/webkitpy/tool/steps/build.py	2011-11-23 23:23:21 UTC (rev 101107)
@@ -41,8 +41,14 @@
         ]
 
     def build(self, build_style):
-        self._tool.executive.run_and_throw_if_fail(self._tool.port().build_webkit_command(build_style=build_style), self._options.quiet, cwd=self._tool.scm().checkout_root)
+        environment = self._tool.copy_current_environment()
+        environment.disable_gcc_smartquotes()
+        env = environment.to_dictionary()
 
+        build_webkit_command = self._tool.port().build_webkit_command(build_style=build_style)
+        self._tool.executive.run_and_throw_if_fail(build_webkit_command, self._options.quiet,
+            cwd=self._tool.scm().checkout_root, env=env)
+
     def run(self, state):
         if not self._options.build:
             return
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to