We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
poetry export adds extra url multiple times
<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this; let's make sure of a few things.
  Please make sure the following boxes are ticked if they are correct.
  If not, please try and fulfill these first.
-->

<!-- 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).

<!--
  Once those are done, if you're able to fill in the following list with your information,
  it'd be very helpful to whoever handles the issue.
-->

- **OS version and name**: macOS Mojave 10.14.6
- **Poetry version**: 1.0.0b1
- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: I can't give this out as it's not open source, but I have a source in `[[tool.poetry.source]]` which is an internal pypi repo.

## Issue
If I run `poetry export -f requirements.txt` the result include the same `--extra-index-url` entry with the same URL at the top of the output once for each one of the packages in my poetry.lock. I suspect this is because poetry.lock (rightly) includes the same `[package.source]` entry for each dependency as they were downloaded from the source in `pyproject.toml` `[[tool.poetry.source]]`.

An interesting extra bit of information is that if I add `default = true` to the `[[tool.poetry.source]]` I only get one `--index-url` entry.

I'm also seeing some odd inconsistencies with the poetry.lock. When I deleted it and recreated it with the source set to default I got a poetry.lock with no (or at least fewer) sources. Running poetry update seemed to put them back. I'm now not able to reproduce this issue, though, so I'm not sure what exactly caused it.

