summaryrefslogtreecommitdiff
path: root/cmd2/cmd2.py
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2018-05-04 23:24:33 -0400
committerGitHub <noreply@github.com>2018-05-04 23:24:33 -0400
commit132a7882a70b2fc096ac83f072deb8e38bbb21f8 (patch)
tree13a7875528d6b7739fe613459c0b9556eafb7466 /cmd2/cmd2.py
parent92fdf41a594858af942078a850d609b459f56329 (diff)
parentf826598cb303096ab509696b03c8d1d722e3ff25 (diff)
downloadcmd2-git-132a7882a70b2fc096ac83f072deb8e38bbb21f8.tar.gz
Merge pull request #387 from python-cmd2/transcript_tests
Unit test coverage for transcripts from history
Diffstat (limited to 'cmd2/cmd2.py')
-rwxr-xr-xcmd2/cmd2.py91
1 files changed, 63 insertions, 28 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index f4f30bd4..ad2038d4 100755
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -3002,34 +3002,7 @@ a..b, a:b, a:, ..b items by indices (inclusive)
except Exception as e:
self.perror('Saving {!r} - {}'.format(args.output_file, e), traceback_war=False)
elif args.transcript:
- # Make sure echo is on so commands print to standard out
- saved_echo = self.echo
- self.echo = True
-
- # Redirect stdout to the transcript file
- saved_self_stdout = self.stdout
- self.stdout = open(args.transcript, 'w')
-
- # Run all of the commands in the history with output redirected to transcript and echo on
- self.runcmds_plus_hooks(history)
-
- # Restore stdout to its original state
- self.stdout.close()
- self.stdout = saved_self_stdout
-
- # Set echo back to its original state
- self.echo = saved_echo
-
- # Post-process the file to escape un-escaped "/" regex escapes
- with open(args.transcript, 'r') as fin:
- data = fin.read()
- post_processed_data = data.replace('/', '\/')
- with open(args.transcript, 'w') as fout:
- fout.write(post_processed_data)
-
- plural = 's' if len(history) > 1 else ''
- self.pfeedback('{} command{} and outputs saved to transcript file {!r}'.format(len(history), plural,
- args.transcript))
+ self._generate_transcript(history, args.transcript)
else:
# Display the history items retrieved
for hi in history:
@@ -3038,6 +3011,68 @@ a..b, a:b, a:, ..b items by indices (inclusive)
else:
self.poutput(hi.pr())
+ def _generate_transcript(self, history, transcript_file):
+ """Generate a transcript file from a given history of commands."""
+ # Save the current echo state, and turn it off. We inject commands into the
+ # output using a different mechanism
+ saved_echo = self.echo
+ self.echo = False
+
+ # Redirect stdout to the transcript file
+ saved_self_stdout = self.stdout
+
+ # The problem with supporting regular expressions in transcripts
+ # is that they shouldn't be processed in the command, just the output.
+ # In addition, when we generate a transcript, any slashes in the output
+ # are not really intended to indicate regular expressions, so they should
+ # be escaped.
+ #
+ # We have to jump through some hoops here in order to catch the commands
+ # separately from the output and escape the slashes in the output.
+ transcript = ''
+ for history_item in history:
+ # build the command, complete with prompts. When we replay
+ # the transcript, we look for the prompts to separate
+ # the command from the output
+ first = True
+ command = ''
+ for line in history_item.splitlines():
+ if first:
+ command += '{}{}\n'.format(self.prompt, line)
+ first = False
+ else:
+ command += '{}{}\n'.format(self.continuation_prompt, line)
+ transcript += command
+ # create a new string buffer and set it to stdout to catch the output
+ # of the command
+ membuf = io.StringIO()
+ self.stdout = membuf
+ # then run the command and let the output go into our buffer
+ self.onecmd_plus_hooks(history_item)
+ # rewind the buffer to the beginning
+ membuf.seek(0)
+ # get the output out of the buffer
+ output = membuf.read()
+ # and add the regex-escaped output to the transcript
+ transcript += output.replace('/', '\/')
+
+ # Restore stdout to its original state
+ self.stdout = saved_self_stdout
+ # Set echo back to its original state
+ self.echo = saved_echo
+
+ # finally, we can write the transcript out to the file
+ with open(transcript_file, 'w') as fout:
+ fout.write(transcript)
+
+ # and let the user know what we did
+ if len(history) > 1:
+ plural = 'commands and their outputs'
+ else:
+ plural = 'command and its output'
+ msg = '{} {} saved to transcript file {!r}'
+ self.pfeedback(msg.format(len(history), plural, transcript_file))
+
@with_argument_list
def do_edit(self, arglist):
"""Edit a file in a text editor.