codes_configurator.py.in 3.16 KB
Newer Older
1 2
#!/usr/bin/python2.7

3 4 5 6 7 8
#
# Copyright (C) 2014 University of Chicago.
# See COPYRIGHT notice in top-level directory.
#
#

9 10
import os
import argparse
11 12 13 14 15 16 17 18 19 20 21 22 23
import imp

# internal testing: import directly
#import configurator as conf

# dynamically load from lib path
def import_from(fname):
    path,name = os.path.split(fname)
    name,ext  = os.path.splitext(name) 

    fmod, fname, data = imp.find_module(name, [path])
    return imp.load_module(name,fmod,fname,data)

24
conf = import_from("@bindir@/_configurator.py")
25 26 27 28 29 30 31 32

def main():
    args = parse_args()
    
    # load the template file
    tstr = open(args.template).read()

    # load the module
33
    mod = conf.import_from(args.substitute_py)
34

35 36
    # intitialize the configuration object 
    cfg = conf.configurator(mod, args.token_pairs)
37

38 39 40 41 42
    # print the header to the log
    if args.log != None:
        flog = open(args.log, "w")
    else:
        flog = open(os.devnull, "w")
43 44
    
    cfg.write_header(flog)
45

46 47 48 49
    # main loop (cfg iterator returns nothing, eval'd for side effects)
    for i,_ in enumerate(cfg):
        new_config = conf.replace_many(tstr, cfg.replace_map)
        fname = template+"."+str(i) if args.output_prefix==None else \
50
                args.output_prefix +"." + "{:05d}".format(i)
51 52
        with open(fname, "w") as fout:
            fout.write(new_config)
53 54 55
        
        # write this config to the log 
        cfg.write_config_line(i, flog)
56

57
    flog.close()
58

59 60 61 62 63 64 65 66 67 68 69 70
sub_help = \
'python file defining "cfields" variable consisting of a sequence of <name, ' \
'value sequence> pairs. The following variables may optionally appear. ' \
'"exceptions" - a sequence of dictionaries. Each configuration generated by ' \
'"cfields" is checked against each dictionary in "exceptions"; if each value ' \
'in the dict matches that of the configuration, then that configuration is ' \
'skipped. "cfields_derived_labels", "cfields_derived" - the former is a ' \
'sequence of strings identifying replace tokens that will be dynamically set ' \
'based on the input configuration generated by cfields. The latter is a ' \
'function that adds all <name,value> pairs for names in ' \
'"cfields_derived_labels".'

71
def parse_args():
72 73 74 75
    parser = argparse.ArgumentParser(\
            description="generate set of configuration files based on template "
                        "file and replacement tokens")
    parser.add_argument("template",
76
            help="template file with replace tokens")
77
    parser.add_argument("substitute_py",
78
            help=sub_help)
79
    parser.add_argument("token_pairs", nargs='*',
80 81 82 83 84 85 86
            help="a list of whitespace-separated token, replace pairs for "
                 "command-line-driven replacement (useful in shell scripts "
                 "for generating sets of configuration files with a distinct "
                 "parameter or for special casing fields)")
    parser.add_argument("-l", "--log",
            help="log file to write parameterizations to")
    parser.add_argument("-o", "--output_prefix",
87 88 89 90 91 92
            help="prefix to output generated configuration files to "
                 "(default: the configuration index appended to the template name)")
    return parser.parse_args()

if __name__ == "__main__":
    main()