blob: 9e18f71d8fdd302459b4795b0d036865e65e4d69 [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh21791602018-03-23 16:45:00 -05002
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
George Keishinge635ddc2022-12-08 07:38:02 -060019import os
Patrick Williams20f38712022-12-08 06:18:26 -060020import sys
Sridevi Ramesh47375aa2022-12-08 05:05:31 -060021
22save_path_0 = sys.path[0]
23del sys.path[0]
24
Patrick Williams20f38712022-12-08 06:18:26 -060025from gen_arg import * # NOQA
26from gen_cmd import * # NOQA
27from gen_misc import * # NOQA
28from gen_print import * # NOQA
29from gen_valid import * # NOQA
George Keishing37c58c82022-12-08 07:42:54 -060030
Michael Walsh21791602018-03-23 16:45:00 -050031# Restore sys.path[0].
32sys.path.insert(0, save_path_0)
33
34
35parser = argparse.ArgumentParser(
Patrick Williams20f38712022-12-08 06:18:26 -060036 usage="%(prog)s [OPTIONS]",
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050037 description="%(prog)s will call a program using parameters retrieved"
38 + " from the given properties file.",
Michael Walsh21791602018-03-23 16:45:00 -050039 formatter_class=argparse.ArgumentDefaultsHelpFormatter,
Patrick Williams20f38712022-12-08 06:18:26 -060040 prefix_chars="-+",
41)
Michael Walsh21791602018-03-23 16:45:00 -050042
43parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060044 "--prop_dir_path",
Michael Walsh21791602018-03-23 16:45:00 -050045 default=os.environ.get("PROP_DIR_PATH", os.getcwd()),
Patrick Williams20f38712022-12-08 06:18:26 -060046 help="The path to the directory that contains the properties file."
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050047 + ' The default value is environment variable "PROP_DIR_PATH", if'
Patrick Williams20f38712022-12-08 06:18:26 -060048 + " set. Otherwise, it is the current working directory.",
49)
Michael Walsh21791602018-03-23 16:45:00 -050050
51parser.add_argument(
Patrick Williams20f38712022-12-08 06:18:26 -060052 "--prop_file_name",
53 help="The path to a properties file that contains the parameters to"
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050054 + ' pass to the program. If the properties file has a ".properties"'
Patrick Williams20f38712022-12-08 06:18:26 -060055 + " 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"
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050058 + ' positional parms, use a parm name of "pos". For example: pos=this'
Patrick Williams20f38712022-12-08 06:18:26 -060059 " value",
60)
Michael Walsh21791602018-03-23 16:45:00 -050061
Patrick Williams20f38712022-12-08 06:18:26 -060062parser.add_argument("program_name", help="The name of the program to be run.")
Michael Walsh21791602018-03-23 16:45:00 -050063
64# Populate stock_list with options we want.
65stock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)]
66
67
Patrick Williams20f38712022-12-08 06:18:26 -060068def exit_function(signal_number=0, frame=None):
Michael Walsh21791602018-03-23 16:45:00 -050069 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050070 Execute whenever the program ends normally or with the signals that we catch (i.e. TERM, INT).
Michael Walsh21791602018-03-23 16:45:00 -050071 """
72
73 dprint_executing()
74 dprint_var(signal_number)
75
76 qprint_pgm_footer()
77
78
Patrick Williams20f38712022-12-08 06:18:26 -060079def signal_handler(signal_number, frame):
Michael Walsh21791602018-03-23 16:45:00 -050080 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050081 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.
Michael Walsh21791602018-03-23 16:45:00 -050083 """
84
Michael Walsh410b1782019-10-22 15:56:18 -050085 # Our convention is to set up exit_function with atexit.register() so there is no need to explicitly
86 # call exit_function from here.
Michael Walsh21791602018-03-23 16:45:00 -050087
88 dprint_executing()
89
Michael Walsh410b1782019-10-22 15:56:18 -050090 # Calling exit prevents us from returning to the code that was running when we received the signal.
Michael Walsh21791602018-03-23 16:45:00 -050091 exit(0)
92
93
94def validate_parms():
Michael Walsh21791602018-03-23 16:45:00 -050095 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050096 Validate program parameters, etc. Return True or False (i.e. pass/fail) accordingly.
Michael Walsh21791602018-03-23 16:45:00 -050097 """
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():
Michael Walsh21791602018-03-23 16:45:00 -0500129 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)