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