6
6
were using the standard library's cmd, while enjoying the extra features.
7
7
8
8
Searchable command history (commands: "history")
9
- Load commands from file, save to file, edit commands in file
9
+ Run commands from file, save to file, edit commands in file
10
10
Multi-line commands
11
- Special-character shortcut commands (beyond cmd's "@ " and "!")
11
+ Special-character shortcut commands (beyond cmd's "? " and "!")
12
12
Settable environment parameters
13
13
Parsing commands with `argparse` argument parsers (flags)
14
14
Redirection to file or paste buffer (clipboard) with > or >>
@@ -327,7 +327,7 @@ class Cmd(cmd.Cmd):
327
327
328
328
Line-oriented command interpreters are often useful for test harnesses, internal tools, and rapid prototypes.
329
329
"""
330
- DEFAULT_SHORTCUTS = {'?' : 'help' , '!' : 'shell' , '@' : 'load ' , '@@' : '_relative_load ' }
330
+ DEFAULT_SHORTCUTS = {'?' : 'help' , '!' : 'shell' , '@' : 'run_script ' , '@@' : '_relative_run_script ' }
331
331
DEFAULT_EDITOR = utils .find_editor ()
332
332
333
333
def __init__ (self , completekey : str = 'tab' , stdin = None , stdout = None , * ,
@@ -343,7 +343,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
343
343
:param stdout: (optional) alternate output file object, if not specified, sys.stdout is used
344
344
:param persistent_history_file: (optional) file path to load a persistent cmd2 command history from
345
345
:param persistent_history_length: (optional) max number of history items to write to the persistent history file
346
- :param startup_script: (optional) file path to a a script to load and execute at startup
346
+ :param startup_script: (optional) file path to a script to execute at startup
347
347
:param use_ipython: (optional) should the "ipy" command be included for an embedded IPython shell
348
348
:param allow_cli_args: (optional) if True, then cmd2 will process command line arguments as either
349
349
commands to be run or, if -t is specified, transcript files to run.
@@ -398,7 +398,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
398
398
'timing' : 'Report execution times' }
399
399
400
400
# Commands to exclude from the help menu and tab completion
401
- self .hidden_commands = ['eof' , '_relative_load' ]
401
+ self .hidden_commands = ['eof' , '_relative_load' , '_relative_run_script' ]
402
402
403
403
# Commands to exclude from the history command
404
404
# initialize history
@@ -429,7 +429,7 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
429
429
# Built-in commands don't make use of this. It is purely there for user-defined commands and convenience.
430
430
self ._last_result = None
431
431
432
- # Used load command to store the current script dir as a LIFO queue to support _relative_load command
432
+ # Used by run_script command to store current script dir as a LIFO queue to support _relative_run_script command
433
433
self ._script_dir = []
434
434
435
435
# Context manager used to protect critical sections in the main thread from stopping due to a KeyboardInterrupt
@@ -460,11 +460,11 @@ def __init__(self, completekey: str = 'tab', stdin=None, stdout=None, *,
460
460
# Commands that will run at the beginning of the command loop
461
461
self ._startup_commands = []
462
462
463
- # If a startup script is provided, then add it in the queue to load
463
+ # If a startup script is provided, then execute it in the startup commands
464
464
if startup_script is not None :
465
465
startup_script = os .path .abspath (os .path .expanduser (startup_script ))
466
466
if os .path .exists (startup_script ) and os .path .getsize (startup_script ) > 0 :
467
- self ._startup_commands .append ("load '{}'" .format (startup_script ))
467
+ self ._startup_commands .append ("run_script '{}'" .format (startup_script ))
468
468
469
469
# Transcript files to run instead of interactive command loop
470
470
self ._transcript_files = None
@@ -3240,15 +3240,15 @@ def py_quit():
3240
3240
3241
3241
return bridge .stop
3242
3242
3243
- pyscript_parser = ACArgumentParser ()
3244
- setattr (pyscript_parser .add_argument ('script_path' , help = 'path to the script file' ),
3243
+ run_pyscript_parser = ACArgumentParser ()
3244
+ setattr (run_pyscript_parser .add_argument ('script_path' , help = 'path to the script file' ),
3245
3245
ACTION_ARG_CHOICES , ('path_complete' ,))
3246
- setattr (pyscript_parser .add_argument ('script_arguments' , nargs = argparse .REMAINDER ,
3247
- help = 'arguments to pass to script' ),
3246
+ setattr (run_pyscript_parser .add_argument ('script_arguments' , nargs = argparse .REMAINDER ,
3247
+ help = 'arguments to pass to script' ),
3248
3248
ACTION_ARG_CHOICES , ('path_complete' ,))
3249
3249
3250
- @with_argparser (pyscript_parser )
3251
- def do_pyscript (self , args : argparse .Namespace ) -> bool :
3250
+ @with_argparser (run_pyscript_parser )
3251
+ def do_run_pyscript (self , args : argparse .Namespace ) -> bool :
3252
3252
"""Run a Python script file inside the console"""
3253
3253
script_path = os .path .expanduser (args .script_path )
3254
3254
py_return = False
@@ -3270,9 +3270,16 @@ def do_pyscript(self, args: argparse.Namespace) -> bool:
3270
3270
finally :
3271
3271
# Restore command line arguments to original state
3272
3272
sys .argv = orig_args
3273
+ if args .__statement__ .command == "pyscript" :
3274
+ self .perror ("pyscript has been renamed and will be removed in the next release, "
3275
+ "please use run_pyscript instead\n " ,
3276
+ traceback_war = False , err_color = Fore .LIGHTYELLOW_EX )
3273
3277
3274
3278
return py_return
3275
3279
3280
+ # pyscript is deprecated
3281
+ do_pyscript = do_run_pyscript
3282
+
3276
3283
# Only include the do_ipy() method if IPython is available on the system
3277
3284
if ipython_available : # pragma: no cover
3278
3285
@with_argparser (ACArgumentParser ())
@@ -3412,7 +3419,7 @@ def do_history(self, args: argparse.Namespace) -> Optional[bool]:
3412
3419
fobj .write ('{}\n ' .format (command .raw ))
3413
3420
try :
3414
3421
self .do_edit (fname )
3415
- return self .do_load (fname )
3422
+ return self .do_run_script (fname )
3416
3423
finally :
3417
3424
os .remove (fname )
3418
3425
elif args .output_file :
@@ -3623,94 +3630,115 @@ def _current_script_dir(self) -> Optional[str]:
3623
3630
else :
3624
3631
return None
3625
3632
3626
- load_description = ("Run commands in script file that is encoded as either ASCII or UTF-8 text\n "
3627
- "\n "
3628
- "Script should contain one command per line, just like the command would be\n "
3629
- "typed in the console.\n "
3630
- "\n "
3631
- "If the -r/--record_transcript flag is used, this command instead records\n "
3632
- "the output of the script commands to a transcript for testing purposes.\n "
3633
- )
3633
+ run_script_description = ("Run commands in script file that is encoded as either ASCII or UTF-8 text\n "
3634
+ "\n "
3635
+ "Script should contain one command per line, just like the command would be\n "
3636
+ "typed in the console.\n "
3637
+ "\n "
3638
+ "If the -r/--record_transcript flag is used, this command instead records\n "
3639
+ "the output of the script commands to a transcript for testing purposes.\n "
3640
+ )
3634
3641
3635
- load_parser = ACArgumentParser (description = load_description )
3636
- setattr (load_parser .add_argument ('-t' , '--transcript' , help = 'record the output of the script as a transcript file' ),
3642
+ run_script_parser = ACArgumentParser (description = run_script_description )
3643
+ setattr (run_script_parser .add_argument ('-t' , '--transcript' ,
3644
+ help = 'record the output of the script as a transcript file' ),
3637
3645
ACTION_ARG_CHOICES , ('path_complete' ,))
3638
- setattr (load_parser .add_argument ('script_path' , help = "path to the script file" ),
3646
+ setattr (run_script_parser .add_argument ('script_path' , help = "path to the script file" ),
3639
3647
ACTION_ARG_CHOICES , ('path_complete' ,))
3640
3648
3641
- @with_argparser (load_parser )
3642
- def do_load (self , args : argparse .Namespace ) -> Optional [bool ]:
3649
+ @with_argparser (run_script_parser )
3650
+ def do_run_script (self , args : argparse .Namespace ) -> Optional [bool ]:
3643
3651
"""
3644
3652
Run commands in script file that is encoded as either ASCII or UTF-8 text
3645
3653
:return: True if running of commands should stop
3646
3654
"""
3647
3655
expanded_path = os .path .abspath (os .path .expanduser (args .script_path ))
3648
3656
3649
- # Make sure the path exists and we can access it
3650
- if not os .path .exists (expanded_path ):
3651
- self .perror ("'{}' does not exist or cannot be accessed" .format (expanded_path ), traceback_war = False )
3652
- return
3657
+ # Wrap everything in a try/finally just to make sure the warning prints at end if `load` was called
3658
+ try :
3659
+ # Make sure the path exists and we can access it
3660
+ if not os .path .exists (expanded_path ):
3661
+ self .perror ("'{}' does not exist or cannot be accessed" .format (expanded_path ), traceback_war = False )
3662
+ return
3653
3663
3654
- # Make sure expanded_path points to a file
3655
- if not os .path .isfile (expanded_path ):
3656
- self .perror ("'{}' is not a file" .format (expanded_path ), traceback_war = False )
3657
- return
3664
+ # Make sure expanded_path points to a file
3665
+ if not os .path .isfile (expanded_path ):
3666
+ self .perror ("'{}' is not a file" .format (expanded_path ), traceback_war = False )
3667
+ return
3658
3668
3659
- # Make sure the file is not empty
3660
- if os .path .getsize (expanded_path ) == 0 :
3661
- self .perror ("'{}' is empty" .format (expanded_path ), traceback_war = False )
3662
- return
3669
+ # Make sure the file is not empty
3670
+ if os .path .getsize (expanded_path ) == 0 :
3671
+ self .perror ("'{}' is empty" .format (expanded_path ), traceback_war = False )
3672
+ return
3663
3673
3664
- # Make sure the file is ASCII or UTF-8 encoded text
3665
- if not utils .is_text_file (expanded_path ):
3666
- self .perror ("'{}' is not an ASCII or UTF-8 encoded text file" .format (expanded_path ), traceback_war = False )
3667
- return
3674
+ # Make sure the file is ASCII or UTF-8 encoded text
3675
+ if not utils .is_text_file (expanded_path ):
3676
+ self .perror ("'{}' is not an ASCII or UTF-8 encoded text file" .format (expanded_path ), traceback_war = False )
3677
+ return
3668
3678
3669
- try :
3670
- # Read all lines of the script
3671
- with open (expanded_path , encoding = 'utf-8' ) as target :
3672
- script_commands = target .read ().splitlines ()
3673
- except OSError as ex : # pragma: no cover
3674
- self .perror ("Problem accessing script from '{}': {}" .format (expanded_path , ex ))
3675
- return
3679
+ try :
3680
+ # Read all lines of the script
3681
+ with open (expanded_path , encoding = 'utf-8' ) as target :
3682
+ script_commands = target .read ().splitlines ()
3683
+ except OSError as ex : # pragma: no cover
3684
+ self .perror ("Problem accessing script from '{}': {}" .format (expanded_path , ex ))
3685
+ return
3676
3686
3677
- orig_script_dir_count = len (self ._script_dir )
3687
+ orig_script_dir_count = len (self ._script_dir )
3678
3688
3679
- try :
3680
- self ._script_dir .append (os .path .dirname (expanded_path ))
3689
+ try :
3690
+ self ._script_dir .append (os .path .dirname (expanded_path ))
3681
3691
3682
- if args .transcript :
3683
- self ._generate_transcript (script_commands , os .path .expanduser (args .transcript ))
3684
- else :
3685
- return self .runcmds_plus_hooks (script_commands )
3692
+ if args .transcript :
3693
+ self ._generate_transcript (script_commands , os .path .expanduser (args .transcript ))
3694
+ else :
3695
+ return self .runcmds_plus_hooks (script_commands )
3686
3696
3697
+ finally :
3698
+ with self .sigint_protection :
3699
+ # Check if a script dir was added before an exception occurred
3700
+ if orig_script_dir_count != len (self ._script_dir ):
3701
+ self ._script_dir .pop ()
3687
3702
finally :
3688
- with self . sigint_protection :
3689
- # Check if a script dir was added before an exception occurred
3690
- if orig_script_dir_count != len ( self . _script_dir ):
3691
- self . _script_dir . pop ( )
3703
+ if args . __statement__ . command == "load" :
3704
+ self . perror ( "load has been renamed and will be removed in the next release, "
3705
+ "please use run_script instead \n " ,
3706
+ traceback_war = False , err_color = Fore . LIGHTYELLOW_EX )
3692
3707
3693
- relative_load_description = load_description
3694
- relative_load_description += ("\n \n "
3695
- "If this is called from within an already-running script, the filename will be\n "
3696
- "interpreted relative to the already-running script's directory." )
3708
+ # load has been deprecated
3709
+ do_load = do_run_script
3697
3710
3698
- relative_load_epilog = ("Notes:\n "
3699
- " This command is intended to only be used within text file scripts." )
3711
+ relative_run_script_description = run_script_description
3712
+ relative_run_script_description += (
3713
+ "\n \n "
3714
+ "If this is called from within an already-running script, the filename will be\n "
3715
+ "interpreted relative to the already-running script's directory." )
3700
3716
3701
- relative_load_parser = ACArgumentParser ( description = relative_load_description , epilog = relative_load_epilog )
3702
- relative_load_parser . add_argument ( 'file_path' , help = 'a file path pointing to a script' )
3717
+ relative_run_script_epilog = ( "Notes: \n "
3718
+ " This command is intended to only be used within text file scripts." )
3703
3719
3704
- @with_argparser (relative_load_parser )
3705
- def do__relative_load (self , args : argparse .Namespace ) -> Optional [bool ]:
3720
+ relative_run_script_parser = ACArgumentParser (description = relative_run_script_description ,
3721
+ epilog = relative_run_script_epilog )
3722
+ relative_run_script_parser .add_argument ('file_path' , help = 'a file path pointing to a script' )
3723
+
3724
+ @with_argparser (relative_run_script_parser )
3725
+ def do__relative_run_script (self , args : argparse .Namespace ) -> Optional [bool ]:
3706
3726
"""
3707
3727
Run commands in script file that is encoded as either ASCII or UTF-8 text
3708
3728
:return: True if running of commands should stop
3709
3729
"""
3730
+ if args .__statement__ .command == "_relative_load" :
3731
+ self .perror ("_relative_load has been renamed and will be removed in the next release, "
3732
+ "please use _relative_run_script instead\n " ,
3733
+ traceback_war = False , err_color = Fore .LIGHTYELLOW_EX )
3734
+
3710
3735
file_path = args .file_path
3711
3736
# NOTE: Relative path is an absolute path, it is just relative to the current script directory
3712
3737
relative_path = os .path .join (self ._current_script_dir or '' , file_path )
3713
- return self .do_load (relative_path )
3738
+ return self .do_run_script (relative_path )
3739
+
3740
+ # _relative_load has been deprecated
3741
+ do__relative_load = do__relative_run_script
3714
3742
3715
3743
def run_transcript_tests (self , transcript_paths : List [str ]) -> None :
3716
3744
"""Runs transcript tests for provided file(s).
0 commit comments