comparison env/lib/python3.7/site-packages/planemo/rscript_parse.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 """Module parses R scripts and sends a yaml file to cmd_bioc_tool_init."""
2 import os
3
4
5 def read_rscript(path):
6 """Read the rscript."""
7 try:
8 with open(os.path.expanduser(path), 'r') as f:
9 rscript = f.readlines()
10 except Exception as e:
11 print(e)
12 return rscript
13
14
15 def parse_rscript(script, example_command):
16 """Parse script."""
17 rscript = read_rscript(script)
18 data = {}
19
20 # Find libraries
21 lib = Library(rscript)
22 library_list = lib.find_library()
23 data['library'] = library_list
24
25 # Find inputs
26 inputs = Input(rscript, example_command)
27 input_list = inputs.find_inputs()
28 data['inputs'] = input_list
29
30 # Find outputs
31 outputs = Output(rscript, example_command)
32 output_list = outputs.find_outputs()
33 data['outputs'] = output_list
34 return data
35
36
37 def parse_example_command(example_command):
38 """Parse example_command to get inputs.
39
40 Each input stored as element in a dictionary list.
41 """
42 cmd = example_command.replace("\n", " ")
43 opts = [i.strip() for i in cmd.split("--")]
44 opt_dict = {}
45 for opt in opts:
46 opt = opt.split(" ")
47 if not opt[0] in opt_dict.keys():
48 opt_dict[opt[0]] = [opt[1]]
49 else:
50 opt_dict[opt[0]].append(opt[1])
51 return opt_dict
52
53
54 class Library(object):
55 """Library class for parsing R scripts."""
56
57 def __init__(self, script):
58 """Initialize class Library."""
59 self.script = script
60 self.searchtext = "library"
61
62 def _prune_library(self, line):
63 """Prune line to get the names in library."""
64 import re
65 split_words = re.compile(r'\w+').findall(line)
66 lib = [w for w in split_words if w != "library"]
67 return lib[0]
68
69 def find_library(self):
70 """Parse library, to find and check requirements."""
71 lib = []
72 for i, line in enumerate(self.script):
73 line = line.strip()
74 if (self.searchtext in line) and (not line.startswith("#")):
75 lib_value = self._prune_library(line)
76 # if lib_value != "getopt": # getopt already exists
77 lib.append(lib_value)
78 return lib
79
80
81 class Input(object):
82 """Input class for parsing inputs."""
83
84 def __init__(self, script, example_command):
85 """Initialize Input with searchtext = input."""
86 self.script = script
87 self.example_command = example_command
88 self.searchtext = "input"
89
90 def find_inputs(self):
91 """Find inputs in example command.
92
93 This parses the R script and has NOTHING TO DO WITH kwds
94 """
95 opt_dict = parse_example_command(self.example_command)
96 inputs = {}
97 for key, value in opt_dict.iteritems():
98 if self.searchtext in key: # key here is "input"
99 for i, line in enumerate(self.script):
100 line = line.strip()
101 if (key in line) and (not line.startswith("#")):
102 # print >> sys.stderr, 'Line: %s\nkey: %s\nvalue: %s' % (line,key,value)
103 inputs[key] = value
104 else:
105 continue
106 # print >> sys.stderr, 'INPUTS: %s' % inputs
107 if not bool(inputs): # if inputs are empty
108 print("No inputs found in the Rscript, please specify inputs.")
109 return inputs
110
111
112 class Output(object):
113 """Output class for parsing outputs."""
114
115 def __init__(self, script, example_command):
116 """Initialize Input with searchtext - output."""
117 self.script = script
118 self.example_command = example_command
119 self.searchtext = "output"
120
121 def find_outputs(self):
122 """Find outputs in example command."""
123 opt_dict = parse_example_command(self.example_command)
124 outputs = {}
125 for key, value in opt_dict.iteritems():
126 if self.searchtext in key:
127 for i, line in enumerate(self.script):
128 line = line.strip()
129 if (key in line) and (not line.startswith("#")):
130 outputs[key] = value
131 else:
132 continue
133 # if not bool(outputs): # if outputs are empty
134 # print("No explicit outputs found, please specify outputs.")
135 return outputs
136
137
138 if __name__ == "__main__":
139 # TODO : Make sure tools with configfile are not used, this is not supported yet
140 test_file1 = "/Users/nturaga/Documents/galaxyproject/bioc-galaxy-integration/my_r_tool/my_r_tool.R"
141 test_file2 = "/Users/nturaga/Documents/galaxyproject/bioc-galaxy-integration/my_r_tool/my_r_tool_verbose.R"
142 test_file3 = "/Users/nturaga/Documents/galaxyproject/bioc-galaxy-integration/my_r_tool/my_r_tool_multi_inputs_outputs.R"
143 test_file4 = "/Users/nturaga/Documents/galaxyproject/bioc-galaxy-integration/my_r_tool/my_r_tool_fail_case.R"
144
145 # Test case with explicit input and outputs
146 print(" \n === Tool test 1 ==== \n ")
147 parse_rscript(test_file1, "Rscript my_r_tool.R --input input.csv --output output.csv")
148
149 # Test case with NO EXPLICIT OUTPUT
150 print(" \n === Tool test 2 ==== \n")
151 parse_rscript(test_file2, "Rscript my_r_tool_verbose.R --verbose TRUE --input intput.csv")
152
153 # Test case with tool which has to fail
154 print("\n == Tool test 4: Fail case ==== \n")
155 parse_rscript(test_file4, "Rscript my_r_tool_fail_case.R")