|
| 1 | +import copy |
| 2 | + |
| 3 | +class ParseJobID: |
| 4 | + def parse_file(self, file_path): |
| 5 | + with open(file_path) as file: |
| 6 | + file_contents = [line for line in file] |
| 7 | + |
| 8 | + jobID = None |
| 9 | + for l in file_contents: |
| 10 | + try: |
| 11 | + jobID = int(l.strip()) |
| 12 | + break |
| 13 | + except: |
| 14 | + continue |
| 15 | + if jobID is not None: |
| 16 | + return jobID |
| 17 | + else: |
| 18 | + raise Exception("No jobid found in " + file_path) |
| 19 | + |
| 20 | + |
| 21 | +class ParseRGTInput: |
| 22 | + def parse_file(self, file_path, verbose=False): |
| 23 | + with open(file_path) as file: |
| 24 | + file_contents = [line for line in file] |
| 25 | + |
| 26 | + unchanged_contents = copy.deepcopy(file_contents) |
| 27 | + # This is used to raise errors and find what line is the problem. |
| 28 | + file_contents = list(enumerate(file_contents)) |
| 29 | + if verbose: |
| 30 | + print("Removing commented lines.") |
| 31 | + file_contents = self.remove_commented(file_contents) |
| 32 | + |
| 33 | + if verbose: |
| 34 | + print("Splitting lines.") |
| 35 | + try: |
| 36 | + file_contents = self.split_lines(file_contents) |
| 37 | + except SyntaxError as e: |
| 38 | + raise Exception(e.toString(unchanged_contents)) |
| 39 | + |
| 40 | + if verbose: |
| 41 | + print("Parsing variables.") |
| 42 | + try: |
| 43 | + path_to_tests, test_list = self.parse_vars(file_contents) |
| 44 | + except SyntaxError as e: |
| 45 | + raise Exception(e.toString(unchanged_contents)) |
| 46 | + |
| 47 | + return path_to_tests, test_list |
| 48 | + |
| 49 | + |
| 50 | + def parse_vars(self, file_contents): |
| 51 | + test_list = [] |
| 52 | + path_to_tests = None |
| 53 | + for line_tup in file_contents: |
| 54 | + line_num = line_tup[0] |
| 55 | + var = line_tup[1]["var"] |
| 56 | + vals = line_tup[1]["vals"] |
| 57 | + |
| 58 | + if var.lower() == "path_to_tests": |
| 59 | + if len(vals) == 0: |
| 60 | + raise SyntaxError(message="No path to tests.", line_num=line_num) |
| 61 | + elif len(vals) > 1: |
| 62 | + raise SyntaxError(message="Too many paths to tests.", line_num=line_num) |
| 63 | + path_to_tests = vals[0] |
| 64 | + elif var.lower() == "test": |
| 65 | + if len(vals) < 2: |
| 66 | + raise SyntaxError(message="Need both program name and test name.", line_num=line_num) |
| 67 | + elif len(vals) > 2: |
| 68 | + raise SyntaxError(message="Too many values after test. Only need program name and test name.", line_num=line_num) |
| 69 | + test_list.append({"program": vals[0], "test": vals[1]}) |
| 70 | + else: |
| 71 | + raise SyntaxError(message="Incorrect variable to set. Should be either 'path_to_tests' or 'test'.", line_num=line_num) |
| 72 | + |
| 73 | + if path_to_tests == None: |
| 74 | + raise Exception("No path to tests found.") |
| 75 | + return path_to_tests, test_list |
| 76 | + |
| 77 | + |
| 78 | + def remove_commented(self, file_contents): |
| 79 | + contents = [] |
| 80 | + for line_tup in file_contents: |
| 81 | + line = line_tup[1] |
| 82 | + if len(line.lstrip()) > 0: |
| 83 | + if line.lstrip()[0] != "#": |
| 84 | + contents.append((line_tup[0], line.lstrip())) |
| 85 | + return contents |
| 86 | + |
| 87 | + |
| 88 | + def split_lines(self, file_contents): |
| 89 | + contents = [] |
| 90 | + for line_tup in file_contents: |
| 91 | + line = line_tup[1] |
| 92 | + line_num = line_tup[0] |
| 93 | + line = line.split('=') |
| 94 | + if len(line) < 2: |
| 95 | + raise SyntaxError(message="Not enough '='.", line_num=line_num) |
| 96 | + elif len(line) > 2: |
| 97 | + raise SyntaxError(message="Too many '='.", line_num=line_num) |
| 98 | + |
| 99 | + line = [l.split() for l in line] |
| 100 | + if len(line[0]) == 0: |
| 101 | + raise SyntaxError(message="Nothing before '='.", line_num=line_num) |
| 102 | + elif len(line[0]) > 1: |
| 103 | + raise SyntaxError(message="Too many space separated items before '='.", line_num=line_num) |
| 104 | + |
| 105 | + if len(line[1]) == 0: |
| 106 | + raise SyntaxError(message="Nothing after '='.", line_num=line_num) |
| 107 | + elif len(line[1]) > 2: |
| 108 | + raise SyntaxError(message="Too many space separated items after '='.", line_num=line_num) |
| 109 | + |
| 110 | + line_dic = {"var": line[0][0], "vals": line[1]} |
| 111 | + contents.append((line_num, line_dic)) |
| 112 | + return contents |
| 113 | + |
| 114 | + |
| 115 | +class SyntaxError(Exception): |
| 116 | + def __init__(self, message, line_num=-1): |
| 117 | + super().__init__(message) |
| 118 | + self.message = message |
| 119 | + self.line_num = line_num |
| 120 | + |
| 121 | + def toString(self, unchanged_contents): |
| 122 | + new_message = self.message |
| 123 | + if self.line_num != -1: |
| 124 | + new_message += "\nline " + str(self.line_num) + ":\t" + unchanged_contents[self.line_num] |
| 125 | + return new_message |
| 126 | + |
| 127 | + |
| 128 | +if __name__ == '__main__': |
| 129 | + rgtin_path = "/Users/cameronkuchta/Documents/GitHub/harmony/sample_inputs/rgt.input.master" |
| 130 | + job_id_path = "/Users/cameronkuchta/Documents/GitHub/harmony/sample_inputs/sample_run/GTC4/test_0001node/Status/123456789.0123/job_id.txt" |
| 131 | + parseID = ParseJobID() |
| 132 | + print(parseID.parse_file(job_id_path)) |
0 commit comments