Skip to content

Commit d91e812

Browse files
authored
--single-step: fix typo ; add --single-process (#1444)
1 parent be0869a commit d91e812

File tree

7 files changed

+77
-6
lines changed

7 files changed

+77
-6
lines changed

cwltool/argparser.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,16 @@ def arg_parser() -> argparse.ArgumentParser:
644644
help="Only executes a single step in a workflow. The input object must "
645645
"match that step's inputs. Can be combined with --print-subgraph.",
646646
)
647+
subgroup.add_argument(
648+
"--single-process",
649+
type=str,
650+
default=None,
651+
help="Only executes the underlying Process (CommandLineTool, "
652+
"ExpressionTool, or sub-Workflow) for the given step in a workflow. "
653+
"This will not include any step-level processing: scatter, when, no "
654+
"processing of step-level default, or valueFrom input modifiers. "
655+
"The input object must match that Process's inputs.",
656+
)
647657

648658
parser.add_argument(
649659
"--mpi-config-file",

cwltool/job.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
from io import IOBase
1616
from threading import Timer
1717
from typing import (
18+
IO,
1819
Callable,
1920
Dict,
20-
IO,
2121
Iterable,
2222
List,
2323
Mapping,

cwltool/main.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
get_container_from_software_requirements,
8282
)
8383
from .stdfsaccess import StdFsAccess
84-
from .subgraph import get_step, get_subgraph
84+
from .subgraph import get_process, get_step, get_subgraph
8585
from .update import ALLUPDATES, UPDATES
8686
from .utils import (
8787
DEFAULT_TMP_PREFIX,
@@ -811,7 +811,7 @@ def choose_step(
811811
if isinstance(tool, Workflow):
812812
url = urllib.parse.urlparse(tool.tool["id"])
813813
if url.fragment:
814-
extracted = get_step(tool, tool.tool["id"] + "/" + args.singe_step)
814+
extracted = get_step(tool, tool.tool["id"] + "/" + args.single_step)
815815
else:
816816
extracted = get_step(
817817
tool,
@@ -831,6 +831,43 @@ def choose_step(
831831
return tool
832832

833833

834+
def choose_process(
835+
args: argparse.Namespace,
836+
tool: Process,
837+
loadingContext: LoadingContext,
838+
) -> Optional[Process]:
839+
"""Walk the given Workflow and extract just args.single_step."""
840+
if loadingContext.loader is None:
841+
raise Exception("loadingContext.loader cannot be None")
842+
843+
if isinstance(tool, Workflow):
844+
url = urllib.parse.urlparse(tool.tool["id"])
845+
if url.fragment:
846+
extracted = get_process(
847+
tool,
848+
tool.tool["id"] + "/" + args.single_process,
849+
loadingContext.loader.idx,
850+
)
851+
else:
852+
extracted = get_process(
853+
tool,
854+
loadingContext.loader.fetcher.urljoin(
855+
tool.tool["id"], "#" + args.single_process
856+
),
857+
loadingContext.loader.idx,
858+
)
859+
else:
860+
_logger.error("Can only use --single-process on Workflows")
861+
return None
862+
if isinstance(loadingContext.loader.idx, MutableMapping):
863+
loadingContext.loader.idx[extracted["id"]] = extracted
864+
tool = make_tool(extracted["id"], loadingContext)
865+
else:
866+
raise Exception("Missing loadingContext.loader.idx!")
867+
868+
return tool
869+
870+
834871
def check_working_directories(
835872
runtimeContext: RuntimeContext,
836873
) -> Optional[int]:
@@ -1068,6 +1105,13 @@ def main(
10681105
else:
10691106
tool = ctool
10701107

1108+
elif args.single_process:
1109+
ctool = choose_process(args, tool, loadingContext)
1110+
if ctool is None:
1111+
return 1
1112+
else:
1113+
tool = ctool
1114+
10711115
if args.print_subgraph:
10721116
if "name" in tool.tool:
10731117
del tool.tool["name"]

cwltool/subgraph.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import urllib
22
from collections import namedtuple
33
from typing import (
4+
Any,
45
Dict,
56
List,
7+
Mapping,
68
MutableMapping,
79
MutableSequence,
810
Optional,
@@ -191,3 +193,17 @@ def get_step(tool: Workflow, step_id: str) -> CommentedMap:
191193
extracted[f] = tool.tool[f]
192194

193195
return extracted
196+
197+
198+
def get_process(tool: Workflow, step_id: str, index: Mapping[str, Any]) -> Any:
199+
"""Return just a single Process from a Workflow step."""
200+
step = find_step(tool.steps, step_id)
201+
if step is None:
202+
raise Exception(f"Step {step_id} was not found")
203+
204+
run = step["run"]
205+
206+
if isinstance(run, str):
207+
return index[run]
208+
else:
209+
return run

tests/test_environment.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""Test passing of environment variables to tools."""
2-
from abc import ABC, abstractmethod
32
import os
3+
from abc import ABC, abstractmethod
44
from pathlib import Path
55
from typing import Any, Callable, Dict, Iterator, List, Mapping, Set, Union, cast
66

77
import pytest
88

99
from cwltool.singularity import get_version
10+
1011
from .util import env_accepts_null, get_tool_env, needs_docker, needs_singularity
1112

1213
# None => accept anything, just require the key is present

tests/test_singularity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests to find local Singularity image."""
2-
import shutil
32
import os
3+
import shutil
44
from pathlib import Path
55
from typing import Any
66

tests/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import os
66
import shutil
77
import subprocess
8-
from pathlib import Path
98
import sys
9+
from pathlib import Path
1010
from typing import Dict, Generator, List, Mapping, Optional, Tuple, Union
1111

1212
import pytest

0 commit comments

Comments
 (0)