Repository: common-workflow-language/cwltool

Issue:
Staged files not accessible under Darwin
I have been creating files on-the-fly using the InitialWorkDirRequirement as described here:

http://www.commonwl.org/v1.0/UserGuide.html#Staging_input_files_in_the_output_directory

This works but I find that when I combine this with a DockerRequirement it stops working and I can no longer find the created file. Example:

```class: CommandLineTool
cwlVersion: v1.0
baseCommand: ["cat"]

requirements:
  - class: DockerRequirement
    dockerImageId: alpine
    dockerPull: alpine
  - class: InlineJavascriptRequirement
  - class: InitialWorkDirRequirement
    listing:
      - entryname: example.conf
        entry: |
          ${
            return inputs.test
          }


inputs:
  - id: test
    type: string
    inputBinding:
      valueFrom: "example.conf"
outputs: []
```
Input:

```test: "test string"```

If I do the same thing without the DockerRequirement I get:

```/usr/local/bin/cwltool 1.0.20161216212910
Resolved 'javascript_file2.cwl' to 'file:///Users/psaffrey/cwl_dev/cwl_examples/javascript_file2.cwl'
[job javascript_file2.cwl] /private/var/folders/dh/t5qjl_gx5tq3664vlgbgqplh0000gq/T/tmpYfWsl4$ cat \
    example.conf
test stringFinal process status is success
{}```

With the DockerRequirement I get this:

```/usr/local/bin/cwltool 1.0.20161216212910
Resolved 'javascript_file2.cwl' to 'file:///Users/psaffrey/cwl_dev/cwl_examples/javascript_file2.cwl'
[job javascript_file2.cwl] /var/folders/dh/t5qjl_gx5tq3664vlgbgqplh0000gq/T/tmpgx_NP_$ docker \
    run \
    -i \
    --volume=/private/var/folders/dh/t5qjl_gx5tq3664vlgbgqplh0000gq/T/tmpgx_NP_:/private/var/spool/cwl:rw \
    --volume=/private/var/folders/dh/t5qjl_gx5tq3664vlgbgqplh0000gq/T/tmpRpeEVS:/tmp:rw \
    --workdir=/private/var/spool/cwl \
    --read-only=true \
    --user=1000 \
    --rm \
    --env=TMPDIR=/tmp \
    --env=HOME=/private/var/spool/cwl \
    alpine \
    cat \
    example.conf
cat: can't open 'example.conf': No such file or directory
[job javascript_file2.cwl] completed permanentFail
Final process status is permanentFail
Workflow error, try again with --debug for more information:
Process status is ['permanentFail']```

Apparently this works on Linux, but not Darwin:

```$ docker --version
Docker version 1.10.1, build 9e83765
$ echo $OSTYPE 
darwin15
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1212```


Discussion:
This is not a CWL issue - it's to do with the way that Docker machine on mac uses its temp directories:

http://stackoverflow.com/questions/37673140/docker-volume-located-in-tmp-on-osx-empty

You can fix it by using the `--tmpdir-prefix` option.
@psaffrey-illumina Should we / can we do this automatically for `Darwin`?
I'm not sure - it's really a feature of the docker support on this platform. The problem is that you need to provide a `--tmpdir-prefix` (I think) in the user's home directory because this is the directory that is automatically mounted inside the VM that docker machine uses. 

I'm pretty sure this problem will also be seen in Windows machines using docker machine, but I gather cwltool isn't fully supported there yet either.

Resolving patch:
diff --git a/cwltool/argparser.py b/cwltool/argparser.py
--- a/cwltool/argparser.py
+++ b/cwltool/argparser.py
@@ -15,6 +15,9 @@
 
 _logger = logging.getLogger("cwltool")
 
+DEFAULT_TMP_PREFIX = "tmp"
+
+
 def arg_parser():  # type: () -> argparse.ArgumentParser
     parser = argparse.ArgumentParser(description='Reference executor for Common Workflow Language')
     parser.add_argument("--basedir", type=Text)
@@ -71,12 +74,12 @@ def arg_parser():  # type: () -> argparse.ArgumentParser
 
     parser.add_argument("--tmpdir-prefix", type=Text,
                         help="Path prefix for temporary directories",
-                        default="tmp")
+                        default=DEFAULT_TMP_PREFIX)
 
     exgroup = parser.add_mutually_exclusive_group()
     exgroup.add_argument("--tmp-outdir-prefix", type=Text,
                          help="Path prefix for intermediate output directories",
-                         default="tmp")
+                         default=DEFAULT_TMP_PREFIX)
 
     exgroup.add_argument("--cachedir", type=Text, default="",
                          help="Directory to cache intermediate workflow outputs to avoid recomputing steps.")
diff --git a/cwltool/main.py b/cwltool/main.py
--- a/cwltool/main.py
+++ b/cwltool/main.py
@@ -17,11 +17,12 @@
 import ruamel.yaml as yaml
 import schema_salad.validate as validate
 import six
+
 from schema_salad.ref_resolver import Loader, file_uri, uri_file_path
 from schema_salad.sourceline import strip_dup_lineno
 
 from . import draft2tool, workflow
-from .argparser import arg_parser, generate_parser
+from .argparser import arg_parser, generate_parser, DEFAULT_TMP_PREFIX
 from .cwlrdf import printdot, printrdf
 from .errors import UnsupportedRequirement, WorkflowException
 from .executors import SingleJobExecutor, MultithreadedJobExecutor
@@ -529,8 +530,16 @@ def main(argsl=None,  # type: List[str]
         if isinstance(tool, int):
             return tool
 
+        # If on MacOS platform, TMPDIR must be set to be under one of the shared volumes in Docker for Mac
+        # More info: https://dockstore.org/docs/faq
+        if sys.platform == "darwin":
+            tmp_prefix = "tmp_outdir_prefix"
+            default_mac_path = "/private/tmp/docker_tmp"
+            if getattr(args, tmp_prefix) and getattr(args, tmp_prefix) == DEFAULT_TMP_PREFIX:
+                setattr(args, tmp_prefix, default_mac_path)
+
         for dirprefix in ("tmpdir_prefix", "tmp_outdir_prefix", "cachedir"):
-            if getattr(args, dirprefix) and getattr(args, dirprefix) != 'tmp':
+            if getattr(args, dirprefix) and getattr(args, dirprefix) != DEFAULT_TMP_PREFIX:
                 sl = "/" if getattr(args, dirprefix).endswith("/") or dirprefix == "cachedir" else ""
                 setattr(args, dirprefix,
                         os.path.abspath(getattr(args, dirprefix)) + sl)


Test patch: