generate.py 5.11 KB
Newer Older
1
#!/usr/bin/env python3
Tobias Langer committed
2 3 4 5 6 7

"""
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.

8 9 10 11 12
* Read the json file of every experiment
* Create folders for every experiment
* Create the header file for every experiment
* Add the make file for every experiment
* Add c++ file for every experiment
Tobias Langer committed
13 14 15 16 17 18 19
"""

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

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
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
45 46 47 48 49 50 51
def query_yes_no(question, default=None):
    """
    Queries the user for a decision.
    """

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

    while True:
60
        print(question, prompt, end='')
Tobias Langer committed
61 62 63 64 65 66 67 68 69 70 71 72
        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:
73
        os.makedirs(filename)
Tobias Langer committed
74 75 76
    except FileExistsError:
        if not query_yes_no('Folder exists, remove?', default='yes'):
            return False
77 78
        shutil.rmtree(filename)
        os.makedirs(filename)
Tobias Langer committed
79 80
    return True

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

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.')

    args = parser.parse_args()
101 102
    cwd = os.getcwd()

Tobias Langer committed
103 104 105 106 107
    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)

108
        try:
Tobias Langer committed
109
            template_path = os.path.join(cwd, experiment['template'])
110 111 112 113 114 115 116
        except KeyError:
            print('Experiment file doesn\'t specify template, aborting…',
                  file=sys.stderr)
            sys.exit(1)
        header = os.path.join(template_path, 'defines.h')
        makefile = os.path.join(template_path, 'Makefile')
        cpp = os.path.join(template_path, 'experiment.cpp')
117 118 119
        timewaste_h = os.path.join(template_path, 'fun.h')
        timewaste_cpp = os.path.join(template_path, 'fun.cpp')
        timetable = os.path.join(template_path, 'timing_header.h')
120

Tobias Langer committed
121 122 123 124 125
        try:
            output_path = experiment['output']
        except KeyError:
            output_path = cwd

Tobias Langer committed
126
        print('[{}/{}] Creating experiment {}:'.format(num + 1,
Tobias Langer committed
127 128 129 130
                                                       len(args.description),
                                                       experiment['name']),
              file=sys.stderr)

Tobias Langer committed
131
        experiment_dir = os.path.join(output_path, experiment['name'])
132

Tobias Langer committed
133
        # Create folder
134
        print('Create folder…', experiment_dir, file=sys.stderr)
135
        if not create_dir(experiment_dir):
Tobias Langer committed
136 137 138 139
            print('Skipping experiment ', experiment['name'], file=sys.stderr)
            continue

        # Add header
140
        print('Create header file…', file=sys.stderr)
141
        header_path = os.path.join(experiment_dir, 'defines.h')
142
        create_header(header, experiment, header_path)
Tobias Langer committed
143 144

        # Add makefile & c++ file
145
        print('Adding Makefile…', file=sys.stderr)
146
        makefile_path = os.path.join(experiment_dir, 'Makefile')
147
        shutil.copyfile(makefile, makefile_path)
148
        print('Add C++ file(s)…', file=sys.stderr)
149
        cpp_file_path = os.path.join(experiment_dir, 'experiment.cpp')
150
        shutil.copyfile(cpp, cpp_file_path)
151 152 153 154 155 156
        fun_cpp_file_path = os.path.join(experiment_dir, 'fun.cpp')
        shutil.copyfile(timewaste_cpp, fun_cpp_file_path)
        fun_h_file_path = os.path.join(experiment_dir, 'fun.h')
        shutil.copyfile(timewaste_h, fun_h_file_path)
        timetable_file_path = os.path.join(experiment_dir, 'timing_header.h')
        shutil.copyfile(timetable, timetable_file_path)
Tobias Langer committed
157 158 159

if __name__ == '__main__':
    main()