1#!/usr/bin/env python3 2 3r""" 4See help text for details (--help or -h option).. 5 6Example properties file content: 7quiet=n 8test_mode=y 9pos=file1 file2 file3 10 11Example call: 12 13prop_call.py --prop_file_name=prop_file my_program 14 15The result is that the following command will be run: 16my_program --test_mode=y --quiet=n file1 file2 file3 17""" 18 19import os 20import sys 21 22save_path_0 = sys.path[0] 23del sys.path[0] 24 25from gen_arg import * # NOQA 26from gen_cmd import * # NOQA 27from gen_misc import * # NOQA 28from gen_print import * # NOQA 29from gen_valid import * # NOQA 30 31# Restore sys.path[0]. 32sys.path.insert(0, save_path_0) 33 34 35parser = argparse.ArgumentParser( 36 usage="%(prog)s [OPTIONS]", 37 description="%(prog)s will call a program using parameters retrieved" 38 + " from the given properties file.", 39 formatter_class=argparse.ArgumentDefaultsHelpFormatter, 40 prefix_chars="-+", 41) 42 43parser.add_argument( 44 "--prop_dir_path", 45 default=os.environ.get("PROP_DIR_PATH", os.getcwd()), 46 help="The path to the directory that contains the properties file." 47 + ' The default value is environment variable "PROP_DIR_PATH", if' 48 + " set. Otherwise, it is the current working directory.", 49) 50 51parser.add_argument( 52 "--prop_file_name", 53 help="The path to a properties file that contains the parameters to" 54 + ' pass to the program. If the properties file has a ".properties"' 55 + " extension, the caller need not specify the extension. The format" 56 + " of each line in the properties file should be as follows:" 57 + " <parm_name=parm_value>. Do not quote the parm value. To specify" 58 + ' positional parms, use a parm name of "pos". For example: pos=this' 59 " value", 60) 61 62parser.add_argument("program_name", help="The name of the program to be run.") 63 64# Populate stock_list with options we want. 65stock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)] 66 67 68def exit_function(signal_number=0, frame=None): 69 r""" 70 Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT). 71 """ 72 73 dprint_executing() 74 dprint_var(signal_number) 75 76 qprint_pgm_footer() 77 78 79def signal_handler(signal_number, frame): 80 r""" 81 Handle signals. Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately 82 with return code 143 and without calling our exit_function. 83 """ 84 85 # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly 86 # call exit_function from here. 87 88 dprint_executing() 89 90 # Calling exit prevents us from returning to the code that was running when we received the signal. 91 exit(0) 92 93 94def validate_parms(): 95 r""" 96 Validate program parameters, etc. Return True or False (i.e. pass/fail) accordingly. 97 """ 98 99 global prop_dir_path 100 global prop_file_path 101 102 if not valid_dir_path(prop_dir_path): 103 return False 104 prop_dir_path = add_trailing_slash(prop_dir_path) 105 106 if not valid_value(prop_file_name): 107 return False 108 109 prop_file_path = prop_dir_path + prop_file_name 110 111 # If properties file is not found, try adding ".properties" extension. 112 if not os.path.isfile(prop_file_path): 113 alt_prop_file_path = prop_file_path + ".properties" 114 if os.path.isfile(alt_prop_file_path): 115 prop_file_path = alt_prop_file_path 116 117 if not valid_file_path(prop_file_path): 118 return False 119 120 if not valid_value(program_name): 121 return False 122 123 gen_post_validation(exit_function, signal_handler) 124 125 return True 126 127 128def main(): 129 if not gen_get_options(parser, stock_list): 130 return False 131 132 if not validate_parms(): 133 return False 134 135 qprint_pgm_header() 136 137 # Get the parameters from the properties file. 138 properties = my_parm_file(prop_file_path) 139 # The parms (including program name) need to go into a list. 140 parms = [program_name] 141 for key, value in properties.items(): 142 if key == "pos": 143 # Process positional parm(s). 144 parms.extend(value.split()) 145 else: 146 parms.append("--" + key + "=" + escape_bash_quotes(value)) 147 148 # parm_string is only created for display in non-quiet mode. 149 parm_string = " ".join(parms[1:]) 150 cmd_buf = program_name + " " + parm_string 151 qprint_issuing(cmd_buf) 152 if not test_mode: 153 os.execvp(program_name, parms) 154 155 return True 156 157 158# Main 159 160if not main(): 161 exit(1) 162