diff options
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r-- | cmd2/cmd2.py | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index c1cebdd2..f46ce496 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -3347,18 +3347,17 @@ class Cmd(cmd.Cmd): for hi in history: self.poutput(hi.pr(script=args.script, expanded=args.expanded, verbose=args.verbose)) - def _generate_transcript(self, history: List[HistoryItem], transcript_file: str) -> None: + def _generate_transcript(self, history: List[Union[HistoryItem, str]], transcript_file: str) -> None: """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 import io + # Disable echo and redirection while we manually redirect stdout to a StringIO buffer + saved_allow_redirection = self.allow_redirection saved_echo = self.echo + saved_stdout = self.stdout + self.allow_redirection = False 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 @@ -3394,10 +3393,10 @@ class Cmd(cmd.Cmd): # and add the regex-escaped output to the transcript transcript += output.replace('/', r'\/') - # Restore stdout to its original state - self.stdout = saved_self_stdout - # Set echo back to its original state + # Restore altered attributes to their original state + self.allow_redirection = saved_allow_redirection self.echo = saved_echo + self.stdout = saved_stdout # finally, we can write the transcript out to the file try: @@ -3453,9 +3452,21 @@ class Cmd(cmd.Cmd): load_description = ("Run commands in script file that is encoded as either ASCII or UTF-8 text\n" "\n" "Script should contain one command per line, just like the command would be\n" - "typed in the console.") + "typed in the console.\n" + "\n" + "It loads commands from a script file into a queue and then the normal cmd2\n" + "REPL resumes control and executes the commands in the queue in FIFO order.\n" + "If you attempt to redirect/pipe a load command, it will capture the output\n" + "of the load command itself, not what it adds to the queue.\n" + "\n" + "If the -r/--record_transcript flag is used, this command instead records\n" + "the output of the script commands to a transcript for testing purposes.\n" + ) load_parser = ACArgumentParser(description=load_description) + setattr(load_parser.add_argument('-r', '--record_transcript', + help='record the output of the script as a transcript file'), + ACTION_ARG_CHOICES, ('path_complete',)) setattr(load_parser.add_argument('script_path', help="path to the script file"), ACTION_ARG_CHOICES, ('path_complete',)) @@ -3489,11 +3500,16 @@ class Cmd(cmd.Cmd): # command queue. Add an "end of script (eos)" command to cleanup the # self._script_dir list when done. with open(expanded_path, encoding='utf-8') as target: - self.cmdqueue = target.read().splitlines() + ['eos'] + self.cmdqueue + script_commands = target.read().splitlines() except OSError as ex: # pragma: no cover self.perror("Problem accessing script from '{}': {}".format(expanded_path, ex)) return + if args.record_transcript: + self._generate_transcript(script_commands, args.record_transcript) + return + + self.cmdqueue = script_commands + ['eos'] + self.cmdqueue self._script_dir.append(os.path.dirname(expanded_path)) relative_load_description = load_description |