Repository: iterative/dvc

Issue:
Image is not supported as a dependency
Version: `0.22.0+f9b30a`

I ran this command:
```
dvc run -d 2018-12-12-13:32:56.png -o derp 'echo derp > derp'
```

Where the dependency is:
```
2018-12-12-13:32:56.png: PNG image data, 1228 x 494, 8-bit/color RGBA, non-interlaced
```

And I got this:
```
Error: Failed to run command: Dependency '2018-12-12-13:32:56.png' is not supported
```

Is this intended? Why we aren't supporting images as dependencies?


Discussion:
look like it's a URL parser issue - '2018-12-12-13' is considered as a schema (http, https, etc)
@shcheklein is right, it is a urlparse issue. E.g.
```
>>> from urllib.parse import urlparse
>>> urlparse('2018-12-12-13:32:56.png').scheme
'2018-12-12-13'
```

Need to use our own regex when detecting dep type.
@efiop, what about just adding a `os.path.isfile('2018-12-12-13:32:56.png') ` before parsing it with urlparse? I think comming with our own regular expression would be harder to maintain than a sanity check.
Are there cases when we specify a dependency or an output (file) and it does not exist? In that scenario `os.path.isfile` would fail and dvc will throw a strange exception that dependency is not supported. 
> Are there cases when we specify a dependency or an output (file) and it does not exist? In that scenario `os.path.isfile` would fail and dvc will throw a strange exception that dependency is not supported.

Probably with `--no-exec`, @shcheklein :
```
dvc run --no-exec -d missing.txt -o also_missing.txt 'cp missing.txt also_missing.txt'
```

However, when you try to reproduce it, you'll encounter an error, because there's no way DVC can reproduce a stage without the dependencies.
Turns out it was actually an issue on our side. Our regex for the local dependency was not smart enough. I will send a patch for this soon.

The `--no-exec` is a good example of that. But we also need to know which remote type to use for specific dependency/output(mind that this issue also affects outputs) beforehand. We should simply not use regex for local ones at all, and instead, use it as a default type if it doesn't have some other supported schema.

Resolving patch:
diff --git a/dvc/dependency/__init__.py b/dvc/dependency/__init__.py
--- a/dvc/dependency/__init__.py
+++ b/dvc/dependency/__init__.py
@@ -5,7 +5,6 @@
 except ImportError:
     from urllib.parse import urlparse
 
-from dvc.exceptions import DvcException
 from dvc.config import Config
 
 from dvc.dependency.base import DependencyBase
@@ -25,9 +24,9 @@
     DependencyGS,
     DependencyHDFS,
     DependencyHTTP,
-    DependencyLOCAL,
     DependencyS3,
     DependencySSH,
+    # NOTE: DependencyLOCAL is the default choice
 ]
 
 DEP_MAP = {
@@ -60,7 +59,7 @@ def _get(stage, p, info):
     for d in DEPS:
         if d.supported(p):
             return d(stage, p, info)
-    raise DvcException('Dependency \'{}\' is not supported'.format(p))
+    return DependencyLOCAL(stage, p, info)
 
 
 def loadd_from(stage, d_list):
diff --git a/dvc/dependency/local.py b/dvc/dependency/local.py
--- a/dvc/dependency/local.py
+++ b/dvc/dependency/local.py
@@ -12,7 +12,7 @@
 
 
 class DependencyLOCAL(DependencyBase):
-    REGEX = r'^(?P<path>(/+|.:\\+)?[^:]*)$'
+    REGEX = r'^(?P<path>.*)$'
 
     DoesNotExistError = DependencyDoesNotExistError
     IsNotFileOrDirError = DependencyIsNotFileOrDirError
diff --git a/dvc/output/__init__.py b/dvc/output/__init__.py
--- a/dvc/output/__init__.py
+++ b/dvc/output/__init__.py
@@ -1,6 +1,5 @@
 import schema
 
-from dvc.exceptions import DvcException
 from dvc.config import Config
 
 from dvc.dependency import SCHEMA, urlparse
@@ -14,7 +13,13 @@
 from dvc.remote import Remote
 
 
-OUTS = [OutputHDFS, OutputS3, OutputGS, OutputSSH, OutputLOCAL]
+OUTS = [
+    OutputHDFS,
+    OutputS3,
+    OutputGS,
+    OutputSSH,
+    # NOTE: OutputLOCAL is the default choice
+]
 
 OUTS_MAP = {'hdfs': OutputHDFS,
             's3': OutputS3,
@@ -42,7 +47,7 @@ def _get(stage, p, info, cache, metric):
     for o in OUTS:
         if o.supported(p):
             return o(stage, p, info, cache=cache, remote=None, metric=metric)
-    raise DvcException('Output \'{}\' is not supported'.format(p))
+    return OutputLOCAL(stage, p, info, cache=cache, remote=None, metric=metric)
 
 
 def loadd_from(stage, d_list):


Test patch:
diff --git a/tests/test_dependency.py b/tests/test_dependency.py
--- a/tests/test_dependency.py
+++ b/tests/test_dependency.py
@@ -1,10 +1,15 @@
-from dvc.dependency import _get
-from dvc.exceptions import DvcException
+from dvc.stage import Stage
+from dvc.dependency import _get, DEP_MAP
 
-from tests.basic_env import TestDvc
+from tests.test_output import TestOutScheme
 
 
-class TestUnsupported(TestDvc):
-    def test(self):
-        with self.assertRaises(DvcException):
-            _get(None, 'unsupported://a/b', None)
+class TestDepScheme(TestOutScheme):
+    MAP = DEP_MAP
+
+    TESTS = TestOutScheme.TESTS.copy()
+    TESTS['http://example.com/path/to/file'] = 'http'
+    TESTS['https://example.com/path/to/file'] = 'https'
+
+    def _get(self, path):
+        return _get(Stage(self.dvc), path, None)
diff --git a/tests/test_output.py b/tests/test_output.py
--- a/tests/test_output.py
+++ b/tests/test_output.py
@@ -1,10 +1,30 @@
-from dvc.output import _get
-from dvc.exceptions import DvcException
+from dvc.stage import Stage
+from dvc.output import _get, OUTS_MAP
 
 from tests.basic_env import TestDvc
 
 
-class TestUnsupported(TestDvc):
+class TestOutScheme(TestDvc):
+    MAP = OUTS_MAP
+
+    TESTS = {
+        's3://bucket/path': 's3',
+        'gs://bucket/path': 'gs',
+        'ssh://example.com:/dir/path': 'ssh',
+        'hdfs://example.com/dir/path': 'hdfs',
+        'path/to/file': '',
+        'path\\to\\file': '',
+        'file': '',
+        './file': '',
+        '.\\file': '',
+        '../file': '',
+        '..\\file': '',
+        'unknown://path': '',
+    }
+
+    def _get(self, path):
+        return _get(Stage(self.dvc), path, None, None, None)
+
     def test(self):
-        with self.assertRaises(DvcException):
-            _get(None, 'unsupported://a/b', None, None, None)
+        for path, cls in self.TESTS.items():
+            self.assertIsInstance(self._get(path), self.MAP[cls])