17
17
import logging
18
18
import os
19
19
import re
20
- from typing import Dict , NamedTuple , Optional
20
+ from typing import Dict , NamedTuple , Optional , TypedDict , Union
21
21
from urllib import parse as urlparse
22
22
23
23
from . import exc
@@ -125,11 +125,20 @@ def convert_pip_url(pip_url: str) -> VCSLocation:
125
125
return VCSLocation (url = url , rev = rev )
126
126
127
127
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
+
128
137
class GitRepo (BaseRepo ):
129
138
bin_name = "git"
130
139
schemes = ("git" , "git+http" , "git+https" , "git+ssh" , "git+git" , "git+file" )
131
140
132
- def __init__ (self , url , repo_dir , ** kwargs ):
141
+ def __init__ (self , url , repo_dir , remotes : RemotesArgs = None , ** kwargs ):
133
142
"""A git repository.
134
143
135
144
Parameters
@@ -145,6 +154,19 @@ def __init__(self, url, repo_dir, **kwargs):
145
154
if "tls_verify" not in kwargs :
146
155
self .tls_verify = False
147
156
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
+
148
170
BaseRepo .__init__ (self , url , repo_dir , ** kwargs )
149
171
150
172
@classmethod
@@ -161,6 +183,28 @@ def get_revision(self):
161
183
except exc .CommandError :
162
184
return "initial"
163
185
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
+
164
208
def obtain (self ):
165
209
"""Retrieve the repository, clone if doesn't exist."""
166
210
self .ensure_dir ()
@@ -182,6 +226,8 @@ def obtain(self):
182
226
cmd = ["submodule" , "update" , "--recursive" , "--init" ]
183
227
self .run (cmd , log_in_real_time = True )
184
228
229
+ self .set_remotes ()
230
+
185
231
def update_repo (self ):
186
232
self .ensure_dir ()
187
233
@@ -388,7 +434,7 @@ def remote(self, name, **kwargs) -> GitRemote:
388
434
except exc .LibVCSException :
389
435
return None
390
436
391
- def set_remote (self , name , url , overwrite = False ):
437
+ def set_remote (self , name , url , push : bool = False , overwrite = False ):
392
438
"""Set remote with name and URL like git remote add.
393
439
394
440
Parameters
0 commit comments