1e7e9171eSGeorge 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 19e635ddc0SGeorge Keishingimport os 20*20f38712SPatrick Williamsimport sys 2147375aa7SSridevi Ramesh 2247375aa7SSridevi Rameshsave_path_0 = sys.path[0] 2347375aa7SSridevi Rameshdel sys.path[0] 2447375aa7SSridevi Ramesh 2509679890SGeorge Keishingfrom gen_arg import * # NOQA 26*20f38712SPatrick Williamsfrom gen_cmd import * # NOQA 27*20f38712SPatrick Williamsfrom gen_misc import * # NOQA 2809679890SGeorge Keishingfrom gen_print import * # NOQA 2909679890SGeorge Keishingfrom gen_valid import * # NOQA 3037c58c8cSGeorge Keishing 3121791604SMichael Walsh# Restore sys.path[0]. 3221791604SMichael Walshsys.path.insert(0, save_path_0) 3321791604SMichael Walsh 3421791604SMichael Walsh 3521791604SMichael Walshparser = argparse.ArgumentParser( 36*20f38712SPatrick Williams 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, 40*20f38712SPatrick Williams prefix_chars="-+", 41*20f38712SPatrick Williams) 4221791604SMichael Walsh 4321791604SMichael Walshparser.add_argument( 44*20f38712SPatrick Williams "--prop_dir_path", 4521791604SMichael Walsh default=os.environ.get("PROP_DIR_PATH", os.getcwd()), 46*20f38712SPatrick Williams help="The path to the directory that contains the properties file." 47004ad3c9SJoy Onyerikwu + ' The default value is environment variable "PROP_DIR_PATH", if' 48*20f38712SPatrick Williams + " set. Otherwise, it is the current working directory.", 49*20f38712SPatrick Williams) 5021791604SMichael Walsh 5121791604SMichael Walshparser.add_argument( 52*20f38712SPatrick Williams "--prop_file_name", 53*20f38712SPatrick Williams help="The path to a properties file that contains the parameters to" 54004ad3c9SJoy Onyerikwu + ' pass to the program. If the properties file has a ".properties"' 55*20f38712SPatrick Williams + " extension, the caller need not specify the extension. The format" 56*20f38712SPatrick Williams + " of each line in the properties file should be as follows:" 57*20f38712SPatrick Williams + " <parm_name=parm_value>. Do not quote the parm value. To specify" 58004ad3c9SJoy Onyerikwu + ' positional parms, use a parm name of "pos". For example: pos=this' 59*20f38712SPatrick Williams " value", 60*20f38712SPatrick Williams) 6121791604SMichael Walsh 62*20f38712SPatrick Williamsparser.add_argument("program_name", help="The name of the program to be run.") 6321791604SMichael Walsh 6421791604SMichael Walsh# Populate stock_list with options we want. 6521791604SMichael Walshstock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)] 6621791604SMichael Walsh 6721791604SMichael Walsh 68*20f38712SPatrick Williamsdef exit_function(signal_number=0, 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 79*20f38712SPatrick Williamsdef signal_handler(signal_number, frame): 8021791604SMichael Walsh r""" 81410b1787SMichael Walsh Handle signals. Without a function to catch a SIGTERM or SIGINT, our program would terminate immediately 82410b1787SMichael Walsh with return code 143 and without calling our exit_function. 8321791604SMichael Walsh """ 8421791604SMichael Walsh 85410b1787SMichael Walsh # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly 86410b1787SMichael Walsh # call exit_function from here. 8721791604SMichael Walsh 8821791604SMichael Walsh dprint_executing() 8921791604SMichael Walsh 90410b1787SMichael Walsh # Calling exit prevents us from returning to the code that was running when we received the signal. 9121791604SMichael Walsh exit(0) 9221791604SMichael Walsh 9321791604SMichael Walsh 9421791604SMichael Walshdef validate_parms(): 9521791604SMichael Walsh r""" 96410b1787SMichael Walsh Validate program parameters, etc. Return True or False (i.e. pass/fail) accordingly. 9721791604SMichael Walsh """ 9821791604SMichael Walsh 9921791604SMichael Walsh global prop_dir_path 10021791604SMichael Walsh global prop_file_path 10121791604SMichael Walsh 10221791604SMichael Walsh if not valid_dir_path(prop_dir_path): 10321791604SMichael Walsh return False 10421791604SMichael Walsh prop_dir_path = add_trailing_slash(prop_dir_path) 10521791604SMichael Walsh 10621791604SMichael Walsh if not valid_value(prop_file_name): 10721791604SMichael Walsh return False 10821791604SMichael Walsh 10921791604SMichael Walsh prop_file_path = prop_dir_path + prop_file_name 11021791604SMichael Walsh 11121791604SMichael Walsh # If properties file is not found, try adding ".properties" extension. 11221791604SMichael Walsh if not os.path.isfile(prop_file_path): 11321791604SMichael Walsh alt_prop_file_path = prop_file_path + ".properties" 11421791604SMichael Walsh if os.path.isfile(alt_prop_file_path): 11521791604SMichael Walsh prop_file_path = alt_prop_file_path 11621791604SMichael Walsh 11721791604SMichael Walsh if not valid_file_path(prop_file_path): 11821791604SMichael Walsh return False 11921791604SMichael Walsh 12021791604SMichael Walsh if not valid_value(program_name): 12121791604SMichael Walsh return False 12221791604SMichael Walsh 12321791604SMichael Walsh gen_post_validation(exit_function, signal_handler) 12421791604SMichael Walsh 12521791604SMichael Walsh return True 12621791604SMichael Walsh 12721791604SMichael Walsh 12821791604SMichael Walshdef main(): 12921791604SMichael Walsh if not gen_get_options(parser, stock_list): 13021791604SMichael Walsh return False 13121791604SMichael Walsh 13221791604SMichael Walsh if not validate_parms(): 13321791604SMichael Walsh return False 13421791604SMichael Walsh 13521791604SMichael Walsh qprint_pgm_header() 13621791604SMichael Walsh 13721791604SMichael Walsh # Get the parameters from the properties file. 13821791604SMichael Walsh properties = my_parm_file(prop_file_path) 13921791604SMichael Walsh # The parms (including program name) need to go into a list. 14021791604SMichael Walsh parms = [program_name] 14121791604SMichael Walsh for key, value in properties.items(): 14221791604SMichael Walsh if key == "pos": 14321791604SMichael Walsh # Process positional parm(s). 14421791604SMichael Walsh parms.extend(value.split()) 14521791604SMichael Walsh else: 14621791604SMichael Walsh parms.append("--" + key + "=" + escape_bash_quotes(value)) 14721791604SMichael Walsh 14821791604SMichael Walsh # parm_string is only created for display in non-quiet mode. 14921791604SMichael Walsh parm_string = " ".join(parms[1:]) 15021791604SMichael Walsh cmd_buf = program_name + " " + parm_string 15121791604SMichael Walsh qprint_issuing(cmd_buf) 15221791604SMichael Walsh if not test_mode: 15321791604SMichael Walsh os.execvp(program_name, parms) 15421791604SMichael Walsh 15521791604SMichael Walsh return True 15621791604SMichael Walsh 15721791604SMichael Walsh 15821791604SMichael Walsh# Main 15921791604SMichael Walsh 16021791604SMichael Walshif not main(): 16121791604SMichael Walsh exit(1) 162