Skip to content

Commit 35c43e8

Browse files
committed
feat(GitRepo): Add remotes
1 parent 3c0f536 commit 35c43e8

File tree

1 file changed

+49
-3
lines changed

1 file changed

+49
-3
lines changed

libvcs/git.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import logging
1818
import os
1919
import re
20-
from typing import Dict, NamedTuple, Optional
20+
from typing import Dict, NamedTuple, Optional, TypedDict, Union
2121
from urllib import parse as urlparse
2222

2323
from . import exc
@@ -125,11 +125,20 @@ def convert_pip_url(pip_url: str) -> VCSLocation:
125125
return VCSLocation(url=url, rev=rev)
126126

127127

128+
class RemoteDict(TypedDict):
129+
fetch: str
130+
push: str
131+
132+
133+
FullRemoteDict = Dict[str, RemoteDict]
134+
RemotesArgs = Union[None, FullRemoteDict, Dict[str, str]]
135+
136+
128137
class GitRepo(BaseRepo):
129138
bin_name = "git"
130139
schemes = ("git", "git+http", "git+https", "git+ssh", "git+git", "git+file")
131140

132-
def __init__(self, url, repo_dir, **kwargs):
141+
def __init__(self, url, repo_dir, remotes: RemotesArgs = None, **kwargs):
133142
"""A git repository.
134143
135144
Parameters
@@ -145,6 +154,19 @@ def __init__(self, url, repo_dir, **kwargs):
145154
if "tls_verify" not in kwargs:
146155
self.tls_verify = False
147156

157+
self._remotes: Union[FullRemoteDict, None]
158+
159+
if remotes is None:
160+
self._remotes: FullRemoteDict = {"origin": url}
161+
elif isinstance(remotes, dict):
162+
self._remotes: FullRemoteDict = remotes
163+
for remote_name, url in remotes.items():
164+
if isinstance(str, dict):
165+
remotes[remote_name] = {
166+
"fetch": url,
167+
"push": url,
168+
}
169+
148170
BaseRepo.__init__(self, url, repo_dir, **kwargs)
149171

150172
@classmethod
@@ -161,6 +183,28 @@ def get_revision(self):
161183
except exc.CommandError:
162184
return "initial"
163185

186+
def set_remotes(self, overwrite: bool = False):
187+
remotes = self._remotes
188+
if isinstance(remotes, dict):
189+
for remote_name, url in remotes.items():
190+
existing_remote = self.remote(remote_name)
191+
if isinstance(url, dict) and "fetch" in url:
192+
if not existing_remote or existing_remote.fetch_url != url:
193+
self.set_remote(
194+
name=remote_name, url=url["fetch"], overwrite=overwrite
195+
)
196+
if "push" in url:
197+
if not existing_remote or existing_remote.push_url != url:
198+
self.set_remote(
199+
name=remote_name,
200+
url=url["push"],
201+
push=True,
202+
overwrite=overwrite,
203+
)
204+
else:
205+
if not existing_remote or existing_remote.fetch_url != url:
206+
self.set_remote(name=remote_name, url=url, overwrite=overwrite)
207+
164208
def obtain(self):
165209
"""Retrieve the repository, clone if doesn't exist."""
166210
self.ensure_dir()
@@ -182,6 +226,8 @@ def obtain(self):
182226
cmd = ["submodule", "update", "--recursive", "--init"]
183227
self.run(cmd, log_in_real_time=True)
184228

229+
self.set_remotes()
230+
185231
def update_repo(self):
186232
self.ensure_dir()
187233

@@ -388,7 +434,7 @@ def remote(self, name, **kwargs) -> GitRemote:
388434
except exc.LibVCSException:
389435
return None
390436

391-
def set_remote(self, name, url, overwrite=False):
437+
def set_remote(self, name, url, push: bool = False, overwrite=False):
392438
"""Set remote with name and URL like git remote add.
393439
394440
Parameters

0 commit comments

Comments
 (0)