mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1748070 - rewrote show_log
to resolve various bugs on Windows (While still maintaining current behavior on POSIX systems) r=firefox-build-system-reviewers,glandium,mhentges
- Changed byte strings being set in env to just strings as byte strings were only necessaery in Python2 and strings work fine in POSIX and Windows as of Python3. (Byte strings no longer work on Windows in Python3) - Replaced all the file descriptor logic used to pipe to `less` with more Pythonic stream manipulation. (There was a change in Windows console IO in Python 3.6 that broke the file descriptor logic we were using here) See: https://www.python.org/dev/peps/pep-0528/#add-io-windowsconsoleio Differential Revision: https://phabricator.services.mozilla.com/D135969
This commit is contained in:
parent
bc10b96605
commit
5b1ec638ce
@ -343,7 +343,11 @@ def clobber(command_context, what, full=False):
|
||||
"mach command.",
|
||||
)
|
||||
def show_log(command_context, log_file=None):
|
||||
"""Show mach logs."""
|
||||
"""Show mach logs
|
||||
If we're in a terminal context, the log is piped to 'less'
|
||||
for more convenient viewing.
|
||||
(https://man7.org/linux/man-pages/man1/less.1.html)
|
||||
"""
|
||||
if not log_file:
|
||||
path = command_context._get_state_filename("last_log.json")
|
||||
log_file = open(path, "rb")
|
||||
@ -351,22 +355,46 @@ def show_log(command_context, log_file=None):
|
||||
if os.isatty(sys.stdout.fileno()):
|
||||
env = dict(os.environ)
|
||||
if "LESS" not in env:
|
||||
# Sensible default flags if none have been set in the user
|
||||
# environment.
|
||||
env[b"LESS"] = b"FRX"
|
||||
less = subprocess.Popen(["less"], stdin=subprocess.PIPE, env=env)
|
||||
# Various objects already have a reference to sys.stdout, so we
|
||||
# can't just change it, we need to change the file descriptor under
|
||||
# it to redirect to less's input.
|
||||
# First keep a copy of the sys.stdout file descriptor.
|
||||
output_fd = os.dup(sys.stdout.fileno())
|
||||
os.dup2(less.stdin.fileno(), sys.stdout.fileno())
|
||||
# Sensible default flags if none have been set in the user environment.
|
||||
env["LESS"] = "FRX"
|
||||
less = subprocess.Popen(
|
||||
["less"], stdin=subprocess.PIPE, env=env, encoding="UTF-8"
|
||||
)
|
||||
|
||||
startTime = 0
|
||||
# Create a new logger handler with the stream being the stdin of our 'less'
|
||||
# process so that we can pipe the logger output into 'less'
|
||||
less_handler = logging.StreamHandler(stream=less.stdin)
|
||||
less_handler.setFormatter(
|
||||
command_context.log_manager.terminal_handler.formatter
|
||||
)
|
||||
less_handler.setLevel(command_context.log_manager.terminal_handler.level)
|
||||
|
||||
# replace the existing terminal handler with the new one for 'less' while
|
||||
# still keeping the original one to set back later
|
||||
original_handler = command_context.log_manager.replace_terminal_handler(
|
||||
less_handler
|
||||
)
|
||||
|
||||
# Parses the log file line by line and streams (to less.stdin) the relevant records we want
|
||||
handle_log_file(command_context, log_file)
|
||||
|
||||
# Set the handler (and contained stream) back to the original one
|
||||
command_context.log_manager.replace_terminal_handler(original_handler)
|
||||
|
||||
# At this point we've piped the entire log file to 'less', so we can close the input stream
|
||||
less.stdin.close()
|
||||
# Wait for the user to manually terminate `less`
|
||||
less.wait()
|
||||
else:
|
||||
handle_log_file(command_context, log_file)
|
||||
|
||||
|
||||
def handle_log_file(command_context, log_file):
|
||||
start_time = 0
|
||||
for line in log_file:
|
||||
created, action, params = json.loads(line)
|
||||
if not startTime:
|
||||
startTime = created
|
||||
if not start_time:
|
||||
start_time = created
|
||||
command_context.log_manager.terminal_handler.formatter.start_time = created
|
||||
if "line" in params:
|
||||
record = logging.makeLogRecord(
|
||||
@ -381,17 +409,6 @@ def show_log(command_context, log_file=None):
|
||||
)
|
||||
command_context._logger.handle(record)
|
||||
|
||||
if command_context.log_manager.terminal:
|
||||
# Close less's input so that it knows that we're done sending data.
|
||||
less.stdin.close()
|
||||
# Since the less's input file descriptor is now also the stdout
|
||||
# file descriptor, we still actually have a non-closed system file
|
||||
# descriptor for less's input. Replacing sys.stdout's file
|
||||
# descriptor with what it was before we replaced it will properly
|
||||
# close less's input.
|
||||
os.dup2(output_fd, sys.stdout.fileno())
|
||||
less.wait()
|
||||
|
||||
|
||||
# Provide commands for inspecting warnings.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user