generate.py 4.52 KB
Newer Older
1
#!/usr/bin/env python3
Tobias Langer committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

"""
This utility script helps in the creation of experiment setups. It therefore
reads experiment descriptions from json files and creates everything necessary
as a result.

It therefore performs the following actions:
* [x] Read the json file of every experiment
* [x] Create folders for every experiment
* [ ] Create the header file for every experiment
* [x] Add the make file for every experiment
* [x] Add c++ file for every experiment
"""

import sys
import os
import argparse
import shutil
import json
21
import pystache
Tobias Langer committed
22

23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
class UtilityFunctions(pystache.TemplateSpec):
    def Upper(self, text=None):
        """
        Capitalize a given token
        """
        return lambda txt: txt.upper()

    def Lower(self, text=None):
        """
        Return the given text in lowercase.
        """
        return lambda txt: txt.lower()

    def CamelCase(self, text=None):
        """
        Capitalize the first letter of the given text.
        """
        def _camel(text):
            text[0].upper()
            return text
        return _camel


Tobias Langer committed
46 47 48 49 50 51 52
def query_yes_no(question, default=None):
    """
    Queries the user for a decision.
    """

    if default is None:
        prompt = ' [y/n]'
53
    elif default.lower() == 'yes':
Tobias Langer committed
54
        prompt = ' [Y/n]'
55
    elif default.lower() == 'no':
Tobias Langer committed
56 57 58 59 60
        prompt = ' [y/N]'
    else:
        raise ValueError('Invalid default answer {}'.format(default))

    while True:
61
        print(question, prompt, end='')
Tobias Langer committed
62 63 64 65 66 67 68 69 70 71 72 73
        choice = input().lower()
        if 'yes'.find(choice) == 0:
            return True
        elif 'no'.find(choice) == 0:
            return False

def create_dir(filename):
    """
    Create the directory denoted by filename, if it doesn't exists. Ask for its
    removal if it exists.
    """
    try:
74
        os.makedirs(filename)
Tobias Langer committed
75 76 77
    except FileExistsError:
        if not query_yes_no('Folder exists, remove?', default='yes'):
            return False
78 79
        shutil.rmtree(filename)
        os.makedirs(filename)
Tobias Langer committed
80 81
    return True

82
def create_header(headerfile, experiment, destination):
Tobias Langer committed
83 84 85
    """
    Create a header file for the experiment.
    """
86 87
    with open(headerfile, 'r') as header_template:
        template = header_template.read()
88
    header_txt = pystache.render(template, experiment, UtilityFunctions())
89 90
    with open(destination, 'w') as header:
        print(header_txt, file=header)
Tobias Langer committed
91 92 93 94 95 96 97 98

def main():
    """
    Starting point of the script, parses arguments and creates the experiments.
    """

    parser = argparse.ArgumentParser(description='Generate experiment data.')
    parser.add_argument('description', type=str, nargs='+', help='file containing the taskset description.')
99 100 101
    parser.add_argument('--header', dest='header', type=str, nargs='?', default='./templates/normal/defines.h', help='path to optional custom header file.')
    parser.add_argument('--makefile', dest='makefile', type=str, nargs='?', default='./templates/normal/Makefile', help='path to optional custom makefile.')
    parser.add_argument('--cpp', dest='cpp', type=str, nargs='*', default='./templates/normal/experiment.cpp', help='path to optional custom c++ implementation.')
Tobias Langer committed
102 103

    args = parser.parse_args()
104 105
    cwd = os.getcwd()

Tobias Langer committed
106 107 108 109 110
    for num, experiment_file in enumerate(args.description):
        with open(experiment_file, 'r') as experiment_description:
            descr_json = experiment_description.read()
        experiment = json.loads(descr_json)

Tobias Langer committed
111
        print('[{}/{}] Creating experiment {}:'.format(num + 1,
Tobias Langer committed
112 113 114 115
                                                       len(args.description),
                                                       experiment['name']),
              file=sys.stderr)

116 117
        experiment_dir = os.path.join(cwd, experiment['name'])

Tobias Langer committed
118
        # Create folder
119
        print('Create folder…', experiment_dir, file=sys.stderr)
120
        if not create_dir(experiment_dir):
Tobias Langer committed
121 122 123 124
            print('Skipping experiment ', experiment['name'], file=sys.stderr)
            continue

        # Add header
125
        print('Create header file…', file=sys.stderr)
126
        header_path = os.path.join(experiment_dir, 'defines.h')
127
        create_header(args.header, experiment, header_path)
Tobias Langer committed
128 129

        # Add makefile & c++ file
130
        print('Adding Makefile…', file=sys.stderr)
131 132
        makefile_path = os.path.join(experiment_dir, 'Makefile')
        shutil.copyfile(args.makefile, makefile_path)
133
        print('Add C++ file(s)…', file=sys.stderr)
134 135
        cpp_file_path = os.path.join(experiment_dir, 'experiment.cpp')
        shutil.copyfile(args.cpp, cpp_file_path)
Tobias Langer committed
136 137 138

if __name__ == '__main__':
    main()