summaryrefslogtreecommitdiff
path: root/Tools/Scripts/webkitpy/common/system
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/Scripts/webkitpy/common/system')
-rw-r--r--Tools/Scripts/webkitpy/common/system/crashlogs.py57
-rw-r--r--Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py18
-rw-r--r--Tools/Scripts/webkitpy/common/system/executive.py15
-rw-r--r--Tools/Scripts/webkitpy/common/system/executive_mock.py23
-rw-r--r--Tools/Scripts/webkitpy/common/system/file_lock.py16
-rw-r--r--Tools/Scripts/webkitpy/common/system/filesystem.py5
-rw-r--r--Tools/Scripts/webkitpy/common/system/filesystem_mock.py9
-rw-r--r--Tools/Scripts/webkitpy/common/system/platforminfo.py7
-rw-r--r--Tools/Scripts/webkitpy/common/system/platforminfo_mock.py8
-rw-r--r--Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py31
-rw-r--r--Tools/Scripts/webkitpy/common/system/systemhost_mock.py6
-rw-r--r--Tools/Scripts/webkitpy/common/system/user.py16
12 files changed, 139 insertions, 72 deletions
diff --git a/Tools/Scripts/webkitpy/common/system/crashlogs.py b/Tools/Scripts/webkitpy/common/system/crashlogs.py
index a6b6575f6..0dd37d255 100644
--- a/Tools/Scripts/webkitpy/common/system/crashlogs.py
+++ b/Tools/Scripts/webkitpy/common/system/crashlogs.py
@@ -26,51 +26,46 @@
# (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 os
import re
-import sys
class CrashLogs(object):
- def __init__(self, filesystem):
- self._filesystem = filesystem
+ def __init__(self, host):
+ self._host = host
- def find_newest_log(self, process_name, pid=None):
- if sys.platform == "darwin":
- return self._find_newest_log_darwin(process_name, pid)
+ def find_newest_log(self, process_name, pid=None, include_errors=False, newer_than=None):
+ if self._host.platform.is_mac():
+ return self._find_newest_log_darwin(process_name, pid, include_errors, newer_than)
+ return None
def _log_directory_darwin(self):
- log_directory = self._filesystem.expanduser("~")
- log_directory = self._filesystem.join(log_directory, "Library", "Logs")
- if self._filesystem.exists(self._filesystem.join(log_directory, "DiagnosticReports")):
- log_directory = self._filesystem.join(log_directory, "DiagnosticReports")
+ log_directory = self._host.filesystem.expanduser("~")
+ log_directory = self._host.filesystem.join(log_directory, "Library", "Logs")
+ if self._host.filesystem.exists(self._host.filesystem.join(log_directory, "DiagnosticReports")):
+ log_directory = self._host.filesystem.join(log_directory, "DiagnosticReports")
else:
- log_directory = self._filesystem.join(log_directory, "CrashReporter")
+ log_directory = self._host.filesystem.join(log_directory, "CrashReporter")
return log_directory
- def _find_newest_log_darwin(self, process_name, pid):
+ def _find_newest_log_darwin(self, process_name, pid, include_errors, newer_than):
def is_crash_log(fs, dirpath, basename):
return basename.startswith(process_name + "_") and basename.endswith(".crash")
log_directory = self._log_directory_darwin()
- logs = self._filesystem.files_under(log_directory, file_filter=is_crash_log)
- if not logs:
- return None
+ logs = self._host.filesystem.files_under(log_directory, file_filter=is_crash_log)
first_line_regex = re.compile(r'^Process:\s+(?P<process_name>.*) \[(?P<pid>\d+)\]$')
+ errors = ''
for path in reversed(sorted(logs)):
- try:
- with self._filesystem.open_text_file_for_reading(path) as f:
- first_line = f.readline()
+ if not newer_than or self._host.filesystem.mtime(path) > newer_than:
+ try:
+ f = self._host.filesystem.read_text_file(path)
+ match = first_line_regex.match(f[0:f.find('\n')])
+ if match and match.group('process_name') == process_name and (pid is None or int(match.group('pid')) == pid):
+ return errors + f
+ except IOError, e:
+ if include_errors:
+ errors += "ERROR: Failed to read '%s': %s\n" % (path, str(e))
- match = first_line_regex.match(first_line)
- if not match:
- continue
- if match.group('process_name') != process_name:
- continue
- if pid is not None and int(match.group('pid')) != pid:
- continue
-
- f.seek(0, os.SEEK_SET)
- return f.read()
- except IOError:
- continue
+ if include_errors and errors:
+ return errors
+ return None
diff --git a/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py b/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py
index ab1a6c2ad..d93feec0e 100644
--- a/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py
+++ b/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py
@@ -22,10 +22,11 @@
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import unittest
-import sys
-from webkitpy.common.system.crashlogs import *
+from webkitpy.common.system.crashlogs import CrashLogs
from webkitpy.common.system.filesystem_mock import MockFileSystem
+from webkitpy.common.system.systemhost import SystemHost
+from webkitpy.common.system.systemhost_mock import MockSystemHost
from webkitpy.thirdparty.mock import Mock
@@ -75,7 +76,7 @@ class CrashLogsTest(unittest.TestCase):
self.assertEqual(a.splitlines(), b.splitlines())
def test_find_log_darwin(self):
- if sys.platform != "darwin":
+ if not SystemHost().platform.is_mac():
return
older_mock_crash_report = make_mock_crash_report_darwin('DumpRenderTree', 28528)
@@ -91,7 +92,7 @@ class CrashLogsTest(unittest.TestCase):
files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = other_process_mock_crash_report
files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = misformatted_mock_crash_report
filesystem = MockFileSystem(files)
- crash_logs = CrashLogs(filesystem)
+ crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem))
log = crash_logs.find_newest_log("DumpRenderTree")
self.assertLinesEqual(log, newer_mock_crash_report)
log = crash_logs.find_newest_log("DumpRenderTree", 28529)
@@ -100,3 +101,12 @@ class CrashLogsTest(unittest.TestCase):
self.assertLinesEqual(log, mock_crash_report)
log = crash_logs.find_newest_log("DumpRenderTree", 28531)
self.assertEqual(log, None)
+ log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0)
+ self.assertEqual(log, None)
+
+ def bad_read(path):
+ raise IOError('No such file or directory')
+
+ filesystem.read_text_file = bad_read
+ log = crash_logs.find_newest_log("DumpRenderTree", 28531, include_errors=True)
+ self.assertTrue('No such file or directory' in log)
diff --git a/Tools/Scripts/webkitpy/common/system/executive.py b/Tools/Scripts/webkitpy/common/system/executive.py
index 06f870c72..43dcbca1b 100644
--- a/Tools/Scripts/webkitpy/common/system/executive.py
+++ b/Tools/Scripts/webkitpy/common/system/executive.py
@@ -32,7 +32,6 @@ import ctypes
import errno
import logging
import os
-import platform
import StringIO
import signal
import subprocess
@@ -255,16 +254,14 @@ class Executive(object):
def check_running_pid(self, pid):
"""Return True if pid is alive, otherwise return False."""
- if sys.platform.startswith('linux') or sys.platform in ('darwin', 'cygwin'):
- try:
- os.kill(pid, 0)
- return True
- except OSError:
- return False
- elif sys.platform == 'win32':
+ if sys.platform == 'win32':
return self._win32_check_running_pid(pid)
- assert(False)
+ try:
+ os.kill(pid, 0)
+ return True
+ except OSError:
+ return False
def running_pids(self, process_name_filter=None):
if not process_name_filter:
diff --git a/Tools/Scripts/webkitpy/common/system/executive_mock.py b/Tools/Scripts/webkitpy/common/system/executive_mock.py
index a76268129..d57a5c480 100644
--- a/Tools/Scripts/webkitpy/common/system/executive_mock.py
+++ b/Tools/Scripts/webkitpy/common/system/executive_mock.py
@@ -27,15 +27,20 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
+import StringIO
from webkitpy.common.system.deprecated_logging import log
from webkitpy.common.system.executive import ScriptError
class MockProcess(object):
- def __init__(self):
+ def __init__(self, stdout='MOCK STDOUT\n'):
self.pid = 42
+ self.stdout = StringIO.StringIO(stdout)
+ self.stdin = StringIO.StringIO()
+ def wait(self):
+ return
# FIXME: This should be unified with MockExecutive2
class MockExecutive(object):
@@ -52,6 +57,7 @@ class MockExecutive(object):
self._should_throw_when_run = should_throw_when_run or set()
# FIXME: Once executive wraps os.getpid() we can just use a static pid for "this" process.
self._running_pids = [os.getpid()]
+ self._proc = None
def check_running_pid(self, pid):
return pid in self._running_pids
@@ -89,9 +95,18 @@ class MockExecutive(object):
def cpu_count(self):
return 2
- def popen(self, *args, **kwargs):
- # FIXME: Implement logging when self._should_log is set.
- return MockProcess()
+ def popen(self, args, cwd=None, env=None, **kwargs):
+ if self._should_log:
+ cwd_string = ""
+ if cwd:
+ cwd_string = ", cwd=%s" % cwd
+ env_string = ""
+ if env:
+ env_string = ", env=%s" % env
+ log("MOCK popen: %s%s%s" % (args, cwd_string, env_string))
+ if not self._proc:
+ self._proc = MockProcess()
+ return self._proc
class MockExecutive2(object):
diff --git a/Tools/Scripts/webkitpy/common/system/file_lock.py b/Tools/Scripts/webkitpy/common/system/file_lock.py
index b4bfffc40..c542777f2 100644
--- a/Tools/Scripts/webkitpy/common/system/file_lock.py
+++ b/Tools/Scripts/webkitpy/common/system/file_lock.py
@@ -43,20 +43,20 @@ class FileLock(object):
self._max_wait_time_sec = max_wait_time_sec
def _create_lock(self):
- if sys.platform.startswith('linux') or sys.platform in ('darwin', 'cygwin'):
- import fcntl
- fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_EX | fcntl.LOCK_NB)
- elif sys.platform == 'win32':
+ if sys.platform == 'win32':
import msvcrt
msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_NBLCK, 32)
+ else:
+ import fcntl
+ fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_EX | fcntl.LOCK_NB)
def _remove_lock(self):
- if sys.platform.startswith('linux') or sys.platform in ('darwin', 'cygwin'):
- import fcntl
- fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_UN)
- elif sys.platform == 'win32':
+ if sys.platform == 'win32':
import msvcrt
msvcrt.locking(self._lock_file_descriptor, msvcrt.LK_UNLCK, 32)
+ else:
+ import fcntl
+ fcntl.flock(self._lock_file_descriptor, fcntl.LOCK_UN)
def acquire_lock(self):
self._lock_file_descriptor = os.open(self._lock_file_path, os.O_TRUNC | os.O_CREAT)
diff --git a/Tools/Scripts/webkitpy/common/system/filesystem.py b/Tools/Scripts/webkitpy/common/system/filesystem.py
index 60b680c06..687a31322 100644
--- a/Tools/Scripts/webkitpy/common/system/filesystem.py
+++ b/Tools/Scripts/webkitpy/common/system/filesystem.py
@@ -55,6 +55,9 @@ class FileSystem(object):
def abspath(self, path):
return os.path.abspath(path)
+ def realpath(self, path):
+ return os.path.realpath(path)
+
def path_to_module(self, module_name):
"""A wrapper for all calls to __file__ to allow easy unit testing."""
# FIXME: This is the only use of sys in this file. It's possible this function should move elsewhere.
@@ -201,6 +204,8 @@ class FileSystem(object):
f.write(contents)
def open_text_file_for_reading(self, path):
+ # Note: There appears to be an issue with the returned file objects
+ # not being seekable. See http://stackoverflow.com/questions/1510188/can-seek-and-tell-work-with-utf-8-encoded-documents-in-python .
return codecs.open(path, 'r', 'utf8')
def open_text_file_for_writing(self, path):
diff --git a/Tools/Scripts/webkitpy/common/system/filesystem_mock.py b/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
index 2ff688af7..d4a955080 100644
--- a/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
+++ b/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
@@ -82,6 +82,9 @@ class MockFileSystem(object):
return self.normpath(path)
return self.abspath(self.join(self.cwd, path))
+ def realpath(self, path):
+ return self.abspath(path)
+
def basename(self, path):
return self._split(path)[1]
@@ -129,7 +132,7 @@ class MockFileSystem(object):
file_filter = file_filter or filter_all
files = []
if self.isfile(path):
- if file_filter(self, self.dirname(path), self.basename(path)):
+ if file_filter(self, self.dirname(path), self.basename(path)) and self.files[path] is not None:
files.append(path)
return files
@@ -149,7 +152,7 @@ class MockFileSystem(object):
continue
dirpath, basename = self._split(filename)
- if file_filter(self, dirpath, basename):
+ if file_filter(self, dirpath, basename) and self.files[filename] is not None:
files.append(filename)
return files
@@ -275,7 +278,7 @@ class MockFileSystem(object):
def normpath(self, path):
# This function is called a lot, so we try to optimize the common cases
# instead of always calling _slow_but_correct_normpath(), above.
- if '..' in path:
+ if '..' in path or '/./' in path:
# This doesn't happen very often; don't bother trying to optimize it.
return self._slow_but_correct_normpath(path)
if not path:
diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo.py b/Tools/Scripts/webkitpy/common/system/platforminfo.py
index dd6d6844c..22cafbbee 100644
--- a/Tools/Scripts/webkitpy/common/system/platforminfo.py
+++ b/Tools/Scripts/webkitpy/common/system/platforminfo.py
@@ -48,6 +48,8 @@ class PlatformInfo(object):
self.os_name = self._determine_os_name(sys_module.platform)
if self.os_name == 'linux':
self.os_version = self._determine_linux_version()
+ if self.os_name == 'freebsd':
+ self.os_version = platform_module.release()
if self.os_name.startswith('mac'):
self.os_version = self._determine_mac_version(platform_module.mac_ver()[0])
if self.os_name.startswith('win'):
@@ -62,6 +64,9 @@ class PlatformInfo(object):
def is_linux(self):
return self.os_name == 'linux'
+ def is_freebsd(self):
+ return self.os_name == 'freebsd'
+
def display_name(self):
# platform.platform() returns Darwin information for Mac, which is just confusing.
if self.is_mac():
@@ -93,6 +98,8 @@ class PlatformInfo(object):
return 'linux'
if sys_platform in ('win32', 'cygwin'):
return 'win'
+ if sys_platform.startswith('freebsd'):
+ return 'freebsd'
raise AssertionError('unrecognized platform string "%s"' % sys_platform)
def _determine_mac_version(self, mac_version_string):
diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py b/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py
index 7302761de..c953aa185 100644
--- a/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py
+++ b/Tools/Scripts/webkitpy/common/system/platforminfo_mock.py
@@ -28,8 +28,9 @@
class MockPlatformInfo(object):
- os_name = 'mac'
- os_version = 'snowleopard'
+ def __init__(self, os_name='mac', os_version='snowleopard'):
+ self.os_name = os_name
+ self.os_version = os_version
def is_mac(self):
return self.os_name == 'mac'
@@ -40,6 +41,9 @@ class MockPlatformInfo(object):
def is_win(self):
return self.os_name == 'win'
+ def is_freebsd(self):
+ return self.os_name == 'freebsd'
+
def display_name(self):
return "MockPlatform 1.0"
diff --git a/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py b/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py
index ac9cfb0d7..5a1f85fc3 100644
--- a/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py
+++ b/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py
@@ -45,7 +45,7 @@ def fake_sys(platform_str='darwin', windows_version_tuple=None):
return FakeSysModule()
-def fake_platform(mac_version_string='10.6.3'):
+def fake_platform(mac_version_string='10.6.3', release_string='bar'):
class FakePlatformModule(object):
def mac_ver(self):
@@ -54,6 +54,9 @@ def fake_platform(mac_version_string='10.6.3'):
def platform(self):
return 'foo'
+ def release(self):
+ return release_string
+
return FakePlatformModule()
@@ -75,7 +78,7 @@ class TestPlatformInfo(unittest.TestCase):
self.assertNotEquals(info.os_name, '')
self.assertNotEquals(info.os_version, '')
self.assertNotEquals(info.display_name(), '')
- self.assertTrue(info.is_mac() or info.is_win() or info.is_linux())
+ self.assertTrue(info.is_mac() or info.is_win() or info.is_linux() or info.is_freebsd())
if info.is_mac():
self.assertTrue(info.total_bytes_memory() > 0)
@@ -89,29 +92,41 @@ class TestPlatformInfo(unittest.TestCase):
self.assertTrue(info.is_linux())
self.assertFalse(info.is_mac())
self.assertFalse(info.is_win())
+ self.assertFalse(info.is_freebsd())
info = self.make_info(fake_sys('linux3'))
self.assertTrue(info.is_linux())
self.assertFalse(info.is_mac())
self.assertFalse(info.is_win())
+ self.assertFalse(info.is_freebsd())
info = self.make_info(fake_sys('darwin'), fake_platform('10.6.3'))
self.assertEquals(info.os_name, 'mac')
self.assertFalse(info.is_linux())
self.assertTrue(info.is_mac())
self.assertFalse(info.is_win())
+ self.assertFalse(info.is_freebsd())
info = self.make_info(fake_sys('win32', tuple([6, 1, 7600])))
self.assertEquals(info.os_name, 'win')
self.assertFalse(info.is_linux())
self.assertFalse(info.is_mac())
self.assertTrue(info.is_win())
+ self.assertFalse(info.is_freebsd())
info = self.make_info(fake_sys('cygwin'), executive=fake_executive('6.1.7600'))
self.assertEquals(info.os_name, 'win')
self.assertFalse(info.is_linux())
self.assertFalse(info.is_mac())
self.assertTrue(info.is_win())
+ self.assertFalse(info.is_freebsd())
+
+ info = self.make_info(fake_sys('freebsd8'))
+ self.assertEquals(info.os_name, 'freebsd')
+ self.assertFalse(info.is_linux())
+ self.assertFalse(info.is_mac())
+ self.assertFalse(info.is_win())
+ self.assertTrue(info.is_freebsd())
self.assertRaises(AssertionError, self.make_info, fake_sys('vms'))
@@ -124,6 +139,9 @@ class TestPlatformInfo(unittest.TestCase):
self.assertEquals(self.make_info(fake_sys('linux2')).os_version, 'lucid')
+ self.assertEquals(self.make_info(fake_sys('freebsd8'), fake_platform('', '8.3-PRERELEASE')).os_version, '8.3-PRERELEASE')
+ self.assertEquals(self.make_info(fake_sys('freebsd9'), fake_platform('', '9.0-RELEASE')).os_version, '9.0-RELEASE')
+
self.assertRaises(AssertionError, self.make_info, fake_sys('win32', tuple([5, 0, 1234])))
self.assertEquals(self.make_info(fake_sys('win32', tuple([6, 2, 1234]))).os_version, 'future')
self.assertEquals(self.make_info(fake_sys('win32', tuple([6, 1, 7600]))).os_version, '7sp0')
@@ -146,6 +164,9 @@ class TestPlatformInfo(unittest.TestCase):
info = self.make_info(fake_sys('linux2'))
self.assertNotEquals(info.display_name(), '')
+ info = self.make_info(fake_sys('freebsd9'))
+ self.assertNotEquals(info.display_name(), '')
+
def test_total_bytes_memory(self):
info = self.make_info(fake_sys('darwin'), fake_platform('10.6.3'), fake_executive('1234'))
self.assertEquals(info.total_bytes_memory(), 1234)
@@ -156,6 +177,9 @@ class TestPlatformInfo(unittest.TestCase):
info = self.make_info(fake_sys('linux2'))
self.assertEquals(info.total_bytes_memory(), None)
+ info = self.make_info(fake_sys('freebsd9'))
+ self.assertEquals(info.total_bytes_memory(), None)
+
def test_free_bytes_memory(self):
vmstat_output = ("Mach Virtual Memory Statistics: (page size of 4096 bytes)\n"
"Pages free: 1.\n"
@@ -169,6 +193,9 @@ class TestPlatformInfo(unittest.TestCase):
info = self.make_info(fake_sys('linux2'))
self.assertEquals(info.free_bytes_memory(), None)
+ info = self.make_info(fake_sys('freebsd9'))
+ self.assertEquals(info.free_bytes_memory(), None)
+
if __name__ == '__main__':
unittest.main()
diff --git a/Tools/Scripts/webkitpy/common/system/systemhost_mock.py b/Tools/Scripts/webkitpy/common/system/systemhost_mock.py
index f3bc94139..4667b08b9 100644
--- a/Tools/Scripts/webkitpy/common/system/systemhost_mock.py
+++ b/Tools/Scripts/webkitpy/common/system/systemhost_mock.py
@@ -35,9 +35,9 @@ from webkitpy.common.system.workspace_mock import MockWorkspace
class MockSystemHost(object):
- def __init__(self, log_executive=False, executive_throws_when_run=None, os_name=None, os_version=None):
- self.executive = MockExecutive(should_log=log_executive, should_throw_when_run=executive_throws_when_run)
- self.filesystem = MockFileSystem()
+ def __init__(self, log_executive=False, executive_throws_when_run=None, os_name=None, os_version=None, executive=None, filesystem=None):
+ self.executive = executive or MockExecutive(should_log=log_executive, should_throw_when_run=executive_throws_when_run)
+ self.filesystem = filesystem or MockFileSystem()
self.user = MockUser()
self.platform = MockPlatformInfo()
if os_name:
diff --git a/Tools/Scripts/webkitpy/common/system/user.py b/Tools/Scripts/webkitpy/common/system/user.py
index 31b218c2f..e20405912 100644
--- a/Tools/Scripts/webkitpy/common/system/user.py
+++ b/Tools/Scripts/webkitpy/common/system/user.py
@@ -29,12 +29,16 @@
import getpass
import logging
import os
+import platform
import re
import shlex
import subprocess
import sys
import webbrowser
+from webkitpy.common.system.executive import Executive
+from webkitpy.common.system.platforminfo import PlatformInfo
+
_log = logging.getLogger(__name__)
@@ -45,17 +49,17 @@ except ImportError:
if sys.platform != "win32":
# There is no readline module for win32, not much to do except cry.
_log.warn("Unable to import readline.")
- # FIXME: We could give instructions for non-mac platforms.
- # Lack of readline results in a very bad user experiance.
- if sys.platform == "darwin":
- _log.warn("If you're using MacPorts, try running:")
- _log.warn(" sudo port install py25-readline")
class User(object):
DEFAULT_NO = 'n'
DEFAULT_YES = 'y'
+ def __init__(self, platforminfo=None):
+ # We cannot get the PlatformInfo object from a SystemHost because
+ # User is part of SystemHost itself.
+ self._platforminfo = platforminfo or PlatformInfo(sys, platform, Executive())
+
# FIXME: These are @classmethods because bugzilla.py doesn't have a Tool object (thus no User instance).
@classmethod
def prompt(cls, message, repeat=1, raw_input=raw_input):
@@ -107,7 +111,7 @@ class User(object):
def edit_changelog(self, files):
edit_application = os.environ.get("CHANGE_LOG_EDIT_APPLICATION")
- if edit_application and sys.platform == "darwin":
+ if edit_application and self._platforminfo.is_mac():
# On Mac we support editing ChangeLogs using an application.
args = shlex.split(edit_application)
print "Using editor in the CHANGE_LOG_EDIT_APPLICATION environment variable."