We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Conan remote update command error in 1.15
With the Conan 1.15 release it is no longer possible to use the `conan remote update` command to ensure an existing remote is configured to be at the specified index. Reverting to Conan 1.14 sees the command work as expected.

    conan remote update ci-conan https://my-artifactory-instance.com/artifactory/api/conan/ci-conan --insert=0 
    ERROR: Remote 'ci-conan' already exists with same URL



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conans/client/cache/remote_registry.py`
Content:
```
1 import json
2 import os
3 from collections import OrderedDict, namedtuple
4 
5 from conans.errors import ConanException, NoRemoteAvailable
6 from conans.util.config_parser import get_bool_from_text_value
7 from conans.util.files import load, save
8 from conans.model.ref import PackageReference, ConanFileReference
9 
10 
11 Remote = namedtuple("Remote", "name url verify_ssl")
12 
13 
14 def load_registry_txt(contents):
15     """Remove in Conan 2.0"""
16     remotes = Remotes()
17     refs = {}
18     end_remotes = False
19     # Parse the file
20     for line in contents.splitlines():
21         line = line.strip()
22 
23         if not line:
24             if end_remotes:
25                 raise ConanException("Bad file format, blank line")
26             end_remotes = True
27             continue
28         chunks = line.split()
29         if not end_remotes:
30             if len(chunks) == 2:  # Retro compatibility
31                 remote_name, url = chunks
32                 verify_ssl = "True"
33             elif len(chunks) == 3:
34                 remote_name, url, verify_ssl = chunks
35             else:
36                 raise ConanException("Bad file format, wrong item numbers in line '%s'" % line)
37 
38             verify_ssl = get_bool_from_text_value(verify_ssl)
39             remotes.add(remote_name, url, verify_ssl)
40         else:
41             ref, remote_name = chunks
42             refs[ref] = remote_name
43 
44     return remotes, refs
45 
46 
47 def load_old_registry_json(contents):
48     """From json"""
49     data = json.loads(contents)
50     remotes = Remotes()
51     refs = data.get("references", {})
52     prefs = data.get("package_references", {})
53     for r in data["remotes"]:
54         remotes.add(r["name"], r["url"], r["verify_ssl"])
55     return remotes, refs, prefs
56 
57 
58 def migrate_registry_file(cache, out):
59     folder = cache.conan_folder
60     reg_json_path = os.path.join(folder, "registry.json")
61     reg_txt_path = os.path.join(folder, "registry.txt")
62     remotes_path = cache.registry_path
63 
64     def add_ref_remote(reference, remotes, remote_name):
65         ref = ConanFileReference.loads(reference, validate=True)
66         remote = remotes.get(remote_name)
67         if remote:
68             with cache.package_layout(ref).update_metadata() as metadata:
69                 metadata.recipe.remote = remote.name
70 
71     def add_pref_remote(pkg_ref, remotes, remote_name):
72         pref = PackageReference.loads(pkg_ref, validate=True)
73         remote = remotes.get(remote_name)
74         if remote:
75             with cache.package_layout(pref.ref).update_metadata() as metadata:
76                 metadata.packages[pref.id].remote = remote.name
77 
78     try:
79         if os.path.exists(reg_json_path):
80             out.warn("registry.json has been deprecated. Migrating to remotes.json")
81             remotes, refs, prefs = load_old_registry_json(load(reg_json_path))
82             remotes.save(remotes_path)
83             for ref, remote_name in refs.items():
84                 add_ref_remote(ref, remotes, remote_name)
85             for pref, remote_name in prefs.items():
86                 add_pref_remote(pref, remotes, remote_name)
87             os.remove(reg_json_path)
88         elif os.path.exists(reg_txt_path):
89             out.warn("registry.txt has been deprecated. Migrating to remotes.json")
90             remotes, refs = load_registry_txt(load(reg_txt_path))
91             remotes.save(remotes_path)
92             for ref, remote_name in refs.items():
93                 add_ref_remote(ref, remotes, remote_name)
94             os.remove(reg_txt_path)
95 
96     except Exception as e:
97         raise ConanException("Cannot migrate old registry: %s" % str(e))
98 
99 
100 class Remotes(object):
101     def __init__(self):
102         self._remotes = OrderedDict()
103         self.selected = None
104 
105     @classmethod
106     def defaults(cls):
107         result = Remotes()
108         result._remotes["conan-center"] = Remote("conan-center", "https://conan.bintray.com", True)
109         return result
110 
111     def select(self, remote_name):
112         self.selected = self[remote_name] if remote_name is not None else None
113 
114     def __bool__(self):
115         return bool(self._remotes)
116 
117     def __nonzero__(self):
118         return self.__bool__()
119 
120     def clear(self):
121         self._remotes.clear()
122 
123     def items(self):
124         return self._remotes.items()
125 
126     def values(self):
127         return self._remotes.values()
128 
129     @staticmethod
130     def loads(text):
131         result = Remotes()
132         data = json.loads(text)
133         for r in data.get("remotes", []):
134             result._remotes[r["name"]] = Remote(r["name"], r["url"], r["verify_ssl"])
135 
136         return result
137 
138     def dumps(self):
139         result = []
140         for remote in self._remotes.values():
141             result.append("%s: %s [Verify SSL: %s]" % (remote.name, remote.url, remote.verify_ssl))
142         return "\n".join(result)
143 
144     def save(self, filename):
145         ret = {"remotes": [{"name": r, "url": u, "verify_ssl": v}
146                            for r, (_, u, v) in self._remotes.items()]}
147         save(filename, json.dumps(ret, indent=True))
148 
149     def _get_by_url(self, url):
150         for remote in self._remotes.values():
151             if remote.url == url:
152                 return remote
153 
154     def rename(self, remote_name, new_remote_name):
155         if new_remote_name in self._remotes:
156             raise ConanException("Remote '%s' already exists" % new_remote_name)
157 
158         remote = self._remotes[remote_name]
159         new_remote = Remote(new_remote_name, remote.url, remote.verify_ssl)
160         self._remotes = OrderedDict([(new_remote_name, new_remote) if k == remote_name
161                                      else (k, v) for k, v in self._remotes.items()])
162 
163     def get_remote(self, remote_name):
164         # Returns the remote defined by the name, or the default if is None
165         return self[remote_name] if remote_name is not None else self.default
166 
167     @property
168     def default(self):
169         try:
170             # This is the python way to get the first element of an OrderedDict
171             return self._remotes[next(iter(self._remotes))]
172         except StopIteration:
173             raise NoRemoteAvailable("No default remote defined")
174 
175     def __contains__(self, remote_name):
176         return remote_name in self._remotes
177 
178     def get(self, remote_name):
179         return self._remotes.get(remote_name)
180 
181     def __getitem__(self, remote_name):
182         try:
183             return self._remotes[remote_name]
184         except KeyError:
185             raise NoRemoteAvailable("No remote '%s' defined in remotes" % (remote_name))
186 
187     def __delitem__(self, remote_name):
188         try:
189             del self._remotes[remote_name]
190         except KeyError:
191             raise NoRemoteAvailable("No remote '%s' defined in remotes" % (remote_name))
192 
193     def _upsert(self, remote_name, url, verify_ssl, insert):
194         # Remove duplicates
195         updated_remote = Remote(remote_name, url, verify_ssl)
196         self._remotes.pop(remote_name, None)
197         remotes_list = []
198         renamed = None
199 
200         for name, remote in self._remotes.items():
201             if remote.url != url:
202                 remotes_list.append((name, remote))
203             else:
204                 renamed = name
205 
206         if insert is not None:
207             try:
208                 insert_index = int(insert)
209             except ValueError:
210                 raise ConanException("insert argument must be an integer")
211             remotes_list.insert(insert_index, (remote_name, updated_remote))
212         else:
213             remotes_list.append((remote_name, updated_remote))
214         self._remotes = OrderedDict(remotes_list)
215         return renamed
216 
217     def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):
218         if force:
219             return self._upsert(remote_name, url, verify_ssl, insert)
220 
221         if remote_name in self._remotes:
222             raise ConanException("Remote '%s' already exists in remotes (use update to modify)"
223                                  % remote_name)
224         self._add_update(remote_name, url, verify_ssl, insert)
225 
226     def update(self, remote_name, url, verify_ssl=True, insert=None):
227         if remote_name not in self._remotes:
228             raise ConanException("Remote '%s' not found in remotes" % remote_name)
229         self._add_update(remote_name, url, verify_ssl, insert)
230 
231     def _add_update(self, remote_name, url, verify_ssl, insert=None):
232         prev_remote = self._get_by_url(url)
233         if prev_remote and verify_ssl == prev_remote.verify_ssl:
234             raise ConanException("Remote '%s' already exists with same URL" % prev_remote.name)
235         updated_remote = Remote(remote_name, url, verify_ssl)
236         if insert is not None:
237             try:
238                 insert_index = int(insert)
239             except ValueError:
240                 raise ConanException("insert argument must be an integer")
241             self._remotes.pop(remote_name, None)  # Remove if exists (update)
242             remotes_list = list(self._remotes.items())
243             remotes_list.insert(insert_index, (remote_name, updated_remote))
244             self._remotes = OrderedDict(remotes_list)
245         else:
246             self._remotes[remote_name] = updated_remote
247 
248 
249 class RemoteRegistry(object):
250 
251     def __init__(self, cache):
252         self._cache = cache
253         self._filename = cache.registry_path
254 
255     def load_remotes(self):
256         content = load(self._filename)
257         return Remotes.loads(content)
258 
259     def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):
260         remotes = self.load_remotes()
261         renamed = remotes.add(remote_name, url, verify_ssl, insert, force)
262         remotes.save(self._filename)
263         if renamed:
264             for ref in self._cache.all_refs():
265                 with self._cache.package_layout(ref).update_metadata() as metadata:
266                     if metadata.recipe.remote == renamed:
267                         metadata.recipe.remote = remote_name
268                     for pkg_metadata in metadata.packages.values():
269                         if pkg_metadata.remote == renamed:
270                             pkg_metadata.remote = remote_name
271 
272     def update(self, remote_name, url, verify_ssl=True, insert=None):
273         remotes = self.load_remotes()
274         remotes.update(remote_name, url, verify_ssl, insert)
275         remotes.save(self._filename)
276 
277     def clear(self):
278         remotes = self.load_remotes()
279         remotes.clear()
280         for ref in self._cache.all_refs():
281             with self._cache.package_layout(ref).update_metadata() as metadata:
282                 metadata.recipe.remote = None
283                 for pkg_metadata in metadata.packages.values():
284                     pkg_metadata.remote = None
285         remotes.save(self._filename)
286 
287     def remove(self, remote_name):
288         remotes = self.load_remotes()
289         del remotes[remote_name]
290 
291         for ref in self._cache.all_refs():
292             with self._cache.package_layout(ref).update_metadata() as metadata:
293                 if metadata.recipe.remote == remote_name:
294                     metadata.recipe.remote = None
295                 for pkg_metadata in metadata.packages.values():
296                     if pkg_metadata.remote == remote_name:
297                         pkg_metadata.remote = None
298 
299         remotes.save(self._filename)
300 
301     def define(self, remotes):
302         # For definition from conan config install
303         for ref in self._cache.all_refs():
304             with self._cache.package_layout(ref).update_metadata() as metadata:
305                 if metadata.recipe.remote not in remotes:
306                     metadata.recipe.remote = None
307                 for pkg_metadata in metadata.packages.values():
308                     if pkg_metadata.remote not in remotes:
309                         pkg_metadata.remote = None
310 
311         remotes.save(self._filename)
312 
313     def rename(self, remote_name, new_remote_name):
314         remotes = self.load_remotes()
315         remotes.rename(remote_name, new_remote_name)
316 
317         for ref in self._cache.all_refs():
318             with self._cache.package_layout(ref).update_metadata() as metadata:
319                 if metadata.recipe.remote == remote_name:
320                     metadata.recipe.remote = new_remote_name
321                 for pkg_metadata in metadata.packages.values():
322                     if pkg_metadata.remote == remote_name:
323                         pkg_metadata.remote = new_remote_name
324 
325         remotes.save(self._filename)
326 
327     @property
328     def refs_list(self):
329         result = {}
330         for ref in self._cache.all_refs():
331             metadata = self._cache.package_layout(ref).load_metadata()
332             if metadata.recipe.remote:
333                 result[ref] = metadata.recipe.remote
334         return result
335 
336     @property
337     def prefs_list(self):
338         result = {}
339         for ref in self._cache.all_refs():
340             metadata = self._cache.package_layout(ref).load_metadata()
341             for pid, pkg_metadata in metadata.packages.items():
342                 pref = PackageReference(ref, pid)
343                 result[pref] = pkg_metadata.remote
344         return result
345
```
--- 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/conans/client/cache/remote_registry.py b/conans/client/cache/remote_registry.py
--- a/conans/client/cache/remote_registry.py
+++ b/conans/client/cache/remote_registry.py
@@ -230,7 +230,7 @@
 
     def _add_update(self, remote_name, url, verify_ssl, insert=None):
         prev_remote = self._get_by_url(url)
-        if prev_remote and verify_ssl == prev_remote.verify_ssl:
+        if prev_remote and verify_ssl == prev_remote.verify_ssl and insert is None:
             raise ConanException("Remote '%s' already exists with same URL" % prev_remote.name)
         updated_remote = Remote(remote_name, url, verify_ssl)
         if insert is not None:

{"golden_diff": "diff --git a/conans/client/cache/remote_registry.py b/conans/client/cache/remote_registry.py\n--- a/conans/client/cache/remote_registry.py\n+++ b/conans/client/cache/remote_registry.py\n@@ -230,7 +230,7 @@\n \n     def _add_update(self, remote_name, url, verify_ssl, insert=None):\n         prev_remote = self._get_by_url(url)\n-        if prev_remote and verify_ssl == prev_remote.verify_ssl:\n+        if prev_remote and verify_ssl == prev_remote.verify_ssl and insert is None:\n             raise ConanException(\"Remote '%s' already exists with same URL\" % prev_remote.name)\n         updated_remote = Remote(remote_name, url, verify_ssl)\n         if insert is not None:\n", "issue": "Conan remote update command error in 1.15\nWith the Conan 1.15 release it is no longer possible to use the `conan remote update` command to ensure an existing remote is configured to be at the specified index. Reverting to Conan 1.14 sees the command work as expected.\r\n\r\n    conan remote update ci-conan https://my-artifactory-instance.com/artifactory/api/conan/ci-conan --insert=0 \r\n    ERROR: Remote 'ci-conan' already exists with same URL\r\n\r\n\n", "before_files": [{"content": "import json\nimport os\nfrom collections import OrderedDict, namedtuple\n\nfrom conans.errors import ConanException, NoRemoteAvailable\nfrom conans.util.config_parser import get_bool_from_text_value\nfrom conans.util.files import load, save\nfrom conans.model.ref import PackageReference, ConanFileReference\n\n\nRemote = namedtuple(\"Remote\", \"name url verify_ssl\")\n\n\ndef load_registry_txt(contents):\n    \"\"\"Remove in Conan 2.0\"\"\"\n    remotes = Remotes()\n    refs = {}\n    end_remotes = False\n    # Parse the file\n    for line in contents.splitlines():\n        line = line.strip()\n\n        if not line:\n            if end_remotes:\n                raise ConanException(\"Bad file format, blank line\")\n            end_remotes = True\n            continue\n        chunks = line.split()\n        if not end_remotes:\n            if len(chunks) == 2:  # Retro compatibility\n                remote_name, url = chunks\n                verify_ssl = \"True\"\n            elif len(chunks) == 3:\n                remote_name, url, verify_ssl = chunks\n            else:\n                raise ConanException(\"Bad file format, wrong item numbers in line '%s'\" % line)\n\n            verify_ssl = get_bool_from_text_value(verify_ssl)\n            remotes.add(remote_name, url, verify_ssl)\n        else:\n            ref, remote_name = chunks\n            refs[ref] = remote_name\n\n    return remotes, refs\n\n\ndef load_old_registry_json(contents):\n    \"\"\"From json\"\"\"\n    data = json.loads(contents)\n    remotes = Remotes()\n    refs = data.get(\"references\", {})\n    prefs = data.get(\"package_references\", {})\n    for r in data[\"remotes\"]:\n        remotes.add(r[\"name\"], r[\"url\"], r[\"verify_ssl\"])\n    return remotes, refs, prefs\n\n\ndef migrate_registry_file(cache, out):\n    folder = cache.conan_folder\n    reg_json_path = os.path.join(folder, \"registry.json\")\n    reg_txt_path = os.path.join(folder, \"registry.txt\")\n    remotes_path = cache.registry_path\n\n    def add_ref_remote(reference, remotes, remote_name):\n        ref = ConanFileReference.loads(reference, validate=True)\n        remote = remotes.get(remote_name)\n        if remote:\n            with cache.package_layout(ref).update_metadata() as metadata:\n                metadata.recipe.remote = remote.name\n\n    def add_pref_remote(pkg_ref, remotes, remote_name):\n        pref = PackageReference.loads(pkg_ref, validate=True)\n        remote = remotes.get(remote_name)\n        if remote:\n            with cache.package_layout(pref.ref).update_metadata() as metadata:\n                metadata.packages[pref.id].remote = remote.name\n\n    try:\n        if os.path.exists(reg_json_path):\n            out.warn(\"registry.json has been deprecated. Migrating to remotes.json\")\n            remotes, refs, prefs = load_old_registry_json(load(reg_json_path))\n            remotes.save(remotes_path)\n            for ref, remote_name in refs.items():\n                add_ref_remote(ref, remotes, remote_name)\n            for pref, remote_name in prefs.items():\n                add_pref_remote(pref, remotes, remote_name)\n            os.remove(reg_json_path)\n        elif os.path.exists(reg_txt_path):\n            out.warn(\"registry.txt has been deprecated. Migrating to remotes.json\")\n            remotes, refs = load_registry_txt(load(reg_txt_path))\n            remotes.save(remotes_path)\n            for ref, remote_name in refs.items():\n                add_ref_remote(ref, remotes, remote_name)\n            os.remove(reg_txt_path)\n\n    except Exception as e:\n        raise ConanException(\"Cannot migrate old registry: %s\" % str(e))\n\n\nclass Remotes(object):\n    def __init__(self):\n        self._remotes = OrderedDict()\n        self.selected = None\n\n    @classmethod\n    def defaults(cls):\n        result = Remotes()\n        result._remotes[\"conan-center\"] = Remote(\"conan-center\", \"https://conan.bintray.com\", True)\n        return result\n\n    def select(self, remote_name):\n        self.selected = self[remote_name] if remote_name is not None else None\n\n    def __bool__(self):\n        return bool(self._remotes)\n\n    def __nonzero__(self):\n        return self.__bool__()\n\n    def clear(self):\n        self._remotes.clear()\n\n    def items(self):\n        return self._remotes.items()\n\n    def values(self):\n        return self._remotes.values()\n\n    @staticmethod\n    def loads(text):\n        result = Remotes()\n        data = json.loads(text)\n        for r in data.get(\"remotes\", []):\n            result._remotes[r[\"name\"]] = Remote(r[\"name\"], r[\"url\"], r[\"verify_ssl\"])\n\n        return result\n\n    def dumps(self):\n        result = []\n        for remote in self._remotes.values():\n            result.append(\"%s: %s [Verify SSL: %s]\" % (remote.name, remote.url, remote.verify_ssl))\n        return \"\\n\".join(result)\n\n    def save(self, filename):\n        ret = {\"remotes\": [{\"name\": r, \"url\": u, \"verify_ssl\": v}\n                           for r, (_, u, v) in self._remotes.items()]}\n        save(filename, json.dumps(ret, indent=True))\n\n    def _get_by_url(self, url):\n        for remote in self._remotes.values():\n            if remote.url == url:\n                return remote\n\n    def rename(self, remote_name, new_remote_name):\n        if new_remote_name in self._remotes:\n            raise ConanException(\"Remote '%s' already exists\" % new_remote_name)\n\n        remote = self._remotes[remote_name]\n        new_remote = Remote(new_remote_name, remote.url, remote.verify_ssl)\n        self._remotes = OrderedDict([(new_remote_name, new_remote) if k == remote_name\n                                     else (k, v) for k, v in self._remotes.items()])\n\n    def get_remote(self, remote_name):\n        # Returns the remote defined by the name, or the default if is None\n        return self[remote_name] if remote_name is not None else self.default\n\n    @property\n    def default(self):\n        try:\n            # This is the python way to get the first element of an OrderedDict\n            return self._remotes[next(iter(self._remotes))]\n        except StopIteration:\n            raise NoRemoteAvailable(\"No default remote defined\")\n\n    def __contains__(self, remote_name):\n        return remote_name in self._remotes\n\n    def get(self, remote_name):\n        return self._remotes.get(remote_name)\n\n    def __getitem__(self, remote_name):\n        try:\n            return self._remotes[remote_name]\n        except KeyError:\n            raise NoRemoteAvailable(\"No remote '%s' defined in remotes\" % (remote_name))\n\n    def __delitem__(self, remote_name):\n        try:\n            del self._remotes[remote_name]\n        except KeyError:\n            raise NoRemoteAvailable(\"No remote '%s' defined in remotes\" % (remote_name))\n\n    def _upsert(self, remote_name, url, verify_ssl, insert):\n        # Remove duplicates\n        updated_remote = Remote(remote_name, url, verify_ssl)\n        self._remotes.pop(remote_name, None)\n        remotes_list = []\n        renamed = None\n\n        for name, remote in self._remotes.items():\n            if remote.url != url:\n                remotes_list.append((name, remote))\n            else:\n                renamed = name\n\n        if insert is not None:\n            try:\n                insert_index = int(insert)\n            except ValueError:\n                raise ConanException(\"insert argument must be an integer\")\n            remotes_list.insert(insert_index, (remote_name, updated_remote))\n        else:\n            remotes_list.append((remote_name, updated_remote))\n        self._remotes = OrderedDict(remotes_list)\n        return renamed\n\n    def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):\n        if force:\n            return self._upsert(remote_name, url, verify_ssl, insert)\n\n        if remote_name in self._remotes:\n            raise ConanException(\"Remote '%s' already exists in remotes (use update to modify)\"\n                                 % remote_name)\n        self._add_update(remote_name, url, verify_ssl, insert)\n\n    def update(self, remote_name, url, verify_ssl=True, insert=None):\n        if remote_name not in self._remotes:\n            raise ConanException(\"Remote '%s' not found in remotes\" % remote_name)\n        self._add_update(remote_name, url, verify_ssl, insert)\n\n    def _add_update(self, remote_name, url, verify_ssl, insert=None):\n        prev_remote = self._get_by_url(url)\n        if prev_remote and verify_ssl == prev_remote.verify_ssl:\n            raise ConanException(\"Remote '%s' already exists with same URL\" % prev_remote.name)\n        updated_remote = Remote(remote_name, url, verify_ssl)\n        if insert is not None:\n            try:\n                insert_index = int(insert)\n            except ValueError:\n                raise ConanException(\"insert argument must be an integer\")\n            self._remotes.pop(remote_name, None)  # Remove if exists (update)\n            remotes_list = list(self._remotes.items())\n            remotes_list.insert(insert_index, (remote_name, updated_remote))\n            self._remotes = OrderedDict(remotes_list)\n        else:\n            self._remotes[remote_name] = updated_remote\n\n\nclass RemoteRegistry(object):\n\n    def __init__(self, cache):\n        self._cache = cache\n        self._filename = cache.registry_path\n\n    def load_remotes(self):\n        content = load(self._filename)\n        return Remotes.loads(content)\n\n    def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):\n        remotes = self.load_remotes()\n        renamed = remotes.add(remote_name, url, verify_ssl, insert, force)\n        remotes.save(self._filename)\n        if renamed:\n            for ref in self._cache.all_refs():\n                with self._cache.package_layout(ref).update_metadata() as metadata:\n                    if metadata.recipe.remote == renamed:\n                        metadata.recipe.remote = remote_name\n                    for pkg_metadata in metadata.packages.values():\n                        if pkg_metadata.remote == renamed:\n                            pkg_metadata.remote = remote_name\n\n    def update(self, remote_name, url, verify_ssl=True, insert=None):\n        remotes = self.load_remotes()\n        remotes.update(remote_name, url, verify_ssl, insert)\n        remotes.save(self._filename)\n\n    def clear(self):\n        remotes = self.load_remotes()\n        remotes.clear()\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    pkg_metadata.remote = None\n        remotes.save(self._filename)\n\n    def remove(self, remote_name):\n        remotes = self.load_remotes()\n        del remotes[remote_name]\n\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote == remote_name:\n                    metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote == remote_name:\n                        pkg_metadata.remote = None\n\n        remotes.save(self._filename)\n\n    def define(self, remotes):\n        # For definition from conan config install\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote not in remotes:\n                    metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote not in remotes:\n                        pkg_metadata.remote = None\n\n        remotes.save(self._filename)\n\n    def rename(self, remote_name, new_remote_name):\n        remotes = self.load_remotes()\n        remotes.rename(remote_name, new_remote_name)\n\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote == remote_name:\n                    metadata.recipe.remote = new_remote_name\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote == remote_name:\n                        pkg_metadata.remote = new_remote_name\n\n        remotes.save(self._filename)\n\n    @property\n    def refs_list(self):\n        result = {}\n        for ref in self._cache.all_refs():\n            metadata = self._cache.package_layout(ref).load_metadata()\n            if metadata.recipe.remote:\n                result[ref] = metadata.recipe.remote\n        return result\n\n    @property\n    def prefs_list(self):\n        result = {}\n        for ref in self._cache.all_refs():\n            metadata = self._cache.package_layout(ref).load_metadata()\n            for pid, pkg_metadata in metadata.packages.items():\n                pref = PackageReference(ref, pid)\n                result[pref] = pkg_metadata.remote\n        return result\n", "path": "conans/client/cache/remote_registry.py"}], "after_files": [{"content": "import json\nimport os\nfrom collections import OrderedDict, namedtuple\n\nfrom conans.errors import ConanException, NoRemoteAvailable\nfrom conans.util.config_parser import get_bool_from_text_value\nfrom conans.util.files import load, save\nfrom conans.model.ref import PackageReference, ConanFileReference\n\n\nRemote = namedtuple(\"Remote\", \"name url verify_ssl\")\n\n\ndef load_registry_txt(contents):\n    \"\"\"Remove in Conan 2.0\"\"\"\n    remotes = Remotes()\n    refs = {}\n    end_remotes = False\n    # Parse the file\n    for line in contents.splitlines():\n        line = line.strip()\n\n        if not line:\n            if end_remotes:\n                raise ConanException(\"Bad file format, blank line\")\n            end_remotes = True\n            continue\n        chunks = line.split()\n        if not end_remotes:\n            if len(chunks) == 2:  # Retro compatibility\n                remote_name, url = chunks\n                verify_ssl = \"True\"\n            elif len(chunks) == 3:\n                remote_name, url, verify_ssl = chunks\n            else:\n                raise ConanException(\"Bad file format, wrong item numbers in line '%s'\" % line)\n\n            verify_ssl = get_bool_from_text_value(verify_ssl)\n            remotes.add(remote_name, url, verify_ssl)\n        else:\n            ref, remote_name = chunks\n            refs[ref] = remote_name\n\n    return remotes, refs\n\n\ndef load_old_registry_json(contents):\n    \"\"\"From json\"\"\"\n    data = json.loads(contents)\n    remotes = Remotes()\n    refs = data.get(\"references\", {})\n    prefs = data.get(\"package_references\", {})\n    for r in data[\"remotes\"]:\n        remotes.add(r[\"name\"], r[\"url\"], r[\"verify_ssl\"])\n    return remotes, refs, prefs\n\n\ndef migrate_registry_file(cache, out):\n    folder = cache.conan_folder\n    reg_json_path = os.path.join(folder, \"registry.json\")\n    reg_txt_path = os.path.join(folder, \"registry.txt\")\n    remotes_path = cache.registry_path\n\n    def add_ref_remote(reference, remotes, remote_name):\n        ref = ConanFileReference.loads(reference, validate=True)\n        remote = remotes.get(remote_name)\n        if remote:\n            with cache.package_layout(ref).update_metadata() as metadata:\n                metadata.recipe.remote = remote.name\n\n    def add_pref_remote(pkg_ref, remotes, remote_name):\n        pref = PackageReference.loads(pkg_ref, validate=True)\n        remote = remotes.get(remote_name)\n        if remote:\n            with cache.package_layout(pref.ref).update_metadata() as metadata:\n                metadata.packages[pref.id].remote = remote.name\n\n    try:\n        if os.path.exists(reg_json_path):\n            out.warn(\"registry.json has been deprecated. Migrating to remotes.json\")\n            remotes, refs, prefs = load_old_registry_json(load(reg_json_path))\n            remotes.save(remotes_path)\n            for ref, remote_name in refs.items():\n                add_ref_remote(ref, remotes, remote_name)\n            for pref, remote_name in prefs.items():\n                add_pref_remote(pref, remotes, remote_name)\n            os.remove(reg_json_path)\n        elif os.path.exists(reg_txt_path):\n            out.warn(\"registry.txt has been deprecated. Migrating to remotes.json\")\n            remotes, refs = load_registry_txt(load(reg_txt_path))\n            remotes.save(remotes_path)\n            for ref, remote_name in refs.items():\n                add_ref_remote(ref, remotes, remote_name)\n            os.remove(reg_txt_path)\n\n    except Exception as e:\n        raise ConanException(\"Cannot migrate old registry: %s\" % str(e))\n\n\nclass Remotes(object):\n    def __init__(self):\n        self._remotes = OrderedDict()\n        self.selected = None\n\n    @classmethod\n    def defaults(cls):\n        result = Remotes()\n        result._remotes[\"conan-center\"] = Remote(\"conan-center\", \"https://conan.bintray.com\", True)\n        return result\n\n    def select(self, remote_name):\n        self.selected = self[remote_name] if remote_name is not None else None\n\n    def __bool__(self):\n        return bool(self._remotes)\n\n    def __nonzero__(self):\n        return self.__bool__()\n\n    def clear(self):\n        self._remotes.clear()\n\n    def items(self):\n        return self._remotes.items()\n\n    def values(self):\n        return self._remotes.values()\n\n    @staticmethod\n    def loads(text):\n        result = Remotes()\n        data = json.loads(text)\n        for r in data.get(\"remotes\", []):\n            result._remotes[r[\"name\"]] = Remote(r[\"name\"], r[\"url\"], r[\"verify_ssl\"])\n\n        return result\n\n    def dumps(self):\n        result = []\n        for remote in self._remotes.values():\n            result.append(\"%s: %s [Verify SSL: %s]\" % (remote.name, remote.url, remote.verify_ssl))\n        return \"\\n\".join(result)\n\n    def save(self, filename):\n        ret = {\"remotes\": [{\"name\": r, \"url\": u, \"verify_ssl\": v}\n                           for r, (_, u, v) in self._remotes.items()]}\n        save(filename, json.dumps(ret, indent=True))\n\n    def _get_by_url(self, url):\n        for remote in self._remotes.values():\n            if remote.url == url:\n                return remote\n\n    def rename(self, remote_name, new_remote_name):\n        if new_remote_name in self._remotes:\n            raise ConanException(\"Remote '%s' already exists\" % new_remote_name)\n\n        remote = self._remotes[remote_name]\n        new_remote = Remote(new_remote_name, remote.url, remote.verify_ssl)\n        self._remotes = OrderedDict([(new_remote_name, new_remote) if k == remote_name\n                                     else (k, v) for k, v in self._remotes.items()])\n\n    def get_remote(self, remote_name):\n        # Returns the remote defined by the name, or the default if is None\n        return self[remote_name] if remote_name is not None else self.default\n\n    @property\n    def default(self):\n        try:\n            # This is the python way to get the first element of an OrderedDict\n            return self._remotes[next(iter(self._remotes))]\n        except StopIteration:\n            raise NoRemoteAvailable(\"No default remote defined\")\n\n    def __contains__(self, remote_name):\n        return remote_name in self._remotes\n\n    def get(self, remote_name):\n        return self._remotes.get(remote_name)\n\n    def __getitem__(self, remote_name):\n        try:\n            return self._remotes[remote_name]\n        except KeyError:\n            raise NoRemoteAvailable(\"No remote '%s' defined in remotes\" % (remote_name))\n\n    def __delitem__(self, remote_name):\n        try:\n            del self._remotes[remote_name]\n        except KeyError:\n            raise NoRemoteAvailable(\"No remote '%s' defined in remotes\" % (remote_name))\n\n    def _upsert(self, remote_name, url, verify_ssl, insert):\n        # Remove duplicates\n        updated_remote = Remote(remote_name, url, verify_ssl)\n        self._remotes.pop(remote_name, None)\n        remotes_list = []\n        renamed = None\n\n        for name, remote in self._remotes.items():\n            if remote.url != url:\n                remotes_list.append((name, remote))\n            else:\n                renamed = name\n\n        if insert is not None:\n            try:\n                insert_index = int(insert)\n            except ValueError:\n                raise ConanException(\"insert argument must be an integer\")\n            remotes_list.insert(insert_index, (remote_name, updated_remote))\n        else:\n            remotes_list.append((remote_name, updated_remote))\n        self._remotes = OrderedDict(remotes_list)\n        return renamed\n\n    def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):\n        if force:\n            return self._upsert(remote_name, url, verify_ssl, insert)\n\n        if remote_name in self._remotes:\n            raise ConanException(\"Remote '%s' already exists in remotes (use update to modify)\"\n                                 % remote_name)\n        self._add_update(remote_name, url, verify_ssl, insert)\n\n    def update(self, remote_name, url, verify_ssl=True, insert=None):\n        if remote_name not in self._remotes:\n            raise ConanException(\"Remote '%s' not found in remotes\" % remote_name)\n        self._add_update(remote_name, url, verify_ssl, insert)\n\n    def _add_update(self, remote_name, url, verify_ssl, insert=None):\n        prev_remote = self._get_by_url(url)\n        if prev_remote and verify_ssl == prev_remote.verify_ssl and insert is None:\n            raise ConanException(\"Remote '%s' already exists with same URL\" % prev_remote.name)\n        updated_remote = Remote(remote_name, url, verify_ssl)\n        if insert is not None:\n            try:\n                insert_index = int(insert)\n            except ValueError:\n                raise ConanException(\"insert argument must be an integer\")\n            self._remotes.pop(remote_name, None)  # Remove if exists (update)\n            remotes_list = list(self._remotes.items())\n            remotes_list.insert(insert_index, (remote_name, updated_remote))\n            self._remotes = OrderedDict(remotes_list)\n        else:\n            self._remotes[remote_name] = updated_remote\n\n\nclass RemoteRegistry(object):\n\n    def __init__(self, cache):\n        self._cache = cache\n        self._filename = cache.registry_path\n\n    def load_remotes(self):\n        content = load(self._filename)\n        return Remotes.loads(content)\n\n    def add(self, remote_name, url, verify_ssl=True, insert=None, force=None):\n        remotes = self.load_remotes()\n        renamed = remotes.add(remote_name, url, verify_ssl, insert, force)\n        remotes.save(self._filename)\n        if renamed:\n            for ref in self._cache.all_refs():\n                with self._cache.package_layout(ref).update_metadata() as metadata:\n                    if metadata.recipe.remote == renamed:\n                        metadata.recipe.remote = remote_name\n                    for pkg_metadata in metadata.packages.values():\n                        if pkg_metadata.remote == renamed:\n                            pkg_metadata.remote = remote_name\n\n    def update(self, remote_name, url, verify_ssl=True, insert=None):\n        remotes = self.load_remotes()\n        remotes.update(remote_name, url, verify_ssl, insert)\n        remotes.save(self._filename)\n\n    def clear(self):\n        remotes = self.load_remotes()\n        remotes.clear()\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    pkg_metadata.remote = None\n        remotes.save(self._filename)\n\n    def remove(self, remote_name):\n        remotes = self.load_remotes()\n        del remotes[remote_name]\n\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote == remote_name:\n                    metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote == remote_name:\n                        pkg_metadata.remote = None\n\n        remotes.save(self._filename)\n\n    def define(self, remotes):\n        # For definition from conan config install\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote not in remotes:\n                    metadata.recipe.remote = None\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote not in remotes:\n                        pkg_metadata.remote = None\n\n        remotes.save(self._filename)\n\n    def rename(self, remote_name, new_remote_name):\n        remotes = self.load_remotes()\n        remotes.rename(remote_name, new_remote_name)\n\n        for ref in self._cache.all_refs():\n            with self._cache.package_layout(ref).update_metadata() as metadata:\n                if metadata.recipe.remote == remote_name:\n                    metadata.recipe.remote = new_remote_name\n                for pkg_metadata in metadata.packages.values():\n                    if pkg_metadata.remote == remote_name:\n                        pkg_metadata.remote = new_remote_name\n\n        remotes.save(self._filename)\n\n    @property\n    def refs_list(self):\n        result = {}\n        for ref in self._cache.all_refs():\n            metadata = self._cache.package_layout(ref).load_metadata()\n            if metadata.recipe.remote:\n                result[ref] = metadata.recipe.remote\n        return result\n\n    @property\n    def prefs_list(self):\n        result = {}\n        for ref in self._cache.all_refs():\n            metadata = self._cache.package_layout(ref).load_metadata()\n            for pid, pkg_metadata in metadata.packages.items():\n                pref = PackageReference(ref, pid)\n                result[pref] = pkg_metadata.remote\n        return result\n", "path": "conans/client/cache/remote_registry.py"}]}