diff --git a/cwltool/main.py b/cwltool/main.py index d1d47c4de..7f219ee2c 100755 --- a/cwltool/main.py +++ b/cwltool/main.py @@ -241,7 +241,6 @@ def output_callback(out, processStatus): return final_output[0] - class FSAction(argparse.Action): objclass = None # type: Text @@ -294,8 +293,9 @@ class DirectoryAppendAction(FSAppendAction): objclass = "Directory" -def add_argument(toolparser, name, inptype, description="", default=None): - # type: (argparse.ArgumentParser, Text, Any, Text, Any) -> None +def add_argument(toolparser, name, inptype, records, description="", + default=None): + # type: (argparse.ArgumentParser, Text, Any, List[Text], Text, Any) -> None if len(name) == 1: flag = "-" else: @@ -329,12 +329,14 @@ def add_argument(toolparser, name, inptype, description="", default=None): elif isinstance(inptype, dict) and inptype["type"] == "enum": atype = Text elif isinstance(inptype, dict) and inptype["type"] == "record": + records.append(name) for field in inptype['fields']: fieldname = name+"."+shortname(field['name']) fieldtype = field['type'] fielddescription = field.get("doc", "") add_argument( - toolparser, fieldname, fieldtype, fielddescription) + toolparser, fieldname, fieldtype, records, + fielddescription) return if inptype == "string": atype = Text @@ -364,8 +366,8 @@ def add_argument(toolparser, name, inptype, description="", default=None): default=default, **typekw) -def generate_parser(toolparser, tool, namemap): - # type: (argparse.ArgumentParser, Process, Dict[Text, Text]) -> argparse.ArgumentParser +def generate_parser(toolparser, tool, namemap, records): + # type: (argparse.ArgumentParser, Process, Dict[Text, Text], List[Text]) -> argparse.ArgumentParser toolparser.add_argument("job_order", nargs="?", help="Job input json file") namemap["job_order"] = "job_order" @@ -375,7 +377,7 @@ def generate_parser(toolparser, tool, namemap): inptype = inp["type"] description = inp.get("doc", "") default = inp.get("default", None) - add_argument(toolparser, name, inptype, description, default) + add_argument(toolparser, name, inptype, records, description, default) return toolparser @@ -418,12 +420,23 @@ def load_job_order(args, t, stdin, print_input_deps=False, relative_deps=False, else: input_basedir = args.basedir if args.basedir else os.getcwd() namemap = {} # type: Dict[Text, Text] - toolparser = generate_parser(argparse.ArgumentParser(prog=args.workflow), t, namemap) + records = [] # type: List[Text] + toolparser = generate_parser( + argparse.ArgumentParser(prog=args.workflow), t, namemap, records) if toolparser: if args.tool_help: toolparser.print_help() return 0 cmd_line = vars(toolparser.parse_args(args.job_order)) + for record_name in records: + record = {} + record_items = { + k:v for k,v in cmd_line.iteritems() + if k.startswith(record_name)} + for key, value in record_items.iteritems(): + record[key[len(record_name)+1:]] = value + del cmd_line[key] + cmd_line[str(record_name)] = record if cmd_line["job_order"]: try: diff --git a/tests/test_toolargparse.py b/tests/test_toolargparse.py index 5c116f2c9..40983088a 100644 --- a/tests/test_toolargparse.py +++ b/tests/test_toolargparse.py @@ -58,6 +58,8 @@ class ToolArgparse(unittest.TestCase): one: File two: string +expression: $(inputs.foo.two) + outputs: [] ''' @@ -77,7 +79,7 @@ def test_bool(self): except SystemExit as e: self.assertEquals(e.code, 0) - def test_record(self): + def test_record_help(self): with NamedTemporaryFile() as f: f.write(self.script3) f.flush() @@ -86,6 +88,17 @@ def test_record(self): except SystemExit as e: self.assertEquals(e.code, 0) + def test_record(self): + with NamedTemporaryFile() as f: + f.write(self.script3) + f.flush() + try: + self.assertEquals(main([f.name, '--foo.one', 'README.rst', + '--foo.two', 'test']), 0) + except SystemExit as e: + self.assertEquals(e.code, 0) + + if __name__ == '__main__': unittest.main()