Matthew Barth | 1080b38 | 2017-02-17 15:50:43 -0600 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | """ |
| 4 | This script parses the given fan presence definition yaml file and generates |
| 5 | a header file based on the defined methods for determining when a fan is |
| 6 | present. |
| 7 | """ |
| 8 | |
| 9 | import os |
| 10 | import sys |
| 11 | import yaml |
| 12 | from argparse import ArgumentParser |
| 13 | # TODO Convert to using a mako template |
| 14 | |
| 15 | |
| 16 | def get_filename(): |
| 17 | """ |
| 18 | Constructs and returns the fully qualified header filename. |
| 19 | """ |
| 20 | script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 21 | header_file = os.path.join(script_dir, "fan_detect_defs.cpp") |
| 22 | |
| 23 | return header_file |
| 24 | |
| 25 | |
| 26 | def create_and_add_header(header_file): |
| 27 | """ |
| 28 | Creates the header file based on the header filename value given within. |
| 29 | The associated fan presence detection application includes this header. |
| 30 | |
| 31 | Parameter descriptions: |
| 32 | header_file Header filename to create |
| 33 | """ |
| 34 | with open(header_file, 'w') as ofile: |
| 35 | ofile.write("/* WARNING: This header contains code generated ") |
| 36 | ofile.write("by " + __file__ + " */\n") |
| 37 | ofile.write("/* !!! DO NOT EDIT THIS FILE BY HAND !!! */\n") |
| 38 | ofile.write("#include \"fan_detect_defs.hpp\"\n\n") |
| 39 | ofile.write("const std::map<std::string, ") |
| 40 | ofile.write("std::set<phosphor::fan::Properties>>") |
| 41 | ofile.write("\nfanDetectMap = {\n") |
| 42 | |
| 43 | |
| 44 | def add_detect(header_fd, dmethod): |
| 45 | """ |
| 46 | Adds the detection method map entry for listing the fan(s) that should be |
| 47 | detected using the supported method. |
| 48 | |
| 49 | Parameter descriptions: |
| 50 | header_fd Header file to add the detection method to |
| 51 | dmethod The detection method to be added |
| 52 | """ |
| 53 | header_fd.write(" {\"" + dmethod + "\",{\n") |
| 54 | |
| 55 | |
| 56 | def add_fan(header_fd, fan_info): |
| 57 | """ |
| 58 | Adds each fan's yaml entry presence detection information to the |
| 59 | corresponding header file for the defined detection method |
| 60 | |
| 61 | Parameter descriptions: |
| 62 | header_fd Header file to add fan information to |
| 63 | fan_info Fan presence detection information |
| 64 | """ |
| 65 | tab = ' ' * 4 |
| 66 | header_fd.write(tab * 2 + "std::make_tuple(\"" + |
| 67 | fan_info['Inventory'] + "\",\n") |
| 68 | header_fd.write(tab * 6 + "\"" +fan_info['Description'] + "\",\n") |
| 69 | header_fd.write(tab * 6 + "std::vector<std::string>({") |
| 70 | for sensors in fan_info['Sensors']: |
| 71 | if sensors != fan_info['Sensors'][-1]: |
| 72 | header_fd.write("\"" + sensors + "\",") |
| 73 | else: |
| 74 | header_fd.write("\"" + sensors + "\"})),\n") |
| 75 | |
| 76 | |
| 77 | def close_detect(header_fd): |
| 78 | """ |
| 79 | Closes the current detection method map entry. |
| 80 | |
| 81 | Parameter descriptions: |
| 82 | header_fd Header file to add detection method closing to |
| 83 | """ |
| 84 | header_fd.write(" }},\n") |
| 85 | |
| 86 | |
| 87 | def add_closing(header_fd): |
| 88 | """ |
| 89 | Appends final closing tags to the header file given. This essentially |
| 90 | ends writing to the header file generated. |
| 91 | |
| 92 | Parameter descriptions: |
| 93 | header_fd Header file to add closing tags to |
| 94 | """ |
| 95 | header_fd.write("};\n") |
| 96 | |
| 97 | |
| 98 | def parse_yaml(yaml_file): |
| 99 | """ |
| 100 | Parse the given yaml file, creating a header file for each 'Detection' |
| 101 | types found to be included within the app supporting presence detection |
| 102 | by that type. |
| 103 | |
| 104 | Parameter descriptions: |
| 105 | yaml_file File to be parsed for fan presences definitions |
| 106 | """ |
| 107 | with open(yaml_file, 'r') as input_file: |
| 108 | yaml_input = yaml.safe_load(input_file) |
| 109 | header_file = get_filename() |
| 110 | create_and_add_header(header_file) |
| 111 | header_fd = open(header_file, 'a') |
| 112 | if yaml_input: |
| 113 | for detect in yaml_input: |
| 114 | for dmethod in detect: |
| 115 | add_detect(header_fd, dmethod.replace(" ", "-").lower()) |
| 116 | for fan in detect[dmethod]: |
| 117 | add_fan(header_fd, fan) |
| 118 | close_detect(header_fd) |
| 119 | add_closing(header_fd) |
| 120 | header_fd.close() |
| 121 | |
| 122 | |
| 123 | if __name__ == '__main__': |
| 124 | parser = ArgumentParser() |
| 125 | # Input yaml containing how each fan's presence detection should be done |
| 126 | parser.add_argument("-y", "--yaml", dest="pres_yaml", |
| 127 | default= |
| 128 | "example/fan-detect.yaml", |
| 129 | help= |
| 130 | "Input fan presences definition yaml file to parse") |
| 131 | args = parser.parse_args(sys.argv[1:]) |
| 132 | |
| 133 | # Verify given yaml file exists |
| 134 | yaml_file = os.path.abspath(args.pres_yaml) |
| 135 | if not os.path.isfile(yaml_file): |
| 136 | print "Unable to find input yaml file " + yaml_file |
| 137 | exit(1) |
| 138 | |
| 139 | parse_yaml(yaml_file) |