11"""
22Declare a git source.
33"""
4+ import logging
45import os
56import typing as tp
6- import logging
77from pathlib import Path
88
99import plumbum as pb
1818VarRemotes = tp .Union [str , tp .Dict [str , str ]]
1919Remotes = tp .Dict [str , str ]
2020
21+ _fetched_cache : tp .Set ['Git' ] = set ()
22+
2123
2224class Git (base .FetchableSource ):
2325 """
@@ -32,6 +34,7 @@ def __init__(
3234 limit : tp .Optional [int ] = 10 ,
3335 refspec : str = 'HEAD' ,
3436 shallow : bool = True ,
37+ submodule_set_urls : tp .Optional [tp .Dict [str , str ]] = None ,
3538 version_filter : tp .Callable [[str ], bool ] = lambda version : True
3639 ):
3740 super ().__init__ (local , remote )
@@ -40,6 +43,7 @@ def __init__(
4043 self .limit = limit
4144 self .refspec = refspec
4245 self .shallow = shallow
46+ self .submodule_set_urls = submodule_set_urls
4347 self .version_filter = version_filter
4448
4549 @property
@@ -62,18 +66,35 @@ def fetch(self) -> pb.LocalPath:
6266 str: [description]
6367 """
6468 prefix = base .target_prefix ()
65- clone = maybe_shallow (
66- git ['clone' , '--recurse-submodules' ], self .shallow
67- )
69+ clone = maybe_shallow (git ['clone' ], self .shallow )
6870 fetch = git ['fetch' , '--update-shallow' , '--all' ]
71+ checkout = git ['checkout' , '-f' , '--recurse-submodules' ]
72+ set_url = git ['submodule' , 'set-url' ]
73+ submodule_update = git ['submodule' , 'update' , '--init' , '--recursive' ]
74+
6975 flat_local = self .local .replace (os .sep , '-' )
7076 cache_path = pb .local .path (prefix ) / flat_local
7177
7278 if clone_needed (self .remote , cache_path ):
7379 clone (self .remote , cache_path )
74- else :
80+
7581 with pb .local .cwd (cache_path ):
76- fetch ()
82+ if "HEAD" not in self .refspec :
83+ checkout (self .refspec .split ('/' )[- 1 ])
84+
85+ if self .submodule_set_urls :
86+ for submodule , url in self .submodule_set_urls .items ():
87+ LOG .debug ('Setting url for submodule %s to %s.' , submodule , url )
88+ set_url (submodule , url )
89+ submodule_update ()
90+ else :
91+ if self in _fetched_cache :
92+ LOG .debug ('Already fetched %s, skipping.' , self .local )
93+ else :
94+ LOG .debug ('Fetching %s.' , self .local )
95+ _fetched_cache .add (self )
96+ with pb .local .cwd (cache_path ):
97+ fetch ()
7798
7899 return cache_path
79100
@@ -99,7 +120,9 @@ def version(self, target_dir: str, version: str = 'HEAD') -> pb.LocalPath:
99120 clone = git ['clone' ]
100121 pull = git ['pull' ]
101122 rev_parse = git ['rev-parse' ]
102- checkout = git ['checkout' ]
123+ set_url = git ['submodule' , 'set-url' ]
124+ submodule_update = git ['submodule' , 'update' , '--init' , '--recursive' ]
125+ checkout = git ['checkout' , '-f' ]
103126
104127 with pb .local .cwd (src_loc ):
105128 is_shallow = rev_parse ('--is-shallow-repository' ).strip ()
@@ -114,12 +137,15 @@ def version(self, target_dir: str, version: str = 'HEAD') -> pb.LocalPath:
114137 else :
115138 mkdir ('-p' , tgt_loc )
116139 with pb .local .cwd (tgt_loc ):
117- clone (
118- '--dissociate' , '--recurse-submodules' , '--reference' ,
119- src_loc , self .remote , '.'
120- )
140+ clone ('--dissociate' , '--reference' , src_loc , self .remote , '.' )
121141 checkout ('--detach' , version )
122142
143+ if self .submodule_set_urls :
144+ for submodule , url in self .submodule_set_urls .items ():
145+ LOG .debug ('Setting url for submodule %s to %s.' , submodule , url )
146+ set_url (submodule , url )
147+ submodule_update ()
148+
123149 ln ('-nsf' , tgt_subdir , active_loc )
124150 return tgt_loc
125151
0 commit comments