1#!/usr/bin/env python3
2
3r"""
4This module is the python counterpart to run_keyword.robot.
5"""
6
7import re
8
9import gen_print as gp
10import gen_robot_utils as gru
11import gen_robot_valid as grv
12from robot.libraries.BuiltIn import BuiltIn
13
14
15def setup():
16    r"""
17    Do general program setup tasks.
18    """
19
20    gp.qprintn()
21
22    validate_parms()
23
24    gp.qprint_pgm_header()
25
26
27def validate_parms():
28    r"""
29    Validate all program parameters.
30    """
31
32    grv.valid_value("keyword_string")
33
34    return True
35
36
37def program_teardown():
38    r"""
39    Clean up after this program.
40    """
41
42    gp.qprint_pgm_footer()
43
44
45def my_run_keywords(lib_file_path, keyword_string, quiet=0, test_mode=0):
46    r"""
47    Run the keywords in the keyword string.
48
49    Description of arguments:
50    lib_file_path   The path to a library or resource needed to run the
51                    keywords.  This may contain a colon-delimited list of
52                    library/resource paths.
53    keyword_string  The keyword string to be run by this function.  If this
54                    keyword string contains " ; " anywhere, it will be taken to
55                    be multiple keyword strings.  Each keyword may also include
56                    a variable assignment.  Example:
57                    ${my_var}=  My Keyword
58    quiet           If this parameter is set to "1", this program will print
59                    only essential information, i.e. it will not echo
60                    parameters, echo commands, print the total run time, etc.
61    test_mode       This means that this program should go through all the
62                    motions but not actually do anything substantial.
63    """
64
65    # NOTE: During code review the following question was raised: Why support
66    # 1) variable assignments 2) multiple keywords?  Couldn't a user simply
67    # call this program twice to get what they need.  If necessary, the user
68    # could take the output of the first call and specify it as a literal on
69    # the second call.
70    #
71    # However, this approach would not work in all cases.  The following case
72    # would be such an example:
73    # Let's say the first keyword string is as follows:
74    # Create Dictionary  foo=bar
75    # You wish to take the output of that call and specify it as a literal
76    # value when running the following:
77    # Want Dictionary  parm=<literal dictionary specification>
78    # The problem is that there is no way to specify a dictionary as a
79    # literal in Robot Framework.
80    # By having this program support variable assignments and multiple
81    # keywords, the user can invoke it with the following keyword string.
82    # ${my_dict}=  Create Dictionary  foo=bar ; Want Dictionary  ${my_dict}
83
84    # The user can pass multiple lib/resource paths by separating them with a
85    # colon.
86    lib_file_path_list = lib_file_path.split(":")
87    # Get rid of empty entry if it exists.
88    if lib_file_path_list[0] == "":
89        del lib_file_path_list[0]
90    for lib_file_path in lib_file_path_list:
91        if lib_file_path.endswith(".py"):
92            gp.dprint_issuing('import_library("' + lib_file_path + '")')
93            BuiltIn().import_library(lib_file_path)
94        else:
95            gp.dprint_issuing('my_import_resource("' + lib_file_path + '")')
96            gru.my_import_resource(lib_file_path)
97
98    # The user can pass multiple keyword strings by separating them with " ; ".
99    keyword_list = keyword_string.split(" ; ")
100    for keyword_string in keyword_list:
101        cmd_buf = keyword_string.split("  ")
102        if re.match(r"\$\{", cmd_buf[0]):
103            # This looks like an assignment (e.g. ${var}=  <keyword>).
104            # We'll extract the variable name, remove element 0 from
105            # cmd_buf and set the global variable with the results
106            # after running the keyword.
107            var_name = cmd_buf[0].strip("${}=")
108            del cmd_buf[0]
109        else:
110            var_name = ""
111
112        if not quiet:
113            gp.print_issuing(cmd_buf, test_mode)
114        if test_mode:
115            continue
116
117        output = BuiltIn().run_keyword(*cmd_buf)
118
119        if var_name != "":
120            BuiltIn().set_global_variable("${" + var_name + "}", output)
121        else:
122            if output is not None:
123                gp.gp_print(output)
124
125
126def main_py():
127    r"""
128    Do main program processing.
129    """
130
131    setup()
132
133    lib_file_path = BuiltIn().get_variable_value("${lib_file_path}")
134    keyword_string = BuiltIn().get_variable_value("${keyword_string}")
135    quiet = int(BuiltIn().get_variable_value("${quiet}"))
136    test_mode = int(BuiltIn().get_variable_value("${test_mode}"))
137
138    my_run_keywords(lib_file_path, keyword_string, quiet, test_mode)
139