We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Excluding file with unsupported VCS
<!-- Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.
- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.
- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).

- **OS version and name**: Fedora 28
- **Poetry version**: 0.12.5
- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: https://gist.github.com/Lothiraldan/7e4c1ffde3ed90ec183ad4eb5e72a44c

## Issue
<!-- Now feel free to write your issue, but please be descriptive! Thanks again 🙌 ❤️ -->

Hello, first thank you for your work on poetry, packaging in Python is something we should be better at and poetry looks very promising.

I'm trying to use poetry with one of my project https://github.com/lothiraldan/balto which will include a compiled react project. I develop the project using Mercurial and then export the repository to Github.

The first time I ran `poetry build`, I saw that the nodes_modules directory was included so I try explictly excluding it with:

```toml
[tool.poetry]
exclude = ["balto/web_interfaces/balto_react/node_modules/**/*"]
```

But it didn't help.

I start taking a look at the code and found that the `find_excluded_files` early abort in case it didn't find the VCS (in my case Mercurial). Apart from adding Mercurial support (which I may do in the future), I think excluding files shouldn't depend on projects using a supported VCS.

I applied the following diff locally to still reads the explicitely excluded files that did the trick:

```diff
diff --git a/poetry/masonry/builders/builder.py b/poetry/masonry/builders/builder.py
index 627e006..477ec8d 100644
--- a/poetry/masonry/builders/builder.py
+++ b/poetry/masonry/builders/builder.py
@@ -43,14 +43,16 @@ class Builder(object):
         # Checking VCS
         vcs = get_vcs(self._path)
         if not vcs:
-            return []
+            vcs_ignored_files = []
+        else:
+            vcs_ignored_files = vcs.get_ignored_files()
 
         explicitely_excluded = []
         for excluded_glob in self._package.exclude:
             for excluded in self._path.glob(excluded_glob):
                 explicitely_excluded.append(excluded)
 
-        ignored = vcs.get_ignored_files() + explicitely_excluded
+        ignored = vcs_ignored_files + explicitely_excluded
         result = []
         for file in ignored:
             try:
```

