@@ -20,14 +20,16 @@ def __init__(
20
20
name : str ,
21
21
force_rebuild : bool = False ,
22
22
no_suffix_src : bool = False ,
23
+ shallow_clone : bool = False ,
23
24
) -> None :
24
25
self ._url = url
25
26
self ._ref = ref
26
27
self ._directory = directory
27
28
self ._name = name
28
29
self ._force_rebuild = force_rebuild
29
30
self ._no_suffix_src = no_suffix_src
30
- self ._rebuild_needed = self ._git_clone ()
31
+ self ._shallow_clone = shallow_clone
32
+ self ._rebuild_needed = self ._setup_repo ()
31
33
32
34
@property
33
35
def src_dir (self ) -> Path :
@@ -128,42 +130,80 @@ def install(self) -> None:
128
130
"""Installs the project."""
129
131
run (f"cmake --install { self .build_dir } " )
130
132
131
- def _git_clone (self ) -> bool :
133
+ def _git_clone (self ) -> None :
134
+ """Clone the git repository."""
135
+ try :
136
+ log .debug (f"Cloning { self ._url } into { self .src_dir } at commit { self ._ref } " )
137
+ git_clone_cmd = "git clone --recursive"
138
+ if self ._shallow_clone :
139
+ git_clone_cmd += f" --depth 1 --branch { self ._ref } "
140
+ git_clone_cmd += f" { self ._url } { self .src_dir } "
141
+ run (git_clone_cmd )
142
+ run (f"git checkout { self ._ref } " , cwd = self .src_dir )
143
+ log .debug (f"Cloned { self ._url } into { self .src_dir } at commit { self ._ref } " )
144
+ except Exception as e :
145
+ log .error (f"Failed to clone repository { self ._url } : { e } " )
146
+ raise
147
+
148
+ def _git_fetch (self ) -> None :
149
+ """Fetch the latest changes from the remote repository."""
150
+ try :
151
+ log .debug (f"Fetching latest changes for { self ._url } in { self .src_dir } " )
152
+ run ("git fetch" , cwd = self .src_dir )
153
+ run ("git reset --hard" , cwd = self .src_dir )
154
+ run (f"git checkout { self ._ref } " , cwd = self .src_dir )
155
+ log .debug (f"Fetched latest changes for { self ._url } in { self .src_dir } " )
156
+ except Exception as e :
157
+ log .error (f"Failed to fetch updates for repository { self ._url } : { e } " )
158
+ raise
159
+
160
+ def _setup_repo (self ) -> bool :
132
161
"""Clone a git repository into a specified directory at a specific commit.
133
162
Returns:
134
163
bool: True if the repository was cloned or updated, False if it was already up-to-date.
135
164
"""
136
- log .debug (f"Cloning { self ._url } into { self .src_dir } at commit { self ._ref } " )
137
- if self .src_dir .exists () and Path (self .src_dir , ".git" ).exists ():
165
+ if not self .src_dir .exists ():
166
+ self ._git_clone ()
167
+ return True
168
+ elif Path (self .src_dir , ".git" ).exists ():
138
169
log .debug (
139
170
f"Repository { self ._url } already exists at { self .src_dir } , checking for updates."
140
171
)
141
- run ("git fetch" , cwd = self .src_dir )
142
- target_commit = (
143
- run (f"git rev-parse { self ._ref } " , cwd = self .src_dir )
172
+ current_commit = (
173
+ run ("git rev-parse HEAD^{commit}" , cwd = self .src_dir )
144
174
.stdout .decode ()
145
175
.strip ()
146
176
)
147
- current_commit = (
148
- run ("git rev-parse HEAD" , cwd = self .src_dir ).stdout .decode ().strip ()
149
- )
150
- if current_commit != target_commit :
151
- log .debug (
152
- f"Current commit { current_commit } does not match target { target_commit } , checking out { self ._ref } ."
177
+ try :
178
+ target_commit = (
179
+ run (f"git rev-parse { self ._ref } ^{{commit}}" , cwd = self .src_dir )
180
+ .stdout .decode ()
181
+ .strip ()
182
+ )
183
+ if current_commit != target_commit :
184
+ log .debug (
185
+ f"Current commit { current_commit } does not match target { target_commit } , checking out { self ._ref } ."
186
+ )
187
+ run ("git reset --hard" , cwd = self .src_dir )
188
+ run (f"git checkout { self ._ref } " , cwd = self .src_dir )
189
+ return True
190
+ except Exception :
191
+ log .error (
192
+ f"Failed to resolve target commit { self ._ref } . Fetching updates."
153
193
)
154
- run ("git reset --hard" , cwd = self .src_dir )
155
- run (f"git checkout { self ._ref } " , cwd = self .src_dir )
194
+ if self ._shallow_clone :
195
+ log .debug (f"Cloning a clean shallow copy." )
196
+ shutil .rmtree (self .src_dir )
197
+ self ._git_clone ()
198
+ return True
199
+ else :
200
+ self ._git_fetch ()
156
201
else :
157
202
log .debug (
158
203
f"Current commit { current_commit } matches target { target_commit } , no update needed."
159
204
)
160
205
return False
161
- elif not self .src_dir .exists ():
162
- run (f"git clone --recursive { self ._url } { self .src_dir } " )
163
- run (f"git checkout { self ._ref } " , cwd = self .src_dir )
164
206
else :
165
207
raise Exception (
166
208
f"The directory { self .src_dir } exists but is not a git repository."
167
209
)
168
- log .debug (f"Cloned { self ._url } into { self .src_dir } at commit { self ._ref } " )
169
- return True
0 commit comments