Index: setup_color.py |
diff --git a/setup_color.py b/setup_color.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..5baa8801437706c4a88a202630ec67f2e1242fea |
--- /dev/null |
+++ b/setup_color.py |
@@ -0,0 +1,94 @@ |
+#!/usr/bin/env python |
+# Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import os |
+import sys |
+from third_party import colorama |
+ |
+IS_TTY = None |
+OUT_TYPE = 'unknown' |
+ |
+def init(): |
+ # should_wrap instructs colorama to wrap stdout/stderr with an ASNI colorcode |
+ # interpreter that converts them to SetConsoleTextAttribute calls. This only |
+ # should be True in cases where we're connected to cmd.exe's console. Setting |
+ # this to True on non-windows systems has no effect. |
+ should_wrap = False |
+ global IS_TTY, OUT_TYPE |
+ IS_TTY = sys.stdout.isatty() |
+ if IS_TTY: |
+ # Yay! We detected a console in the normal way. It doesn't really matter |
+ # if it's windows or not, we win. |
+ OUT_TYPE = 'console' |
+ should_wrap = True |
+ elif sys.platform.startswith('win'): |
+ # assume this is some sort of file |
+ OUT_TYPE = 'file (win)' |
+ |
+ import msvcrt |
+ import ctypes |
+ h = msvcrt.get_osfhandle(sys.stdout.fileno()) |
+ # h is the win32 HANDLE for stdout. |
+ ftype = ctypes.windll.kernel32.GetFileType(h) |
+ if ftype == 2: # FILE_TYPE_CHAR |
+ # This is a normal cmd console, but we'll only get here if we're running |
+ # inside a `git command` which is actually git->bash->command. Not sure |
+ # why isatty doesn't detect this case. |
+ OUT_TYPE = 'console (cmd via msys)' |
+ IS_TTY = True |
+ should_wrap = True |
+ elif ftype == 3: # FILE_TYPE_PIPE |
+ OUT_TYPE = 'pipe (win)' |
+ # This is some kind of pipe on windows. This could either be a real pipe |
+ # or this could be msys using a pipe to emulate a pty. We use the same |
+ # algorithm that msys-git uses to determine if it's connected to a pty or |
+ # not. |
+ |
+ # This function and the structures are defined in the MSDN documentation |
+ # using the same names. |
+ def NT_SUCCESS(status): |
+ # The first two bits of status are the severity. The success |
+ # severities are 0 and 1, and the !success severities are 2 and 3. |
+ # Therefore since ctypes interprets the default restype of the call |
+ # to be an 'C int' (which is guaranteed to be signed 32 bits), All |
+ # success codes are positive, and all !success codes are negative. |
+ return status >= 0 |
+ |
+ class UNICODE_STRING(ctypes.Structure): |
+ _fields_ = [('Length', ctypes.c_ushort), |
+ ('MaximumLength', ctypes.c_ushort), |
+ ('Buffer', ctypes.c_wchar_p)] |
+ |
+ class OBJECT_NAME_INFORMATION(ctypes.Structure): |
+ _fields_ = [('Name', UNICODE_STRING), |
+ ('NameBuffer', ctypes.c_wchar_p)] |
+ |
+ buf = ctypes.create_string_buffer('\0', 1024) |
+ # Ask NT what the name of the object our stdout HANDLE is. It would be |
+ # possible to use GetFileInformationByHandleEx, but it's only available |
+ # on Vista+. If you're reading this in 2017 or later, feel free to |
+ # refactor this out. |
+ # |
+ # The '1' here is ObjectNameInformation |
+ if NT_SUCCESS(ctypes.windll.ntdll.NtQueryObject(h, 1, buf, len(buf)-2, |
+ None)): |
+ out = OBJECT_NAME_INFORMATION.from_buffer(buf) |
+ name = out.Name.Buffer.split('\\')[-1] |
+ IS_TTY = name.startswith('msys-') and '-pty' in name |
+ if IS_TTY: |
+ OUT_TYPE = 'bash (msys)' |
+ else: |
+ # A normal file, or an unknown file type. |
+ pass |
+ else: |
+ # This is non-windows, so we trust isatty. |
+ OUT_TYPE = 'pipe or file' |
+ |
+ colorama.init(wrap=should_wrap) |
+ |
+if __name__ == '__main__': |
+ init() |
+ print 'IS_TTY:', IS_TTY |
+ print 'OUT_TYPE:', OUT_TYPE |