I can send a PR with it if the code looks correct and the behavior change is ok.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `poetry/masonry/builders/builder.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 import os
3 import re
4 import shutil
5 import tempfile
6 
7 from collections import defaultdict
8 from contextlib import contextmanager
9 
10 from poetry.utils._compat import Path
11 from poetry.vcs import get_vcs
12 
13 from ..metadata import Metadata
14 from ..utils.module import Module
15 from ..utils.package_include import PackageInclude
16 
17 
18 AUTHOR_REGEX = re.compile(r"(?u)^(?P<name>[- .,\w\d'’\"()]+) <(?P<email>.+?)>$")
19 
20 
21 class Builder(object):
22 
23     AVAILABLE_PYTHONS = {"2", "2.7", "3", "3.4", "3.5", "3.6", "3.7"}
24 
25     def __init__(self, poetry, env, io):
26         self._poetry = poetry
27         self._env = env
28         self._io = io
29         self._package = poetry.package
30         self._path = poetry.file.parent
31         self._module = Module(
32             self._package.name,
33             self._path.as_posix(),
34             packages=self._package.packages,
35             includes=self._package.include,
36         )
37         self._meta = Metadata.from_package(self._package)
38 
39     def build(self):
40         raise NotImplementedError()
41 
42     def find_excluded_files(self):  # type: () -> list
43         # Checking VCS
44         vcs = get_vcs(self._path)
45         if not vcs:
46             return []
47 
48         explicitely_excluded = []
49         for excluded_glob in self._package.exclude:
50             for excluded in self._path.glob(excluded_glob):
51                 explicitely_excluded.append(excluded)
52 
53         ignored = vcs.get_ignored_files() + explicitely_excluded
54         result = []
55         for file in ignored:
56             try:
57                 file = Path(file).absolute().relative_to(self._path)
58             except ValueError:
59                 # Should only happen in tests
60                 continue
61 
62             result.append(file)
63 
64         return result
65 
66     def find_files_to_add(self, exclude_build=True):  # type: () -> list
67         """
68         Finds all files to add to the tarball
69         """
70         excluded = self.find_excluded_files()
71         to_add = []
72 
73         for include in self._module.includes:
74             for file in include.elements:
75                 if "__pycache__" in str(file):
76                     continue
77 
78                 if file.is_dir():
79                     continue
80 
81                 file = file.relative_to(self._path)
82 
83                 if file in excluded and isinstance(include, PackageInclude):
84                     continue
85 
86                 if file.suffix == ".pyc":
87                     continue
88 
89                 if file in to_add:
90                     # Skip duplicates
91                     continue
92 
93                 self._io.writeln(
94                     " - Adding: <comment>{}</comment>".format(str(file)),
95                     verbosity=self._io.VERBOSITY_VERY_VERBOSE,
96                 )
97                 to_add.append(file)
98 
99         # Include project files
100         self._io.writeln(
101             " - Adding: <comment>pyproject.toml</comment>",
102             verbosity=self._io.VERBOSITY_VERY_VERBOSE,
103         )
104         to_add.append(Path("pyproject.toml"))
105 
106         # If a license file exists, add it
107         for license_file in self._path.glob("LICENSE*"):
108             self._io.writeln(
109                 " - Adding: <comment>{}</comment>".format(
110                     license_file.relative_to(self._path)
111                 ),
112                 verbosity=self._io.VERBOSITY_VERY_VERBOSE,
113             )
114             to_add.append(license_file.relative_to(self._path))
115 
116         # If a README is specificed we need to include it
117         # to avoid errors
118         if "readme" in self._poetry.local_config:
119             readme = self._path / self._poetry.local_config["readme"]
120             if readme.exists():
121                 self._io.writeln(
122                     " - Adding: <comment>{}</comment>".format(
123                         readme.relative_to(self._path)
124                     ),
125                     verbosity=self._io.VERBOSITY_VERY_VERBOSE,
126                 )
127                 to_add.append(readme.relative_to(self._path))
128 
129         # If a build script is specified and explicitely required
130         # we add it to the list of files
131         if self._package.build and not exclude_build:
132             to_add.append(Path(self._package.build))
133 
134         return sorted(to_add)
135 
136     def convert_entry_points(self):  # type: () -> dict
137         result = defaultdict(list)
138 
139         # Scripts -> Entry points
140         for name, ep in self._poetry.local_config.get("scripts", {}).items():
141             extras = ""
142             if isinstance(ep, dict):
143                 extras = "[{}]".format(", ".join(ep["extras"]))
144                 ep = ep["callable"]
145 
146             result["console_scripts"].append("{} = {}{}".format(name, ep, extras))
147 
148         # Plugins -> entry points
149         plugins = self._poetry.local_config.get("plugins", {})
150         for groupname, group in plugins.items():
151             for name, ep in sorted(group.items()):
152                 result[groupname].append("{} = {}".format(name, ep))
153 
154         for groupname in result:
155             result[groupname] = sorted(result[groupname])
156 
157         return dict(result)
158 
159     @classmethod
160     def convert_author(cls, author):  # type: () -> dict
161         m = AUTHOR_REGEX.match(author)
162 
163         name = m.group("name")
164         email = m.group("email")
165 
166         return {"name": name, "email": email}
167 
168     @classmethod
169     @contextmanager
170     def temporary_directory(cls, *args, **kwargs):
171         try:
172             from tempfile import TemporaryDirectory
173 
174             with TemporaryDirectory(*args, **kwargs) as name:
175                 yield name
176         except ImportError:
177             name = tempfile.mkdtemp(*args, **kwargs)
178 
179             yield name
180 
181             shutil.rmtree(name)
182
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/poetry/masonry/builders/builder.py b/poetry/masonry/builders/builder.py
--- a/poetry/masonry/builders/builder.py
+++ b/poetry/masonry/builders/builder.py
@@ -43,14 +43,16 @@
         # Checking VCS
         vcs = get_vcs(self._path)
         if not vcs:
-            return []
+            vcs_ignored_files = []
+        else:
+            vcs_ignored_files = vcs.get_ignored_files()
 
         explicitely_excluded = []
         for excluded_glob in self._package.exclude:
             for excluded in self._path.glob(excluded_glob):
                 explicitely_excluded.append(excluded)
 
-        ignored = vcs.get_ignored_files() + explicitely_excluded
+        ignored = vcs_ignored_files + explicitely_excluded
         result = []
         for file in ignored:
             try:

{"golden_diff": "diff --git a/poetry/masonry/builders/builder.py b/poetry/masonry/builders/builder.py\n--- a/poetry/masonry/builders/builder.py\n+++ b/poetry/masonry/builders/builder.py\n@@ -43,14 +43,16 @@\n         # Checking VCS\n         vcs = get_vcs(self._path)\n         if not vcs:\n-            return []\n+            vcs_ignored_files = []\n+        else:\n+            vcs_ignored_files = vcs.get_ignored_files()\n \n         explicitely_excluded = []\n         for excluded_glob in self._package.exclude:\n             for excluded in self._path.glob(excluded_glob):\n                 explicitely_excluded.append(excluded)\n \n-        ignored = vcs.get_ignored_files() + explicitely_excluded\n+        ignored = vcs_ignored_files + explicitely_excluded\n         result = []\n         for file in ignored:\n             try:\n", "issue": "Excluding file with unsupported VCS\n<!-- Checked checkbox should look like this: [x] -->\r\n- [x] I am on the [latest](https://github.com/sdispater/poetry/releases/latest) Poetry version.\r\n- [x] I have searched the [issues](https://github.com/sdispater/poetry/issues) of this repo and believe that this is not a duplicate.\r\n- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).\r\n\r\n- **OS version and name**: Fedora 28\r\n- **Poetry version**: 0.12.5\r\n- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: https://gist.github.com/Lothiraldan/7e4c1ffde3ed90ec183ad4eb5e72a44c\r\n\r\n## Issue\r\n<!-- Now feel free to write your issue, but please be descriptive! Thanks again \ud83d\ude4c \u2764\ufe0f -->\r\n\r\nHello, first thank you for your work on poetry, packaging in Python is something we should be better at and poetry looks very promising.\r\n\r\nI'm trying to use poetry with one of my project https://github.com/lothiraldan/balto which will include a compiled react project. I develop the project using Mercurial and then export the repository to Github.\r\n\r\nThe first time I ran `poetry build`, I saw that the nodes_modules directory was included so I try explictly excluding it with:\r\n\r\n```toml\r\n[tool.poetry]\r\nexclude = [\"balto/web_interfaces/balto_react/node_modules/**/*\"]\r\n```\r\n\r\nBut it didn't help.\r\n\r\nI start taking a look at the code and found that the `find_excluded_files` early abort in case it didn't find the VCS (in my case Mercurial). Apart from adding Mercurial support (which I may do in the future), I think excluding files shouldn't depend on projects using a supported VCS.\r\n\r\nI applied the following diff locally to still reads the explicitely excluded files that did the trick:\r\n\r\n```diff\r\ndiff --git a/poetry/masonry/builders/builder.py b/poetry/masonry/builders/builder.py\r\nindex 627e006..477ec8d 100644\r\n--- a/poetry/masonry/builders/builder.py\r\n+++ b/poetry/masonry/builders/builder.py\r\n@@ -43,14 +43,16 @@ class Builder(object):\r\n         # Checking VCS\r\n         vcs = get_vcs(self._path)\r\n         if not vcs:\r\n-            return []\r\n+            vcs_ignored_files = []\r\n+        else:\r\n+            vcs_ignored_files = vcs.get_ignored_files()\r\n \r\n         explicitely_excluded = []\r\n         for excluded_glob in self._package.exclude:\r\n             for excluded in self._path.glob(excluded_glob):\r\n                 explicitely_excluded.append(excluded)\r\n \r\n-        ignored = vcs.get_ignored_files() + explicitely_excluded\r\n+        ignored = vcs_ignored_files + explicitely_excluded\r\n         result = []\r\n         for file in ignored:\r\n             try:\r\n```\r\n\r\nI can send a PR with it if the code looks correct and the behavior change is ok.\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport os\nimport re\nimport shutil\nimport tempfile\n\nfrom collections import defaultdict\nfrom contextlib import contextmanager\n\nfrom poetry.utils._compat import Path\nfrom poetry.vcs import get_vcs\n\nfrom ..metadata import Metadata\nfrom ..utils.module import Module\nfrom ..utils.package_include import PackageInclude\n\n\nAUTHOR_REGEX = re.compile(r\"(?u)^(?P<name>[- .,\\w\\d'\u2019\\\"()]+) <(?P<email>.+?)>$\")\n\n\nclass Builder(object):\n\n    AVAILABLE_PYTHONS = {\"2\", \"2.7\", \"3\", \"3.4\", \"3.5\", \"3.6\", \"3.7\"}\n\n    def __init__(self, poetry, env, io):\n        self._poetry = poetry\n        self._env = env\n        self._io = io\n        self._package = poetry.package\n        self._path = poetry.file.parent\n        self._module = Module(\n            self._package.name,\n            self._path.as_posix(),\n            packages=self._package.packages,\n            includes=self._package.include,\n        )\n        self._meta = Metadata.from_package(self._package)\n\n    def build(self):\n        raise NotImplementedError()\n\n    def find_excluded_files(self):  # type: () -> list\n        # Checking VCS\n        vcs = get_vcs(self._path)\n        if not vcs:\n            return []\n\n        explicitely_excluded = []\n        for excluded_glob in self._package.exclude:\n            for excluded in self._path.glob(excluded_glob):\n                explicitely_excluded.append(excluded)\n\n        ignored = vcs.get_ignored_files() + explicitely_excluded\n        result = []\n        for file in ignored:\n            try:\n                file = Path(file).absolute().relative_to(self._path)\n            except ValueError:\n                # Should only happen in tests\n                continue\n\n            result.append(file)\n\n        return result\n\n    def find_files_to_add(self, exclude_build=True):  # type: () -> list\n        \"\"\"\n        Finds all files to add to the tarball\n        \"\"\"\n        excluded = self.find_excluded_files()\n        to_add = []\n\n        for include in self._module.includes:\n            for file in include.elements:\n                if \"__pycache__\" in str(file):\n                    continue\n\n                if file.is_dir():\n                    continue\n\n                file = file.relative_to(self._path)\n\n                if file in excluded and isinstance(include, PackageInclude):\n                    continue\n\n                if file.suffix == \".pyc\":\n                    continue\n\n                if file in to_add:\n                    # Skip duplicates\n                    continue\n\n                self._io.writeln(\n                    \" - Adding: <comment>{}</comment>\".format(str(file)),\n                    verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n                )\n                to_add.append(file)\n\n        # Include project files\n        self._io.writeln(\n            \" - Adding: <comment>pyproject.toml</comment>\",\n            verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n        )\n        to_add.append(Path(\"pyproject.toml\"))\n\n        # If a license file exists, add it\n        for license_file in self._path.glob(\"LICENSE*\"):\n            self._io.writeln(\n                \" - Adding: <comment>{}</comment>\".format(\n                    license_file.relative_to(self._path)\n                ),\n                verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n            )\n            to_add.append(license_file.relative_to(self._path))\n\n        # If a README is specificed we need to include it\n        # to avoid errors\n        if \"readme\" in self._poetry.local_config:\n            readme = self._path / self._poetry.local_config[\"readme\"]\n            if readme.exists():\n                self._io.writeln(\n                    \" - Adding: <comment>{}</comment>\".format(\n                        readme.relative_to(self._path)\n                    ),\n                    verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n                )\n                to_add.append(readme.relative_to(self._path))\n\n        # If a build script is specified and explicitely required\n        # we add it to the list of files\n        if self._package.build and not exclude_build:\n            to_add.append(Path(self._package.build))\n\n        return sorted(to_add)\n\n    def convert_entry_points(self):  # type: () -> dict\n        result = defaultdict(list)\n\n        # Scripts -> Entry points\n        for name, ep in self._poetry.local_config.get(\"scripts\", {}).items():\n            extras = \"\"\n            if isinstance(ep, dict):\n                extras = \"[{}]\".format(\", \".join(ep[\"extras\"]))\n                ep = ep[\"callable\"]\n\n            result[\"console_scripts\"].append(\"{} = {}{}\".format(name, ep, extras))\n\n        # Plugins -> entry points\n        plugins = self._poetry.local_config.get(\"plugins\", {})\n        for groupname, group in plugins.items():\n            for name, ep in sorted(group.items()):\n                result[groupname].append(\"{} = {}\".format(name, ep))\n\n        for groupname in result:\n            result[groupname] = sorted(result[groupname])\n\n        return dict(result)\n\n    @classmethod\n    def convert_author(cls, author):  # type: () -> dict\n        m = AUTHOR_REGEX.match(author)\n\n        name = m.group(\"name\")\n        email = m.group(\"email\")\n\n        return {\"name\": name, \"email\": email}\n\n    @classmethod\n    @contextmanager\n    def temporary_directory(cls, *args, **kwargs):\n        try:\n            from tempfile import TemporaryDirectory\n\n            with TemporaryDirectory(*args, **kwargs) as name:\n                yield name\n        except ImportError:\n            name = tempfile.mkdtemp(*args, **kwargs)\n\n            yield name\n\n            shutil.rmtree(name)\n", "path": "poetry/masonry/builders/builder.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport os\nimport re\nimport shutil\nimport tempfile\n\nfrom collections import defaultdict\nfrom contextlib import contextmanager\n\nfrom poetry.utils._compat import Path\nfrom poetry.vcs import get_vcs\n\nfrom ..metadata import Metadata\nfrom ..utils.module import Module\nfrom ..utils.package_include import PackageInclude\n\n\nAUTHOR_REGEX = re.compile(r\"(?u)^(?P<name>[- .,\\w\\d'\u2019\\\"()]+) <(?P<email>.+?)>$\")\n\n\nclass Builder(object):\n\n    AVAILABLE_PYTHONS = {\"2\", \"2.7\", \"3\", \"3.4\", \"3.5\", \"3.6\", \"3.7\"}\n\n    def __init__(self, poetry, env, io):\n        self._poetry = poetry\n        self._env = env\n        self._io = io\n        self._package = poetry.package\n        self._path = poetry.file.parent\n        self._module = Module(\n            self._package.name,\n            self._path.as_posix(),\n            packages=self._package.packages,\n            includes=self._package.include,\n        )\n        self._meta = Metadata.from_package(self._package)\n\n    def build(self):\n        raise NotImplementedError()\n\n    def find_excluded_files(self):  # type: () -> list\n        # Checking VCS\n        vcs = get_vcs(self._path)\n        if not vcs:\n            vcs_ignored_files = []\n        else:\n            vcs_ignored_files = vcs.get_ignored_files()\n\n        explicitely_excluded = []\n        for excluded_glob in self._package.exclude:\n            for excluded in self._path.glob(excluded_glob):\n                explicitely_excluded.append(excluded)\n\n        ignored = vcs_ignored_files + explicitely_excluded\n        result = []\n        for file in ignored:\n            try:\n                file = Path(file).absolute().relative_to(self._path)\n            except ValueError:\n                # Should only happen in tests\n                continue\n\n            result.append(file)\n\n        return result\n\n    def find_files_to_add(self, exclude_build=True):  # type: () -> list\n        \"\"\"\n        Finds all files to add to the tarball\n        \"\"\"\n        excluded = self.find_excluded_files()\n        to_add = []\n\n        for include in self._module.includes:\n            for file in include.elements:\n                if \"__pycache__\" in str(file):\n                    continue\n\n                if file.is_dir():\n                    continue\n\n                file = file.relative_to(self._path)\n\n                if file in excluded and isinstance(include, PackageInclude):\n                    continue\n\n                if file.suffix == \".pyc\":\n                    continue\n\n                if file in to_add:\n                    # Skip duplicates\n                    continue\n\n                self._io.writeln(\n                    \" - Adding: <comment>{}</comment>\".format(str(file)),\n                    verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n                )\n                to_add.append(file)\n\n        # Include project files\n        self._io.writeln(\n            \" - Adding: <comment>pyproject.toml</comment>\",\n            verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n        )\n        to_add.append(Path(\"pyproject.toml\"))\n\n        # If a license file exists, add it\n        for license_file in self._path.glob(\"LICENSE*\"):\n            self._io.writeln(\n                \" - Adding: <comment>{}</comment>\".format(\n                    license_file.relative_to(self._path)\n                ),\n                verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n            )\n            to_add.append(license_file.relative_to(self._path))\n\n        # If a README is specificed we need to include it\n        # to avoid errors\n        if \"readme\" in self._poetry.local_config:\n            readme = self._path / self._poetry.local_config[\"readme\"]\n            if readme.exists():\n                self._io.writeln(\n                    \" - Adding: <comment>{}</comment>\".format(\n                        readme.relative_to(self._path)\n                    ),\n                    verbosity=self._io.VERBOSITY_VERY_VERBOSE,\n                )\n                to_add.append(readme.relative_to(self._path))\n\n        # If a build script is specified and explicitely required\n        # we add it to the list of files\n        if self._package.build and not exclude_build:\n            to_add.append(Path(self._package.build))\n\n        return sorted(to_add)\n\n    def convert_entry_points(self):  # type: () -> dict\n        result = defaultdict(list)\n\n        # Scripts -> Entry points\n        for name, ep in self._poetry.local_config.get(\"scripts\", {}).items():\n            extras = \"\"\n            if isinstance(ep, dict):\n                extras = \"[{}]\".format(\", \".join(ep[\"extras\"]))\n                ep = ep[\"callable\"]\n\n            result[\"console_scripts\"].append(\"{} = {}{}\".format(name, ep, extras))\n\n        # Plugins -> entry points\n        plugins = self._poetry.local_config.get(\"plugins\", {})\n        for groupname, group in plugins.items():\n            for name, ep in sorted(group.items()):\n                result[groupname].append(\"{} = {}\".format(name, ep))\n\n        for groupname in result:\n            result[groupname] = sorted(result[groupname])\n\n        return dict(result)\n\n    @classmethod\n    def convert_author(cls, author):  # type: () -> dict\n        m = AUTHOR_REGEX.match(author)\n\n        name = m.group(\"name\")\n        email = m.group(\"email\")\n\n        return {\"name\": name, \"email\": email}\n\n    @classmethod\n    @contextmanager\n    def temporary_directory(cls, *args, **kwargs):\n        try:\n            from tempfile import TemporaryDirectory\n\n            with TemporaryDirectory(*args, **kwargs) as name:\n                yield name\n        except ImportError:\n            name = tempfile.mkdtemp(*args, **kwargs)\n\n            yield name\n\n            shutil.rmtree(name)\n", "path": "poetry/masonry/builders/builder.py"}]}