diff --git a/ush/bash_utils/check_for_preexist_dir_file.sh b/ush/bash_utils/check_for_preexist_dir_file.sh index 53dab67588..4ca55766d2 100644 --- a/ush/bash_utils/check_for_preexist_dir_file.sh +++ b/ush/bash_utils/check_for_preexist_dir_file.sh @@ -63,7 +63,7 @@ where the arguments are defined as follows: method: String specifying the action to take if a preexisting version of - dir_or_file is found. Valid values are \"delete\", \"rename\", and \"quit\". + dir_or_file is found. Valid values are \"delete\", \"reuse\", \"rename\", and \"quit\". " fi @@ -84,7 +84,7 @@ where the arguments are defined as follows: # #----------------------------------------------------------------------- # - local valid_vals_method=( "delete" "rename" "quit" ) + local valid_vals_method=( "delete" "reuse" "rename" "quit" ) check_var_valid_value "method" "valid_vals_method" # #----------------------------------------------------------------------- @@ -139,6 +139,15 @@ Moving (renaming) preexisting directory or file to: # #----------------------------------------------------------------------- # +# If method is set to "reuse", keep preexisting directory intact. +# +#----------------------------------------------------------------------- +# + "reuse") + ;; +# +#----------------------------------------------------------------------- +# # If method is set to "quit", we simply exit with a nonzero status. Note # that "exit" is different than "return" because it will cause the calling # script (in which this file/function is sourced) to stop execution. diff --git a/ush/config_defaults.yaml b/ush/config_defaults.yaml index 0a9c48e1c7..80f28ace18 100644 --- a/ush/config_defaults.yaml +++ b/ush/config_defaults.yaml @@ -836,7 +836,7 @@ workflow: # use to deal with preexisting directories [e.g ones generated by previous # calls to the experiment generation script using the same experiment name # (EXPT_SUBDIR) as the current experiment]. This variable must be set to - # one of "delete", "rename", and "quit". The resulting behavior for each + # one of "delete", "reuse", "rename", and "quit". The resulting behavior for each # of these values is as follows: # # * "delete": @@ -850,6 +850,22 @@ workflow: # the suffix "_oldNNN", where NNN is a 3-digit integer chosen to make # the new name unique. # + # * "reuse": + # If method is set to "reuse", + # keep preexisting directory intact except that + # when preexisting directory is $EXPDIR, do the following: + # save all old files to a subdirecotry oldxxx/ and then + # populate new files into the $EXPDIR directory + # This is useful to keep ongoing runs uninterrupted: + # rocotoco *db files and previous cycles will stay and hence + # 1. no need to manually cp/mv *db files and previous cycles back + # 2. no need to manually restart related rocoto tasks failed during + # the workflow generation process + # This may best suit for incremental system reuses. + # + # Alternatively, one can always elect to use the "rename" option + # and then manually do the above aftermath + # # * "quit": # The preexisting directory is left unchanged, but execution of the # currently running script is terminated. In this case, the preexisting diff --git a/ush/python_utils/check_for_preexist_dir_file.py b/ush/python_utils/check_for_preexist_dir_file.py index 39ad7f1706..79666f8288 100644 --- a/ush/python_utils/check_for_preexist_dir_file.py +++ b/ush/python_utils/check_for_preexist_dir_file.py @@ -4,7 +4,7 @@ from datetime import datetime from textwrap import dedent from .check_var_valid_value import check_var_valid_value -from .filesys_cmds_vrfy import rm_vrfy, mv_vrfy +from .filesys_cmds_vrfy import rm_vrfy, mv_vrfy, rsync_vrfy from .print_msg import log_info @@ -14,13 +14,13 @@ def check_for_preexist_dir_file(path, method): Args: path: path to directory - method: could be any of [ 'delete', 'rename', 'quit' ] + method: could be any of [ 'delete', 'reuse', 'rename', 'quit' ] Returns: None """ try: - check_var_valid_value(method, ["delete", "rename", "quit"]) + check_var_valid_value(method, ["delete", "reuse", "rename", "quit"]) except ValueError: errmsg = dedent( f""" @@ -33,7 +33,7 @@ def check_for_preexist_dir_file(path, method): if os.path.exists(path): if method == "delete": rm_vrfy(" -rf ", path) - elif method == "rename": + elif method == "rename" or method == "reuse": now = datetime.now() d = now.strftime("_old_%Y%m%d_%H%M%S") new_path = path + d @@ -44,7 +44,10 @@ def check_for_preexist_dir_file(path, method): Moving (renaming) preexisting directory or file to: {new_path}""" ) - mv_vrfy(path, new_path) + if method == "rename": + mv_vrfy(path, new_path) + else: + rsync_vrfy(path, new_path) else: raise FileExistsError( dedent( diff --git a/ush/python_utils/filesys_cmds_vrfy.py b/ush/python_utils/filesys_cmds_vrfy.py index d99b97c7f2..ca986f9693 100644 --- a/ush/python_utils/filesys_cmds_vrfy.py +++ b/ush/python_utils/filesys_cmds_vrfy.py @@ -25,6 +25,10 @@ def cp_vrfy(*args): return cmd_vrfy("cp", *args) +def rsync_vrfy(*args): + return cmd_vrfy("rsync", *args) + + def mv_vrfy(*args): return cmd_vrfy("mv", *args)