New prop_call.py program
prop_call.py will call a program using parameters retrieved from the
given properties file.
Change-Id: I852b8ac2a26b9a732ed7b673e1f91785f70eca15
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/bin/prop_call.py b/bin/prop_call.py
new file mode 100755
index 0000000..b616feb
--- /dev/null
+++ b/bin/prop_call.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+
+r"""
+See help text for details (--help or -h option)..
+
+Example properties file content:
+quiet=n
+test_mode=y
+pos=file1 file2 file3
+
+Example call:
+
+prop_call.py --prop_file_name=prop_file my_program
+
+The result is that the following command will be run:
+my_program --test_mode=y --quiet=n file1 file2 file3
+"""
+
+import sys
+import os
+
+save_path_0 = sys.path[0]
+del sys.path[0]
+
+from gen_arg import *
+from gen_print import *
+from gen_valid import *
+from gen_misc import *
+from gen_cmd import *
+
+# Restore sys.path[0].
+sys.path.insert(0, save_path_0)
+
+
+parser = argparse.ArgumentParser(
+ usage='%(prog)s [OPTIONS]',
+ description="%(prog)s will call a program using parameters retrieved" +
+ " from the given properties file.",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ prefix_chars='-+')
+
+parser.add_argument(
+ '--prop_dir_path',
+ default=os.environ.get("PROP_DIR_PATH", os.getcwd()),
+ help='The path to the directory that contains the properties file.' +
+ ' The default value is environment variable "PROP_DIR_PATH", if' +
+ ' set. Otherwise, it is the current working directory.')
+
+parser.add_argument(
+ '--prop_file_name',
+ help='The path to a properties file that contains the parameters to' +
+ ' pass to the program. If the properties file has a ".properties"' +
+ ' extension, the caller need not specify the extension. The format' +
+ ' of each line in the properties file should be as follows:' +
+ ' <parm_name=parm_value>. Do not quote the parm value. To specify' +
+ ' positional parms, use a parm name of "pos". For example: pos=this'
+ ' value')
+
+parser.add_argument(
+ 'program_name',
+ help='The name of the program to be run.')
+
+# Populate stock_list with options we want.
+stock_list = [("test_mode", 0), ("quiet", 1), ("debug", 0)]
+
+
+def exit_function(signal_number=0,
+ frame=None):
+
+ r"""
+ Execute whenever the program ends normally or with the signals that we
+ catch (i.e. TERM, INT).
+ """
+
+ dprint_executing()
+ dprint_var(signal_number)
+
+ qprint_pgm_footer()
+
+
+def signal_handler(signal_number,
+ frame):
+
+ r"""
+ Handle signals. Without a function to catch a SIGTERM or SIGINT, our
+ program would terminate immediately with return code 143 and without
+ calling our exit_function.
+ """
+
+ # Our convention is to set up exit_function with atexit.register() so
+ # there is no need to explicitly call exit_function from here.
+
+ dprint_executing()
+
+ # Calling exit prevents us from returning to the code that was running
+ # when we received the signal.
+ exit(0)
+
+
+def validate_parms():
+
+ r"""
+ Validate program parameters, etc. Return True or False (i.e. pass/fail)
+ accordingly.
+ """
+
+ global prop_dir_path
+ global prop_file_path
+
+ if not valid_dir_path(prop_dir_path):
+ return False
+ prop_dir_path = add_trailing_slash(prop_dir_path)
+
+ if not valid_value(prop_file_name):
+ return False
+
+ prop_file_path = prop_dir_path + prop_file_name
+
+ # If properties file is not found, try adding ".properties" extension.
+ if not os.path.isfile(prop_file_path):
+ alt_prop_file_path = prop_file_path + ".properties"
+ if os.path.isfile(alt_prop_file_path):
+ prop_file_path = alt_prop_file_path
+
+ if not valid_file_path(prop_file_path):
+ return False
+
+ if not valid_value(program_name):
+ return False
+
+ gen_post_validation(exit_function, signal_handler)
+
+ return True
+
+
+def main():
+
+ if not gen_get_options(parser, stock_list):
+ return False
+
+ if not validate_parms():
+ return False
+
+ qprint_pgm_header()
+
+ # Get the parameters from the properties file.
+ properties = my_parm_file(prop_file_path)
+ # The parms (including program name) need to go into a list.
+ parms = [program_name]
+ for key, value in properties.items():
+ if key == "pos":
+ # Process positional parm(s).
+ parms.extend(value.split())
+ else:
+ parms.append("--" + key + "=" + escape_bash_quotes(value))
+
+ # parm_string is only created for display in non-quiet mode.
+ parm_string = " ".join(parms[1:])
+ cmd_buf = program_name + " " + parm_string
+ qprint_issuing(cmd_buf)
+ if not test_mode:
+ os.execvp(program_name, parms)
+
+ return True
+
+
+# Main
+
+if not main():
+ exit(1)