Skip to content

Commit e59538c

Browse files
authored
Merge pull request #1169 from common-workflow-language/argparser-require
Add input_required flag to main().
2 parents ecdfe1e + 2d7dd84 commit e59538c

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

cwltool/argparser.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,14 +394,16 @@ class DirectoryAppendAction(FSAppendAction):
394394

395395

396396
def add_argument(toolparser, name, inptype, records, description="",
397-
default=None):
398-
# type: (argparse.ArgumentParser, Text, Any, List[Text], Text, Any) -> None
397+
default=None, input_required=True):
398+
# type: (argparse.ArgumentParser, Text, Any, List[Text], Text, Any, bool) -> None
399399
if len(name) == 1:
400400
flag = "-"
401401
else:
402402
flag = "--"
403403

404-
required = default is None
404+
# if input_required is false, don't make the command line
405+
# parameter required.
406+
required = default is None and input_required
405407
if isinstance(inptype, MutableSequence):
406408
if inptype[0] == "null":
407409
required = False
@@ -462,8 +464,8 @@ def add_argument(toolparser, name, inptype, records, description="",
462464
default=default, **typekw)
463465

464466

465-
def generate_parser(toolparser, tool, namemap, records):
466-
# type: (argparse.ArgumentParser, Process, Dict[Text, Text], List[Text]) -> argparse.ArgumentParser
467+
def generate_parser(toolparser, tool, namemap, records, input_required=True):
468+
# type: (argparse.ArgumentParser, Process, Dict[Text, Text], List[Text], bool) -> argparse.ArgumentParser
467469
toolparser.add_argument("job_order", nargs="?", help="Job input json file")
468470
namemap["job_order"] = "job_order"
469471

@@ -473,6 +475,6 @@ def generate_parser(toolparser, tool, namemap, records):
473475
inptype = inp["type"]
474476
description = inp.get("doc", "")
475477
default = inp.get("default", None)
476-
add_argument(toolparser, name, inptype, records, description, default)
478+
add_argument(toolparser, name, inptype, records, description, default, input_required)
477479

478480
return toolparser

cwltool/main.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,15 @@ def init_job_order(job_order_object, # type: Optional[MutableMapping[Text
285285
relative_deps=False, # type: bool
286286
make_fs_access=StdFsAccess, # type: Callable[[Text], StdFsAccess]
287287
input_basedir="", # type: Text
288-
secret_store=None # type: Optional[SecretStore]
288+
secret_store=None, # type: Optional[SecretStore]
289+
input_required=True # type: bool
289290
): # type: (...) -> MutableMapping[Text, Any]
290291
secrets_req, _ = process.get_requirement("http://commonwl.org/cwltool#Secrets")
291292
if job_order_object is None:
292293
namemap = {} # type: Dict[Text, Text]
293294
records = [] # type: List[Text]
294295
toolparser = generate_parser(
295-
argparse.ArgumentParser(prog=args.workflow), process, namemap, records)
296+
argparse.ArgumentParser(prog=args.workflow), process, namemap, records, input_required)
296297
if args.tool_help:
297298
toolparser.print_help()
298299
exit(0)
@@ -490,7 +491,8 @@ def main(argsl=None, # type: Optional[List[str]]
490491
custom_schema_callback=None, # type: Optional[Callable[[], None]]
491492
executor=None, # type: Optional[JobExecutor]
492493
loadingContext=None, # type: Optional[LoadingContext]
493-
runtimeContext=None # type: Optional[RuntimeContext]
494+
runtimeContext=None, # type: Optional[RuntimeContext]
495+
input_required=True # type: bool
494496
): # type: (...) -> int
495497
if not stdout: # force UTF-8 even if the console is configured differently
496498
if (hasattr(sys.stdout, "encoding")
@@ -795,7 +797,8 @@ def my_represent_none(self, data): # pylint: disable=unused-argument
795797
relative_deps=args.relative_deps,
796798
make_fs_access=runtimeContext.make_fs_access,
797799
input_basedir=input_basedir,
798-
secret_store=runtimeContext.secret_store)
800+
secret_store=runtimeContext.secret_store,
801+
input_required=input_required)
799802
except SystemExit as err:
800803
return err.code
801804

tests/test_toolargparse.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import os
2+
import sys
23
from tempfile import NamedTemporaryFile
4+
from io import BytesIO, StringIO
35

46
import pytest
57
from cwltool.main import main
8+
import cwltool.executors
69

710
from .util import get_data, needs_docker
811

9-
1012
script_a = '''
1113
#!/usr/bin/env cwl-runner
1214
cwlVersion: v1.0
@@ -94,3 +96,43 @@ def test_argparse(name, script_contents, params, tmpdir):
9496
finally:
9597
if script and script.name and os.path.exists(script.name):
9698
os.unlink(script.name)
99+
100+
101+
class NoopJobExecutor(cwltool.executors.JobExecutor):
102+
def run_jobs(self,
103+
process, # type: Process
104+
job_order_object, # type: Dict[Text, Any]
105+
logger, # type: logging.Logger
106+
runtime_context # type: RuntimeContext
107+
): # type: (...) -> None
108+
pass
109+
110+
def execute(self,
111+
process, # type: Process
112+
job_order_object, # type: Dict[Text, Any]
113+
runtime_context, # type: RuntimeContext
114+
logger=None, # type: logging.Logger
115+
): # type: (...) -> Tuple[Optional[Union[Dict[Text, Any], List[Dict[Text, Any]]]], Text]
116+
return {}, "success"
117+
118+
def test_dont_require_inputs():
119+
if sys.version_info[0] < 3:
120+
stream = BytesIO()
121+
else:
122+
stream = StringIO()
123+
124+
script = None
125+
try:
126+
script = NamedTemporaryFile(mode='w', delete=False)
127+
script.write(script_a)
128+
script.close()
129+
130+
assert main(argsl=["--debug", script.name, "--input", script.name], executor=NoopJobExecutor(), stdout=stream) == 0
131+
assert main(argsl=["--debug", script.name], executor=NoopJobExecutor(), stdout=stream) == 2
132+
assert main(argsl=["--debug", script.name], executor=NoopJobExecutor(), input_required=False, stdout=stream) == 0
133+
134+
except SystemExit as err:
135+
assert err.code == 0, name
136+
finally:
137+
if script and script.name and os.path.exists(script.name):
138+
os.unlink(script.name)

0 commit comments

Comments
 (0)