1010import logging
1111import argparse
1212import shutil
13- from git import Repo , GitCommandError
13+ from git import Repo , GitCommandError , Git
1414import bz2
1515import contextlib
1616from datetime import datetime
@@ -92,39 +92,8 @@ def parse_src_link(src_link):
9292 return src_info
9393
9494
95- def main ():
96- parser = argparse .ArgumentParser (description = 'FOSSLight Downloader' , prog = 'fosslight_download' , add_help = False )
97- parser .add_argument ('-h' , '--help' , help = 'Print help message' , action = 'store_true' , dest = 'help' )
98- parser .add_argument ('-s' , '--source' , help = 'Source link to download' , type = str , dest = 'source' )
99- parser .add_argument ('-t' , '--target_dir' , help = 'Target directory' , type = str , dest = 'target_dir' , default = "" )
100- parser .add_argument ('-d' , '--log_dir' , help = 'Directory to save log file' , type = str , dest = 'log_dir' , default = "" )
101-
102- src_link = ""
103- target_dir = os .getcwd ()
104- log_dir = os .getcwd ()
105-
106- try :
107- args = parser .parse_args ()
108- except SystemExit :
109- sys .exit (0 )
110-
111- if args .help :
112- print_help_msg_download ()
113- if args .source :
114- src_link = args .source
115- if args .target_dir :
116- target_dir = args .target_dir
117- if args .log_dir :
118- log_dir = args .log_dir
119-
120- if not src_link :
121- print_help_msg_download ()
122- else :
123- cli_download_and_extract (src_link , target_dir , log_dir )
124-
125-
12695def cli_download_and_extract (link : str , target_dir : str , log_dir : str , checkout_to : str = "" ,
127- compressed_only : bool = False ) -> Tuple [bool , str , str , str ]:
96+ compressed_only : bool = False , ssh_key : str = "" ) -> Tuple [bool , str , str , str ]:
12897 global logger
12998
13099 success = True
@@ -152,7 +121,7 @@ def cli_download_and_extract(link: str, target_dir: str, log_dir: str, checkout_
152121 is_rubygems = src_info .get ("rubygems" , False )
153122
154123 # General download (git clone, wget)
155- success_git , msg , oss_name , oss_version = download_git_clone (link , target_dir , checkout_to , tag , branch )
124+ success_git , msg , oss_name , oss_version = download_git_clone (link , target_dir , checkout_to , tag , branch , ssh_key )
156125 if (not is_rubygems ) and (not success_git ):
157126 if os .path .isfile (target_dir ):
158127 shutil .rmtree (target_dir )
@@ -229,11 +198,36 @@ def get_github_token(git_url):
229198 return github_token
230199
231200
232- def download_git_clone (git_url , target_dir , checkout_to = "" , tag = "" , branch = "" ):
201+ def download_git_repository (refs_to_checkout , git_url , target_dir , tag ):
202+ success = False
203+ oss_version = ""
204+ clone_default_branch_flag = False
205+ if refs_to_checkout :
206+ try :
207+ # gitPython uses the branch argument the same whether you check out to a branch or a tag.
208+ repo = Repo .clone_from (git_url , target_dir , branch = refs_to_checkout )
209+ success = True
210+ except GitCommandError as error :
211+ logger .debug (f"Git checkout error:{ error } " )
212+ success = False
213+
214+ if not success :
215+ repo = Repo .clone_from (git_url , target_dir )
216+ clone_default_branch_flag = True
217+ success = True
218+
219+ if refs_to_checkout != tag or clone_default_branch_flag :
220+ oss_version = repo .active_branch .name
221+ else :
222+ oss_version = repo .git .describe ('--tags' )
223+ return success , oss_version
224+
225+
226+ def download_git_clone (git_url , target_dir , checkout_to = "" , tag = "" , branch = "" , ssh_key = "" ):
233227 oss_name = get_github_ossname (git_url )
234228 refs_to_checkout = decide_checkout (checkout_to , tag , branch )
235- clone_default_branch_flag = False
236229 msg = ""
230+ success = True
237231
238232 try :
239233 if platform .system () != "Windows" :
@@ -244,36 +238,32 @@ def download_git_clone(git_url, target_dir, checkout_to="", tag="", branch=""):
244238 alarm .start ()
245239
246240 Path (target_dir ).mkdir (parents = True , exist_ok = True )
247- if refs_to_checkout != "" :
248- try :
249- # gitPython uses the branch argument the same whether you check out to a branch or a tag.
250- repo = Repo .clone_from (git_url , target_dir , branch = refs_to_checkout )
251- except GitCommandError as error :
252- error_msg = error .args [2 ].decode ("utf-8" )
253- if "Remote branch " + refs_to_checkout + " not found in upstream origin" in error_msg :
254- # clone default branch, when non-existent branch or tag entered
255- repo = Repo .clone_from (git_url , target_dir )
256- clone_default_branch_flag = True
257- else :
258- repo = Repo .clone_from (git_url , target_dir )
259- clone_default_branch_flag = True
260241
261- if refs_to_checkout != tag or clone_default_branch_flag :
262- oss_version = repo .active_branch .name
242+ if git_url .startswith ("ssh:" ) and not ssh_key :
243+ msg = "Private git needs ssh_key"
244+ success = False
263245 else :
264- oss_version = repo .git .describe ('--tags' )
265- logger .info (f"git checkout: { oss_version } " )
246+ if ssh_key :
247+ logger .info (f"Download git with ssh_key" )
248+ git_ssh_cmd = f'ssh -i { ssh_key } '
249+ with Git ().custom_environment (GIT_SSH_COMMAND = git_ssh_cmd ):
250+ success , oss_version = download_git_repository (refs_to_checkout , git_url , target_dir , tag )
251+ else :
252+ success , oss_version = download_git_repository (refs_to_checkout , git_url , target_dir , tag )
266253
267- if platform .system () != "Windows" :
268- signal .alarm (0 )
269- else :
270- del alarm
254+ logger .info (f"git checkout: { oss_version } " )
255+ refs_to_checkout = oss_version
256+
257+ if platform .system () != "Windows" :
258+ signal .alarm (0 )
259+ else :
260+ del alarm
271261 except Exception as error :
262+ success = False
272263 logger .warning (f"git clone - failed: { error } " )
273264 msg = str (error )
274- return False , msg , oss_name , refs_to_checkout
275265
276- return True , msg , oss_name , oss_version
266+ return success , msg , oss_name , refs_to_checkout
277267
278268
279269def download_wget (link , target_dir , compressed_only ):
@@ -444,5 +434,36 @@ def gem_download(link, target_dir, checkout_to):
444434 return success
445435
446436
437+ def main ():
438+ parser = argparse .ArgumentParser (description = 'FOSSLight Downloader' , prog = 'fosslight_download' , add_help = False )
439+ parser .add_argument ('-h' , '--help' , help = 'Print help message' , action = 'store_true' , dest = 'help' )
440+ parser .add_argument ('-s' , '--source' , help = 'Source link to download' , type = str , dest = 'source' )
441+ parser .add_argument ('-t' , '--target_dir' , help = 'Target directory' , type = str , dest = 'target_dir' , default = "" )
442+ parser .add_argument ('-d' , '--log_dir' , help = 'Directory to save log file' , type = str , dest = 'log_dir' , default = "" )
443+
444+ src_link = ""
445+ target_dir = os .getcwd ()
446+ log_dir = os .getcwd ()
447+
448+ try :
449+ args = parser .parse_args ()
450+ except SystemExit :
451+ sys .exit (0 )
452+
453+ if args .help :
454+ print_help_msg_download ()
455+ if args .source :
456+ src_link = args .source
457+ if args .target_dir :
458+ target_dir = args .target_dir
459+ if args .log_dir :
460+ log_dir = args .log_dir
461+
462+ if not src_link :
463+ print_help_msg_download ()
464+ else :
465+ cli_download_and_extract (src_link , target_dir , log_dir )
466+
467+
447468if __name__ == '__main__' :
448469 main ()
0 commit comments