Chromium Code Reviews| Index: setup_color.py | 
| diff --git a/setup_color.py b/setup_color.py | 
| new file mode 100755 | 
| index 0000000000000000000000000000000000000000..08b9afa47e7fa9f66004581ba2e12cc719a4fa80 | 
| --- /dev/null | 
| +++ b/setup_color.py | 
| @@ -0,0 +1,96 @@ | 
| +#!/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 = True | 
| 
 
dnj
2016/04/03 00:57:45
I feel like this should start False and turn True
 
iannucci
2016/04/04 20:24:59
done
 
 | 
| + 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' | 
| + elif sys.platform.startswith('win'): | 
| + # assume this is some sort of file | 
| + OUT_TYPE = 'file (win)' | 
| + # On windows, things are a bit more nuanced. We start by assuming that it's | 
| + # a pipe. | 
| + | 
| + 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. This case still needs to be wrapped | 
| + # on windows though, because it needs to use SetConsoleTextAttribute to | 
| + # do actual color manipulation. | 
| + OUT_TYPE = 'console (cmd via msys)' | 
| + IS_TTY = 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. | 
| + | 
| + # We don't want to wrap since it's either a real pipe, or an msys pty. | 
| + # Either way it doesn't need SetConsoleTextAttribute. | 
| + should_wrap = False | 
| + | 
| + # This function and the structures are defined in the MSDN documentation | 
| + # using the same names. | 
| + def NT_SUCCESS(status): | 
| + if status >= 0 and status <= 0x3FFFFFFF: | 
| 
 
dnj
2016/04/03 00:57:45
Windows success and information types are contiguo
 
iannucci
2016/04/04 20:24:59
yeah changed and added comment.
 
 | 
| + return True | 
| + if status >= 0x40000000 and status <= 0x7FFFFFFF: | 
| + return True | 
| + return False | 
| + | 
| + 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)): | 
| + # MSYS console, but not an MSYS pipe | 
| + 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 = 'console (msys)' | 
| + else: | 
| + # A normal file, or an unknown file type. | 
| + should_wrap = False | 
| + else: | 
| + # This is non-windows, so we trust isatty. | 
| + OUT_TYPE = 'pipe|file' | 
| + | 
| + colorama.init(wrap=should_wrap) | 
| + | 
| +if __name__ == '__main__': | 
| + init() | 
| + print 'IS_TTY:', IS_TTY | 
| + print 'OUT_TYPE:', OUT_TYPE |