Bug 1315785 - Set an environment variable when mach is attached to a TTY; r?glandium draft
authorGregory Szorc <gps@mozilla.com>
Tue, 08 Nov 2016 12:15:13 -0800
changeset 435491 51d7cc8c5521fade2297bceb08cfabcdda7900b4
parent 435490 4f32973b6a7ce8355e467c280790147e4c7bfb82
child 435492 a61a37415e90f13ad79535daab0ea1ea98b1f4a9
push id35066
push userbmo:gps@mozilla.com
push dateTue, 08 Nov 2016 20:22:43 +0000
reviewersglandium
bugs1315785
milestone52.0a1
Bug 1315785 - Set an environment variable when mach is attached to a TTY; r?glandium The way it works now, `mach` commands often invoke subprocesses where the subprocesses' stdio file descriptors are pipes so the mach command can e.g. parse output. Processes like clang, gcc, and cargo determine if they can send color codes to {stderr, stdout} by seeing if those file descriptors are TTYs. When e.g. `make` is executed via `mach`, this test fails because those descriptors are pipes (even though they eventually end up on a TTY). We can't wire the file descriptors to the TTY because `mach` needs to analyze output. We don't want users defining process flags to force color in their mozconfigs because color codes would still be sent if stdout was not a TTY. This patch sets the MACH_STDOUT_ISATTY environment variable in all mach commands when stdout is a TTY. Subsequent processes can then look for this variable to determine whether to override color settings, print terminal control codes, etc. MozReview-Commit-ID: GxXP2mQssjC
python/mach/mach/main.py
--- a/python/mach/mach/main.py
+++ b/python/mach/mach/main.py
@@ -337,16 +337,23 @@ To see more help for a specific command,
                 sys.stdin = codecs.getreader('utf-8')(stdin)
 
             if stdout.encoding is None:
                 sys.stdout = codecs.getwriter('utf-8')(stdout)
 
             if stderr.encoding is None:
                 sys.stderr = codecs.getwriter('utf-8')(stderr)
 
+            # Allow invoked processes (which may not have a handle on the
+            # original stdout file descriptor) to know if the original stdout
+            # is a TTY. This provides a mechanism to allow said processes to
+            # enable emitting code codes, for example.
+            if os.isatty(orig_stdout.fileno()):
+                os.environ[b'MACH_STDOUT_ISATTY'] = b'1'
+
             return self._run(argv)
         except KeyboardInterrupt:
             print('mach interrupted by signal or user action. Stopping.')
             return 1
 
         except Exception as e:
             # _run swallows exceptions in invoked handlers and converts them to
             # a proper exit code. So, the only scenario where we should get an