1*e7e9171eSGeorge Keishing#!/usr/bin/env python3 221791604SMichael Walsh 321791604SMichael Walshr""" 421791604SMichael WalshSee help text for details (--help or -h option).. 521791604SMichael Walsh 621791604SMichael WalshExample properties file content: 721791604SMichael Walshquiet=n 821791604SMichael Walshtest_mode=y 921791604SMichael Walshpos=file1 file2 file3 1021791604SMichael Walsh 1121791604SMichael WalshExample call: 1221791604SMichael Walsh 1321791604SMichael Walshprop_call.py --prop_file_name=prop_file my_program 1421791604SMichael Walsh 1521791604SMichael WalshThe result is that the following command will be run: 1621791604SMichael Walshmy_program --test_mode=y --quiet=n file1 file2 file3 1721791604SMichael Walsh""" 1821791604SMichael Walsh 1921791604SMichael Walshimport sys 2021791604SMichael Walshimport os 2121791604SMichael Walsh 2221791604SMichael Walshsave_path_0 = sys.path[0] 2321791604SMichael Walshdel sys.path[0] 2421791604SMichael Walsh 2521791604SMichael Walshfrom gen_arg import * 2621791604SMichael Walshfrom gen_print import * 2721791604SMichael Walshfrom gen_valid import * 2821791604SMichael Walshfrom gen_misc import * 2921791604SMichael Walshfrom gen_cmd import * 3021791604SMichael Walsh 3121791604SMichael Walsh# Restore sys.path[0]. 3221791604SMichael Walshsys.path.insert(0, save_path_0) 3321791604SMichael Walsh 3421791604SMichael Walsh 3521791604SMichael Walshparser = argparse.ArgumentParser( 3621791604SMichael Walsh usage='%(prog)s [OPTIONS]', 37004ad3c9SJoy Onyerikwu description="%(prog)s will call a program using parameters retrieved" 38004ad3c9SJoy Onyerikwu + " from the given properties file.", 3921791604SMichael Walsh formatter_class=argparse.ArgumentDefaultsHelpFormatter, 4021791604SMichael Walsh prefix_chars='-+') 4121791604SMichael Walsh 4221791604SMichael Walshparser.add_argument( 4321791604SMichael Walsh '--prop_dir_path', 4421791604SMichael Walsh default=os.environ.get("PROP_DIR_PATH", os.getcwd()), 45004ad3c9SJoy Onyerikwu help='The path to the directory that contains the properties file.' 46004ad3c9SJoy Onyerikwu + ' The default value is environment variable "PROP_DIR_PATH", if' 47004ad3c9SJoy Onyerikwu + ' set. Otherwise, it is the current working directory.') 4821791604SMichael Walsh 4921791604SMichael Walshparser.add_argument( 5021791604SMichael Walsh '--prop_file_name', 51004ad3c9SJoy Onyerikwu help='The path to a properties file that contains the parameters to' 52004ad3c9SJoy Onyerikwu + ' pass to the program. If the properties file has a ".properties"' 53004ad3c9SJoy Onyerikwu + ' extension, the caller need not specify the extension. The format' 54004ad3c9SJoy Onyerikwu + ' of each line in the properties file should be as follows:' 55004ad3c9SJoy Onyerikwu + ' <parm_name=parm_value>. Do not quote the parm value. To specify' 56004ad3c9SJoy Onyerikwu + ' positional parms, use a parm name of "pos". For example: pos=this' 5721791604SMichael Walsh ' value') 5821791604SMichael Walsh 5921791604SMichael Walshparser.add_argument( 6021791604SMichael Walsh 'program_name', 6121791604SMichael Walsh help='The name of the program to be run.') 6221791604SMichael Walsh 6321791604SMichael Walsh# Populate stock_list with options we want. 6421791604SMichael Walshstock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)] 6521791604SMichael Walsh 6621791604SMichael Walsh 6721791604SMichael Walshdef exit_function(signal_number=0, 6821791604SMichael Walsh frame=None): 6921791604SMichael Walsh r""" 70410b1787SMichael Walsh Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT). 7121791604SMichael Walsh """ 7221791604SMichael Walsh 7321791604SMichael Walsh dprint_executing() 7421791604SMichael Walsh dprint_var(signal_number) 7521791604SMichael Walsh 7621791604SMichael Walsh qprint_pgm_footer() 7721791604SMichael Walsh 7821791604SMichael Walsh 7921791604SMichael Walshdef signal_handler(signal_number, 8021791604SMichael Walsh frame): 8121791604SMichael Walsh r""" 82410b1787SMichael Walsh Handle signals. Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately 83410b1787SMichael Walsh with return code 143 and without calling our exit_function. 8421791604SMichael Walsh """ 8521791604SMichael Walsh 86410b1787SMichael Walsh # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly 87410b1787SMichael Walsh # call exit_function from here. 8821791604SMichael Walsh 8921791604SMichael Walsh dprint_executing() 9021791604SMichael Walsh 91410b1787SMichael Walsh # Calling exit prevents us from returning to the code that was running when we received the signal. 9221791604SMichael Walsh exit(0) 9321791604SMichael Walsh 9421791604SMichael Walsh 9521791604SMichael Walshdef validate_parms(): 9621791604SMichael Walsh r""" 97410b1787SMichael Walsh Validate program parameters, etc. Return True or False (i.e. pass/fail) accordingly. 9821791604SMichael Walsh """ 9921791604SMichael Walsh 10021791604SMichael Walsh global prop_dir_path 10121791604SMichael Walsh global prop_file_path 10221791604SMichael Walsh 10321791604SMichael Walsh if not valid_dir_path(prop_dir_path): 10421791604SMichael Walsh return False 10521791604SMichael Walsh prop_dir_path = add_trailing_slash(prop_dir_path) 10621791604SMichael Walsh 10721791604SMichael Walsh if not valid_value(prop_file_name): 10821791604SMichael Walsh return False 10921791604SMichael Walsh 11021791604SMichael Walsh prop_file_path = prop_dir_path + prop_file_name 11121791604SMichael Walsh 11221791604SMichael Walsh # If properties file is not found, try adding ".properties" extension. 11321791604SMichael Walsh if not os.path.isfile(prop_file_path): 11421791604SMichael Walsh alt_prop_file_path = prop_file_path + ".properties" 11521791604SMichael Walsh if os.path.isfile(alt_prop_file_path): 11621791604SMichael Walsh prop_file_path = alt_prop_file_path 11721791604SMichael Walsh 11821791604SMichael Walsh if not valid_file_path(prop_file_path): 11921791604SMichael Walsh return False 12021791604SMichael Walsh 12121791604SMichael Walsh if not valid_value(program_name): 12221791604SMichael Walsh return False 12321791604SMichael Walsh 12421791604SMichael Walsh gen_post_validation(exit_function, signal_handler) 12521791604SMichael Walsh 12621791604SMichael Walsh return True 12721791604SMichael Walsh 12821791604SMichael Walsh 12921791604SMichael Walshdef main(): 13021791604SMichael Walsh 13121791604SMichael Walsh if not gen_get_options(parser, stock_list): 13221791604SMichael Walsh return False 13321791604SMichael Walsh 13421791604SMichael Walsh if not validate_parms(): 13521791604SMichael Walsh return False 13621791604SMichael Walsh 13721791604SMichael Walsh qprint_pgm_header() 13821791604SMichael Walsh 13921791604SMichael Walsh # Get the parameters from the properties file. 14021791604SMichael Walsh properties = my_parm_file(prop_file_path) 14121791604SMichael Walsh # The parms (including program name) need to go into a list. 14221791604SMichael Walsh parms = [program_name] 14321791604SMichael Walsh for key, value in properties.items(): 14421791604SMichael Walsh if key == "pos": 14521791604SMichael Walsh # Process positional parm(s). 14621791604SMichael Walsh parms.extend(value.split()) 14721791604SMichael Walsh else: 14821791604SMichael Walsh parms.append("--" + key + "=" + escape_bash_quotes(value)) 14921791604SMichael Walsh 15021791604SMichael Walsh # parm_string is only created for display in non-quiet mode. 15121791604SMichael Walsh parm_string = " ".join(parms[1:]) 15221791604SMichael Walsh cmd_buf = program_name + " " + parm_string 15321791604SMichael Walsh qprint_issuing(cmd_buf) 15421791604SMichael Walsh if not test_mode: 15521791604SMichael Walsh os.execvp(program_name, parms) 15621791604SMichael Walsh 15721791604SMichael Walsh return True 15821791604SMichael Walsh 15921791604SMichael Walsh 16021791604SMichael Walsh# Main 16121791604SMichael Walsh 16221791604SMichael Walshif not main(): 16321791604SMichael Walsh exit(1) 164