--- 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/utils/exporter.py`
Content:
```
1 from typing import Union
2 
3 from clikit.api.io import IO
4 
5 from poetry.packages.directory_dependency import DirectoryDependency
6 from poetry.packages.file_dependency import FileDependency
7 from poetry.packages.url_dependency import URLDependency
8 from poetry.packages.vcs_dependency import VCSDependency
9 from poetry.poetry import Poetry
10 from poetry.utils._compat import Path
11 from poetry.utils._compat import decode
12 from poetry.utils.extras import get_extra_package_names
13 
14 
15 class Exporter(object):
16     """
17     Exporter class to export a lock file to alternative formats.
18     """
19 
20     ACCEPTED_FORMATS = ("requirements.txt",)
21     ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512")
22 
23     def __init__(self, poetry):  # type: (Poetry) -> None
24         self._poetry = poetry
25 
26     def export(
27         self,
28         fmt,
29         cwd,
30         output,
31         with_hashes=True,
32         dev=False,
33         extras=None,
34         with_credentials=False,
35     ):  # type: (str, Path, Union[IO, str], bool, bool, bool) -> None
36         if fmt not in self.ACCEPTED_FORMATS:
37             raise ValueError("Invalid export format: {}".format(fmt))
38 
39         getattr(self, "_export_{}".format(fmt.replace(".", "_")))(
40             cwd,
41             output,
42             with_hashes=with_hashes,
43             dev=dev,
44             extras=extras,
45             with_credentials=with_credentials,
46         )
47 
48     def _export_requirements_txt(
49         self,
50         cwd,
51         output,
52         with_hashes=True,
53         dev=False,
54         extras=None,
55         with_credentials=False,
56     ):  # type: (Path, Union[IO, str], bool, bool, bool) -> None
57         indexes = []
58         content = ""
59         packages = self._poetry.locker.locked_repository(dev).packages
60 
61         # Build a set of all packages required by our selected extras
62         extra_package_names = set(
63             get_extra_package_names(
64                 packages, self._poetry.locker.lock_data.get("extras", {}), extras or ()
65             )
66         )
67 
68         for package in sorted(packages, key=lambda p: p.name):
69             # If a package is optional and we haven't opted in to it, continue
70             if package.optional and package.name not in extra_package_names:
71                 continue
72 
73             if package.source_type == "git":
74                 dependency = VCSDependency(
75                     package.name,
76                     package.source_type,
77                     package.source_url,
78                     package.source_reference,
79                 )
80                 dependency.marker = package.marker
81                 line = "-e git+{}@{}#egg={}".format(
82                     package.source_url, package.source_reference, package.name
83                 )
84             elif package.source_type in ["directory", "file", "url"]:
85                 if package.source_type == "file":
86                     dependency = FileDependency(package.name, Path(package.source_url))
87                 elif package.source_type == "directory":
88                     dependency = DirectoryDependency(
89                         package.name, Path(package.source_url)
90                     )
91                 else:
92                     dependency = URLDependency(package.name, package.source_url)
93 
94                 dependency.marker = package.marker
95 
96                 line = "{}".format(package.source_url)
97                 if package.develop:
98                     line = "-e " + line
99             else:
100                 dependency = package.to_dependency()
101                 line = "{}=={}".format(package.name, package.version)
102 
103             requirement = dependency.to_pep_508()
104             if ";" in requirement:
105                 line += "; {}".format(requirement.split(";")[1].strip())
106 
107             if (
108                 package.source_type not in {"git", "directory", "file", "url"}
109                 and package.source_url
110             ):
111                 indexes.append(package.source_url)
112 
113             if package.files and with_hashes:
114                 hashes = []
115                 for f in package.files:
116                     h = f["hash"]
117                     algorithm = "sha256"
118                     if ":" in h:
119                         algorithm, h = h.split(":")
120 
121                         if algorithm not in self.ALLOWED_HASH_ALGORITHMS:
122                             continue
123 
124                     hashes.append("{}:{}".format(algorithm, h))
125 
126                 if hashes:
127                     line += " \\\n"
128                     for i, h in enumerate(hashes):
129                         line += "    --hash={}{}".format(
130                             h, " \\\n" if i < len(hashes) - 1 else ""
131                         )
132 
133             line += "\n"
134             content += line
135 
136         if indexes:
137             # If we have extra indexes, we add them to the begin
138             # of the output
139             indexes_header = ""
140             for index in indexes:
141                 repository = [
142                     r
143                     for r in self._poetry.pool.repositories
144                     if r.url == index.rstrip("/")
145                 ][0]
146                 if (
147                     self._poetry.pool.has_default()
148                     and repository is self._poetry.pool.repositories[0]
149                 ):
150                     url = (
151                         repository.authenticated_url
152                         if with_credentials
153                         else repository.url
154                     )
155                     indexes_header = "--index-url {}\n".format(url)
156                     continue
157 
158                 url = (
159                     repository.authenticated_url if with_credentials else repository.url
160                 )
161                 indexes_header += "--extra-index-url {}\n".format(url)
162 
163             content = indexes_header + "\n" + content
164 
165         self._output(content, cwd, output)
166 
167     def _output(
168         self, content, cwd, output
169     ):  # type: (str, Path, Union[IO, str]) -> None
170         decoded = decode(content)
171         try:
172             output.write(decoded)
173         except AttributeError:
174             filepath = cwd / output
175             with filepath.open("w", encoding="utf-8") as f:
176                 f.write(decoded)
177
```
--- 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/utils/exporter.py b/poetry/utils/exporter.py
--- a/poetry/utils/exporter.py
+++ b/poetry/utils/exporter.py
@@ -54,7 +54,7 @@
         extras=None,
         with_credentials=False,
     ):  # type: (Path, Union[IO, str], bool, bool, bool) -> None
-        indexes = []
+        indexes = set()
         content = ""
         packages = self._poetry.locker.locked_repository(dev).packages
 
@@ -108,7 +108,7 @@
                 package.source_type not in {"git", "directory", "file", "url"}
                 and package.source_url
             ):
-                indexes.append(package.source_url)
+                indexes.add(package.source_url)
 
             if package.files and with_hashes:
                 hashes = []
@@ -134,10 +134,9 @@
             content += line
 
         if indexes:
-            # If we have extra indexes, we add them to the begin
-            # of the output
+            # If we have extra indexes, we add them to the beginning of the output
             indexes_header = ""
-            for index in indexes:
+            for index in sorted(indexes):
                 repository = [
                     r
                     for r in self._poetry.pool.repositories

{"golden_diff": "diff --git a/poetry/utils/exporter.py b/poetry/utils/exporter.py\n--- a/poetry/utils/exporter.py\n+++ b/poetry/utils/exporter.py\n@@ -54,7 +54,7 @@\n         extras=None,\n         with_credentials=False,\n     ):  # type: (Path, Union[IO, str], bool, bool, bool) -> None\n-        indexes = []\n+        indexes = set()\n         content = \"\"\n         packages = self._poetry.locker.locked_repository(dev).packages\n \n@@ -108,7 +108,7 @@\n                 package.source_type not in {\"git\", \"directory\", \"file\", \"url\"}\n                 and package.source_url\n             ):\n-                indexes.append(package.source_url)\n+                indexes.add(package.source_url)\n \n             if package.files and with_hashes:\n                 hashes = []\n@@ -134,10 +134,9 @@\n             content += line\n \n         if indexes:\n-            # If we have extra indexes, we add them to the begin\n-            # of the output\n+            # If we have extra indexes, we add them to the beginning of the output\n             indexes_header = \"\"\n-            for index in indexes:\n+            for index in sorted(indexes):\n                 repository = [\n                     r\n                     for r in self._poetry.pool.repositories\n", "issue": "poetry export adds extra url multiple times\n<!--\r\n  Hi there! Thank you for discovering and submitting an issue.\r\n\r\n  Before you submit this; let's make sure of a few things.\r\n  Please make sure the following boxes are ticked if they are correct.\r\n  If not, please try and fulfill these first.\r\n-->\r\n\r\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<!--\r\n  Once those are done, if you're able to fill in the following list with your information,\r\n  it'd be very helpful to whoever handles the issue.\r\n-->\r\n\r\n- **OS version and name**: macOS Mojave 10.14.6\r\n- **Poetry version**: 1.0.0b1\r\n- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: I can't give this out as it's not open source, but I have a source in `[[tool.poetry.source]]` which is an internal pypi repo.\r\n\r\n## Issue\r\nIf I run `poetry export -f requirements.txt` the result include the same `--extra-index-url` entry with the same URL at the top of the output once for each one of the packages in my poetry.lock. I suspect this is because poetry.lock (rightly) includes the same `[package.source]` entry for each dependency as they were downloaded from the source in `pyproject.toml` `[[tool.poetry.source]]`.\r\n\r\nAn interesting extra bit of information is that if I add `default = true` to the `[[tool.poetry.source]]` I only get one `--index-url` entry.\r\n\r\nI'm also seeing some odd inconsistencies with the poetry.lock. When I deleted it and recreated it with the source set to default I got a poetry.lock with no (or at least fewer) sources. Running poetry update seemed to put them back. I'm now not able to reproduce this issue, though, so I'm not sure what exactly caused it.\n", "before_files": [{"content": "from typing import Union\n\nfrom clikit.api.io import IO\n\nfrom poetry.packages.directory_dependency import DirectoryDependency\nfrom poetry.packages.file_dependency import FileDependency\nfrom poetry.packages.url_dependency import URLDependency\nfrom poetry.packages.vcs_dependency import VCSDependency\nfrom poetry.poetry import Poetry\nfrom poetry.utils._compat import Path\nfrom poetry.utils._compat import decode\nfrom poetry.utils.extras import get_extra_package_names\n\n\nclass Exporter(object):\n    \"\"\"\n    Exporter class to export a lock file to alternative formats.\n    \"\"\"\n\n    ACCEPTED_FORMATS = (\"requirements.txt\",)\n    ALLOWED_HASH_ALGORITHMS = (\"sha256\", \"sha384\", \"sha512\")\n\n    def __init__(self, poetry):  # type: (Poetry) -> None\n        self._poetry = poetry\n\n    def export(\n        self,\n        fmt,\n        cwd,\n        output,\n        with_hashes=True,\n        dev=False,\n        extras=None,\n        with_credentials=False,\n    ):  # type: (str, Path, Union[IO, str], bool, bool, bool) -> None\n        if fmt not in self.ACCEPTED_FORMATS:\n            raise ValueError(\"Invalid export format: {}\".format(fmt))\n\n        getattr(self, \"_export_{}\".format(fmt.replace(\".\", \"_\")))(\n            cwd,\n            output,\n            with_hashes=with_hashes,\n            dev=dev,\n            extras=extras,\n            with_credentials=with_credentials,\n        )\n\n    def _export_requirements_txt(\n        self,\n        cwd,\n        output,\n        with_hashes=True,\n        dev=False,\n        extras=None,\n        with_credentials=False,\n    ):  # type: (Path, Union[IO, str], bool, bool, bool) -> None\n        indexes = []\n        content = \"\"\n        packages = self._poetry.locker.locked_repository(dev).packages\n\n        # Build a set of all packages required by our selected extras\n        extra_package_names = set(\n            get_extra_package_names(\n                packages, self._poetry.locker.lock_data.get(\"extras\", {}), extras or ()\n            )\n        )\n\n        for package in sorted(packages, key=lambda p: p.name):\n            # If a package is optional and we haven't opted in to it, continue\n            if package.optional and package.name not in extra_package_names:\n                continue\n\n            if package.source_type == \"git\":\n                dependency = VCSDependency(\n                    package.name,\n                    package.source_type,\n                    package.source_url,\n                    package.source_reference,\n                )\n                dependency.marker = package.marker\n                line = \"-e git+{}@{}#egg={}\".format(\n                    package.source_url, package.source_reference, package.name\n                )\n            elif package.source_type in [\"directory\", \"file\", \"url\"]:\n                if package.source_type == \"file\":\n                    dependency = FileDependency(package.name, Path(package.source_url))\n                elif package.source_type == \"directory\":\n                    dependency = DirectoryDependency(\n                        package.name, Path(package.source_url)\n                    )\n                else:\n                    dependency = URLDependency(package.name, package.source_url)\n\n                dependency.marker = package.marker\n\n                line = \"{}\".format(package.source_url)\n                if package.develop:\n                    line = \"-e \" + line\n            else:\n                dependency = package.to_dependency()\n                line = \"{}=={}\".format(package.name, package.version)\n\n            requirement = dependency.to_pep_508()\n            if \";\" in requirement:\n                line += \"; {}\".format(requirement.split(\";\")[1].strip())\n\n            if (\n                package.source_type not in {\"git\", \"directory\", \"file\", \"url\"}\n                and package.source_url\n            ):\n                indexes.append(package.source_url)\n\n            if package.files and with_hashes:\n                hashes = []\n                for f in package.files:\n                    h = f[\"hash\"]\n                    algorithm = \"sha256\"\n                    if \":\" in h:\n                        algorithm, h = h.split(\":\")\n\n                        if algorithm not in self.ALLOWED_HASH_ALGORITHMS:\n                            continue\n\n                    hashes.append(\"{}:{}\".format(algorithm, h))\n\n                if hashes:\n                    line += \" \\\\\\n\"\n                    for i, h in enumerate(hashes):\n                        line += \"    --hash={}{}\".format(\n                            h, \" \\\\\\n\" if i < len(hashes) - 1 else \"\"\n                        )\n\n            line += \"\\n\"\n            content += line\n\n        if indexes:\n            # If we have extra indexes, we add them to the begin\n            # of the output\n            indexes_header = \"\"\n            for index in indexes:\n                repository = [\n                    r\n                    for r in self._poetry.pool.repositories\n                    if r.url == index.rstrip(\"/\")\n                ][0]\n                if (\n                    self._poetry.pool.has_default()\n                    and repository is self._poetry.pool.repositories[0]\n                ):\n                    url = (\n                        repository.authenticated_url\n                        if with_credentials\n                        else repository.url\n                    )\n                    indexes_header = \"--index-url {}\\n\".format(url)\n                    continue\n\n                url = (\n                    repository.authenticated_url if with_credentials else repository.url\n                )\n                indexes_header += \"--extra-index-url {}\\n\".format(url)\n\n            content = indexes_header + \"\\n\" + content\n\n        self._output(content, cwd, output)\n\n    def _output(\n        self, content, cwd, output\n    ):  # type: (str, Path, Union[IO, str]) -> None\n        decoded = decode(content)\n        try:\n            output.write(decoded)\n        except AttributeError:\n            filepath = cwd / output\n            with filepath.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(decoded)\n", "path": "poetry/utils/exporter.py"}], "after_files": [{"content": "from typing import Union\n\nfrom clikit.api.io import IO\n\nfrom poetry.packages.directory_dependency import DirectoryDependency\nfrom poetry.packages.file_dependency import FileDependency\nfrom poetry.packages.url_dependency import URLDependency\nfrom poetry.packages.vcs_dependency import VCSDependency\nfrom poetry.poetry import Poetry\nfrom poetry.utils._compat import Path\nfrom poetry.utils._compat import decode\nfrom poetry.utils.extras import get_extra_package_names\n\n\nclass Exporter(object):\n    \"\"\"\n    Exporter class to export a lock file to alternative formats.\n    \"\"\"\n\n    ACCEPTED_FORMATS = (\"requirements.txt\",)\n    ALLOWED_HASH_ALGORITHMS = (\"sha256\", \"sha384\", \"sha512\")\n\n    def __init__(self, poetry):  # type: (Poetry) -> None\n        self._poetry = poetry\n\n    def export(\n        self,\n        fmt,\n        cwd,\n        output,\n        with_hashes=True,\n        dev=False,\n        extras=None,\n        with_credentials=False,\n    ):  # type: (str, Path, Union[IO, str], bool, bool, bool) -> None\n        if fmt not in self.ACCEPTED_FORMATS:\n            raise ValueError(\"Invalid export format: {}\".format(fmt))\n\n        getattr(self, \"_export_{}\".format(fmt.replace(\".\", \"_\")))(\n            cwd,\n            output,\n            with_hashes=with_hashes,\n            dev=dev,\n            extras=extras,\n            with_credentials=with_credentials,\n        )\n\n    def _export_requirements_txt(\n        self,\n        cwd,\n        output,\n        with_hashes=True,\n        dev=False,\n        extras=None,\n        with_credentials=False,\n    ):  # type: (Path, Union[IO, str], bool, bool, bool) -> None\n        indexes = set()\n        content = \"\"\n        packages = self._poetry.locker.locked_repository(dev).packages\n\n        # Build a set of all packages required by our selected extras\n        extra_package_names = set(\n            get_extra_package_names(\n                packages, self._poetry.locker.lock_data.get(\"extras\", {}), extras or ()\n            )\n        )\n\n        for package in sorted(packages, key=lambda p: p.name):\n            # If a package is optional and we haven't opted in to it, continue\n            if package.optional and package.name not in extra_package_names:\n                continue\n\n            if package.source_type == \"git\":\n                dependency = VCSDependency(\n                    package.name,\n                    package.source_type,\n                    package.source_url,\n                    package.source_reference,\n                )\n                dependency.marker = package.marker\n                line = \"-e git+{}@{}#egg={}\".format(\n                    package.source_url, package.source_reference, package.name\n                )\n            elif package.source_type in [\"directory\", \"file\", \"url\"]:\n                if package.source_type == \"file\":\n                    dependency = FileDependency(package.name, Path(package.source_url))\n                elif package.source_type == \"directory\":\n                    dependency = DirectoryDependency(\n                        package.name, Path(package.source_url)\n                    )\n                else:\n                    dependency = URLDependency(package.name, package.source_url)\n\n                dependency.marker = package.marker\n\n                line = \"{}\".format(package.source_url)\n                if package.develop:\n                    line = \"-e \" + line\n            else:\n                dependency = package.to_dependency()\n                line = \"{}=={}\".format(package.name, package.version)\n\n            requirement = dependency.to_pep_508()\n            if \";\" in requirement:\n                line += \"; {}\".format(requirement.split(\";\")[1].strip())\n\n            if (\n                package.source_type not in {\"git\", \"directory\", \"file\", \"url\"}\n                and package.source_url\n            ):\n                indexes.add(package.source_url)\n\n            if package.files and with_hashes:\n                hashes = []\n                for f in package.files:\n                    h = f[\"hash\"]\n                    algorithm = \"sha256\"\n                    if \":\" in h:\n                        algorithm, h = h.split(\":\")\n\n                        if algorithm not in self.ALLOWED_HASH_ALGORITHMS:\n                            continue\n\n                    hashes.append(\"{}:{}\".format(algorithm, h))\n\n                if hashes:\n                    line += \" \\\\\\n\"\n                    for i, h in enumerate(hashes):\n                        line += \"    --hash={}{}\".format(\n                            h, \" \\\\\\n\" if i < len(hashes) - 1 else \"\"\n                        )\n\n            line += \"\\n\"\n            content += line\n\n        if indexes:\n            # If we have extra indexes, we add them to the beginning of the output\n            indexes_header = \"\"\n            for index in sorted(indexes):\n                repository = [\n                    r\n                    for r in self._poetry.pool.repositories\n                    if r.url == index.rstrip(\"/\")\n                ][0]\n                if (\n                    self._poetry.pool.has_default()\n                    and repository is self._poetry.pool.repositories[0]\n                ):\n                    url = (\n                        repository.authenticated_url\n                        if with_credentials\n                        else repository.url\n                    )\n                    indexes_header = \"--index-url {}\\n\".format(url)\n                    continue\n\n                url = (\n                    repository.authenticated_url if with_credentials else repository.url\n                )\n                indexes_header += \"--extra-index-url {}\\n\".format(url)\n\n            content = indexes_header + \"\\n\" + content\n\n        self._output(content, cwd, output)\n\n    def _output(\n        self, content, cwd, output\n    ):  # type: (str, Path, Union[IO, str]) -> None\n        decoded = decode(content)\n        try:\n            output.write(decoded)\n        except AttributeError:\n            filepath = cwd / output\n            with filepath.open(\"w\", encoding=\"utf-8\") as f:\n                f.write(decoded)\n", "path": "poetry/utils/exporter.py"}]}