From 1cae2ef7ad302c1da6f17ee3c632800e69ae6a8a Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 2 Jan 2015 10:58:07 +0000 Subject: Fix logging and display of commandlines being executed by Morph We were attempting to display commandlines with correct shell-escaping, but the logic was super broken so users would end up seeing this sort of thing instead: 2015-01-02 10:25:42 # g | i | t | | r | e | v | - | p | a | r | s | e | | - | - | v | e | r | i | f | y | | ' | 9 | 8 | f | e | a | 8 | 7 | b | 7 | 2 | 7 | 2 | 5 | 3 | e | 7 | f | f | 8 | 1 | 0 | 5 | 4 | 3 | 4 | c | 9 | e | a | 9 | 0 | 2 | b | b | 6 | a | 6 | f | 7 | e | ^ | { | c | o | m | m | i | t | } | ' Commandlines should now display as intended, more like this: 2015-01-02 10:57:17 # git rev-parse --verify '9df9643842e4b4d8ece710fe6105f32fa38a0d22^{commit}' This broken logic was introduced as a post-review fixup in merge commit c57952ef44a0f1f161441970fcf2f27a39b0de7c. --- morphlib/app.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/morphlib/app.py b/morphlib/app.py index eb0ff3b7..6710e4f0 100644 --- a/morphlib/app.py +++ b/morphlib/app.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2014 Codethink Limited +# Copyright (C) 2011-2015 Codethink Limited # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -361,12 +361,13 @@ class Morph(cliapp.Application): if print_command: # Print the command line - commands = [argv] + list(args) - for command in commands: + commands = [] + for command in [argv] + list(args): if isinstance(command, list): - for i in xrange(0, len(command)): - command[i] = str(command[i]) - commands = ' '.join(map(pipes.quote, command)) + command_str = ' '.join(map(pipes.quote, command)) + else: + command_str = pipes.quote(command) + commands.append(command_str) self.status(msg='# %(cmdline)s', cmdline=' | '.join(commands), -- cgit v1.2.1 From 6f5c4a44a124e018982cffe06fd10e93ea65f446 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Fri, 2 Jan 2015 10:53:11 +0000 Subject: Improve logic for displaying command execution to user This avoids writing each command to the log file twice, as we did previously. Also, the user-visible message is now only constructed if we are definitely going to write it to the screen (a tiny optimisation). Hopefully the logic is clearer now too. --- morphlib/app.py | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/morphlib/app.py b/morphlib/app.py index 6710e4f0..177bce45 100644 --- a/morphlib/app.py +++ b/morphlib/app.py @@ -309,6 +309,11 @@ class Morph(cliapp.Application): if (submod.url, submod.commit) not in done: subs_to_process.add((submod.url, submod.commit)) + def _write_status(self, text): + timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) + self.output.write('%s %s\n' % (timestamp, text)) + self.output.flush() + def status(self, **kwargs): '''Show user a status update. @@ -345,9 +350,20 @@ class Morph(cliapp.Application): ok = verbose or error or (not quiet and not chatty) if ok: - timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) - self.output.write('%s %s\n' % (timestamp, text)) - self.output.flush() + self._write_status(text) + + def _commandline_as_message(self, argv, args): + '''Create a status string for a command that's about to be executed.''' + + commands = [] + for command in [argv] + list(args): + if isinstance(command, list): + command_str = ' '.join(map(pipes.quote, command)) + else: + command_str = pipes.quote(command) + commands.append(command_str) + + return '# ' + ' | '.join(commands) def _prepare_for_runcmd(self, argv, args, kwargs): if 'env' not in kwargs: @@ -359,19 +375,11 @@ class Morph(cliapp.Application): else: print_command = True - if print_command: - # Print the command line - commands = [] - for command in [argv] + list(args): - if isinstance(command, list): - command_str = ' '.join(map(pipes.quote, command)) - else: - command_str = pipes.quote(command) - commands.append(command_str) - - self.status(msg='# %(cmdline)s', - cmdline=' | '.join(commands), - chatty=True) + if print_command and self.settings['verbose']: + # Don't call self.status() here, to avoid writing the message to + # the log as well as to the console. The cliapp.runcmd() function + # will also log the command, and it's messy having it logged twice. + self._write_status(self._commandline_as_message(argv, args)) # Log the environment. prev = getattr(self, 'prev_env', {}) -- cgit v1.2.1