|
79 | 79 | visit_class,
|
80 | 80 | windows_default_container_id,
|
81 | 81 | )
|
| 82 | +from .update import ORDERED_VERSIONS |
82 | 83 |
|
83 | 84 | if TYPE_CHECKING:
|
84 | 85 | from .provenance_profile import ProvenanceProfile # pylint: disable=unused-import
|
@@ -215,6 +216,9 @@ def revmap_file(
|
215 | 216 | else:
|
216 | 217 | return f
|
217 | 218 |
|
| 219 | + if "dirname" in f: |
| 220 | + del f["dirname"] |
| 221 | + |
218 | 222 | if "path" in f:
|
219 | 223 | path = cast(str, f["path"])
|
220 | 224 | uripath = file_uri(path)
|
@@ -444,6 +448,10 @@ def make_path_mapper(
|
444 | 448 | def updatePathmap(
|
445 | 449 | self, outdir: str, pathmap: PathMapper, fn: CWLObjectType
|
446 | 450 | ) -> None:
|
| 451 | + if not isinstance(fn, MutableMapping): |
| 452 | + raise WorkflowException( |
| 453 | + "Expected File or Directory object, was %s" % type(fn) |
| 454 | + ) |
447 | 455 | basename = cast(str, fn["basename"])
|
448 | 456 | if "location" in fn:
|
449 | 457 | location = cast(str, fn["location"])
|
@@ -607,20 +615,71 @@ def _initialworkdir(self, j: JobBase, builder: Builder) -> None:
|
607 | 615 | "Entry at index %s of listing is not a Dirent, File or Directory object, was %s"
|
608 | 616 | % (i, t2)
|
609 | 617 | )
|
| 618 | + if "basename" not in t3: |
| 619 | + continue |
| 620 | + basename = os.path.normpath(cast(str, t3["basename"])) |
| 621 | + t3["basename"] = basename |
| 622 | + if basename.startswith("../"): |
| 623 | + raise SourceLine( |
| 624 | + initialWorkdir, "listing", WorkflowException |
| 625 | + ).makeError( |
| 626 | + "Name '%s' at index %s of listing is invalid, cannot start with '../'" |
| 627 | + % (basename, i) |
| 628 | + ) |
| 629 | + if basename.startswith("/"): |
| 630 | + # only if DockerRequirement in requirements |
| 631 | + cwl_version = self.metadata.get( |
| 632 | + "http://commonwl.org/cwltool#original_cwlVersion", None |
| 633 | + ) |
| 634 | + if isinstance(cwl_version, str) and ORDERED_VERSIONS.index( |
| 635 | + cwl_version |
| 636 | + ) < ORDERED_VERSIONS.index("v1.2.0-dev4"): |
| 637 | + raise SourceLine( |
| 638 | + initialWorkdir, "listing", WorkflowException |
| 639 | + ).makeError( |
| 640 | + "Name '%s' at index %s of listing is invalid, paths starting with '/' only permitted in CWL 1.2 and later" |
| 641 | + % (basename, i) |
| 642 | + ) |
610 | 643 |
|
611 |
| - normalizeFilesDirs(ls) |
| 644 | + req, is_req = self.get_requirement("DockerRequirement") |
| 645 | + if is_req is not True: |
| 646 | + raise SourceLine( |
| 647 | + initialWorkdir, "listing", WorkflowException |
| 648 | + ).makeError( |
| 649 | + "Name '%s' at index %s of listing is invalid, name can only start with '/' when DockerRequirement is in 'requirements'" |
| 650 | + % (basename, i) |
| 651 | + ) |
612 | 652 |
|
613 |
| - j.generatefiles["listing"] = ls |
614 |
| - for entry in ls: |
615 |
| - self.updatePathmap( |
616 |
| - builder.outdir, cast(PathMapper, builder.pathmapper), entry |
617 |
| - ) |
| 653 | + with SourceLine(initialWorkdir, "listing", WorkflowException): |
| 654 | + j.generatefiles["listing"] = ls |
| 655 | + for entry in ls: |
| 656 | + if "basename" in entry: |
| 657 | + basename = cast(str, entry["basename"]) |
| 658 | + entry["dirname"] = os.path.join( |
| 659 | + builder.outdir, os.path.dirname(basename) |
| 660 | + ) |
| 661 | + entry["basename"] = os.path.basename(basename) |
| 662 | + normalizeFilesDirs(entry) |
| 663 | + self.updatePathmap( |
| 664 | + cast(Optional[str], entry.get("dirname")) or builder.outdir, |
| 665 | + cast(PathMapper, builder.pathmapper), |
| 666 | + entry, |
| 667 | + ) |
| 668 | + if "listing" in entry: |
618 | 669 |
|
619 |
| - visit_class( |
620 |
| - [builder.files, builder.bindings], |
621 |
| - ("File", "Directory"), |
622 |
| - partial(check_adjust, builder), |
623 |
| - ) |
| 670 | + def remove_dirname(d: CWLObjectType) -> None: |
| 671 | + if "dirname" in d: |
| 672 | + del d["dirname"] |
| 673 | + |
| 674 | + visit_class( |
| 675 | + entry["listing"], ("File", "Directory"), remove_dirname, |
| 676 | + ) |
| 677 | + |
| 678 | + visit_class( |
| 679 | + [builder.files, builder.bindings], |
| 680 | + ("File", "Directory"), |
| 681 | + partial(check_adjust, builder), |
| 682 | + ) |
624 | 683 |
|
625 | 684 | def job(
|
626 | 685 | self,
|
|
0 commit comments