@@ -61,8 +61,9 @@ class InstallerImpl:
6161 _sources_list_dir = os .path .join (os .sep , "etc" , "apt" , "sources.list.d" )
6262
6363 def __init__ (
64- self , ros_test_deps : bool = False , ros_doc_deps : bool = False , skip_ros_deps : bool = False , debug : bool = False
64+ self , branch : Optional [ str ] = None , ros_test_deps : bool = False , ros_doc_deps : bool = False , skip_ros_deps : bool = False , debug : bool = False
6565 ):
66+ self ._branch = branch
6667 self ._ros_test_deps = ros_test_deps
6768 self ._ros_doc_deps = ros_doc_deps
6869 self ._skip_ros_deps = skip_ros_deps
@@ -82,6 +83,7 @@ def __init__(
8283 self ._dependencies_dir = os .path .join (self ._tue_env_dir , ".env" , "dependencies" )
8384 self ._dependencies_on_dir = os .path .join (self ._tue_env_dir , ".env" , "dependencies-on" )
8485 self ._installed_dir = os .path .join (self ._tue_env_dir , ".env" , "installed" )
86+ self ._version_cache_dir = os .path .join (self ._tue_env_dir , ".env" , "version_cache" )
8587
8688 os .makedirs (self ._dependencies_dir , exist_ok = True )
8789 os .makedirs (self ._dependencies_on_dir , exist_ok = True )
@@ -117,6 +119,8 @@ def __init__(
117119 self ._snaps = []
118120 self ._gems = []
119121
122+ self ._git_pull_queue = set ()
123+
120124 self ._sudo_password = None
121125
122126 def __del__ (self ):
@@ -469,8 +473,165 @@ def tue_install_target(self, target: str, now: bool = False) -> bool:
469473 self .tue_install_debug (f"Finished installing { target } " )
470474 return True
471475
476+ def _show_update_msg (self , repo , msg : str = None ):
477+ # shellcheck disable=SC2086,SC2116
478+ if msg :
479+ print_msg = "\n "
480+ print_msg += f" { colored (repo , attrs = ['bold' ])} "
481+ print_msg += f"\n --------------------------------------------------"
482+ print_msg += f"\n { msg } "
483+ print_msg += f"\n --------------------------------------------------"
484+ print_msg += f"\n "
485+ self .tue_install_tee (print_msg )
486+ else :
487+ self .tue_install_tee (f"{ colored (repo , attrs = ['bold' ])} : up-tp-date" )
488+
489+ def _try_branch_git (self , target_dir , version ):
490+ self .tue_install_debug (f"_try_branch_git { target_dir = } { version = } " )
491+
492+ cmd = f"git -C { target_dir } checkout { version } --"
493+ self .tue_install_debug (f"{ cmd } " )
494+ cmd , cmds = _which_split_cmd (cmd )
495+ try_branch_res = sp .check_output (cmds , stderr = sp .STDOUT , text = True ).strip ()
496+ self .tue_install_debug (f"{ try_branch_res = } " )
497+
498+ cmd = f"git -C { target_dir } submodule sync --recursive"
499+ self .tue_install_debug (f"{ cmd } " )
500+ cmd , cmds = _which_split_cmd (cmd )
501+ submodule_sync_results = sp .run (cmds , stdout = sp .PIPE , stderr = sp .STDOUT , text = True )
502+ submodule_sync_res = submodule_sync_results .stdout .strip ()
503+ self .tue_install_debug (f"{ submodule_sync_res = } " )
504+
505+ cmd = f"git -C { target_dir } submodule update --init --recursive"
506+ self .tue_install_debug (f"{ cmd } " )
507+ cmd , cmds = _which_split_cmd (cmd )
508+ submodule_res = sp .check_output (cmds , stderr = sp .STDOUT , text = True ).strip ()
509+ self .tue_install_debug (f"{ submodule_res = } " )
510+
511+ if "Already on " in try_branch_res or "fatal: invalid reference:" in try_branch_res :
512+ try_branch_res = ""
513+
514+ if submodule_sync_results .returncode != 0 and submodule_sync_res :
515+ try_branch_res += f"\n { submodule_sync_res } "
516+ if submodule_res :
517+ try_branch_res += f"\n { submodule_res } "
518+
519+ return try_branch_res
520+
472521 def tue_install_git (self , url : str , target_dir : Optional [str ] = None , version : Optional [str ] = None ) -> bool :
473522 self .tue_install_debug (f"tue-install-git { url = } { target_dir = } { version = } " )
523+
524+ # ToDo: convert _git_https_or_ssh to python
525+ cmd = f"bash -c '_git_https_or_ssh { url } '"
526+ cmd , cmds = _which_split_cmd (cmd )
527+ url_old = url
528+ url = sp .check_output (cmds , text = True ).strip ()
529+ if not url :
530+ self .tue_install_error (f"repo: '{ url } ' is invalid. It is generated from: '{ url_old } '\n "
531+ f"The problem will probably be solved by resourcing the setup" )
532+ # ToDo: This depends on behaviour of tue-install-error
533+ return False
534+
535+ if target_dir is None :
536+ # ToDo: convert _git_url_to_repos_dir to python
537+ cmd = f"bash -c '_git_url_to_repos_dir { url } '"
538+ cmd , cmds = _which_split_cmd (cmd )
539+ target_dir = sp .check_output (cmds , text = True ).strip ()
540+ if not target_dir :
541+ self .tue_install_error (f"Could not create target_dir path from the git url: '{ url } '" )
542+ # ToDo: This depends on behaviour of tue-install-error
543+ return False
544+
545+ if not target_dir :
546+ self .tue_install_error (f"target_dir is specified, but empty" )
547+ # ToDo: This depends on behaviour of tue-install-error
548+ return False
549+
550+ if not os .path .isdir (target_dir ):
551+ cmd = f"git clone --recursive { url } { target_dir } "
552+ self .tue_install_debug (f"{ cmd } " )
553+ cmd , cmds = _which_split_cmd (cmd )
554+ clone_results = sp .run (cmds , stdout = sp .PIPE , stderr = sp .STDOUT , text = True )
555+ res = clone_results .stdout .strip ()
556+ if clone_results .returncode != 0 :
557+ self .tue_install_error (f"Failed to clone { url } to { target_dir } \n { res } " )
558+ # ToDo: This depends on behaviour of tue-install-error
559+ return False
560+
561+ self ._git_pull_queue .add (target_dir )
562+ else :
563+ if target_dir in self ._git_pull_queue :
564+ self .tue_install_debug ("Repo previously pulled, skipping" )
565+ res = ""
566+ else :
567+ cmd = f"git -C { target_dir } config --get remote.origin.url"
568+ cmd , cmds = _which_split_cmd (cmd )
569+ self .tue_install_debug (f"{ cmd } " )
570+ cmd , cmds = _which_split_cmd (cmd )
571+ current_url = sp .check_output (cmds , text = True ).strip ()
572+ # If different, switch url
573+ if current_url != url :
574+ cmd = f"git -C { target_dir } remote set-url origin { url } "
575+ sub = self ._default_background_popen (cmd )
576+ if sub .returncode != 0 :
577+ self .tue_install_error (f"Could not change git url of '{ target_dir } ' to '{ url } '"
578+ f"({ sub .returncode } ):\n { repr (cmd )} " )
579+ # ToDo: This depends on behaviour of tue-install-error
580+ return False
581+
582+ self .tue_install_info (f"url has switched to '{ url } '" )
583+
584+ cmd = f"git -C { target_dir } pull --ff-only --prune"
585+ self .tue_install_debug (f"{ cmd } " )
586+ cmd , cmds = _which_split_cmd (cmd )
587+ res = sp .check_output (cmds , stderr = sp .STDOUT , text = True ).strip ()
588+ self .tue_install_debug (f"{ res = } " )
589+
590+ self ._git_pull_queue .add (target_dir )
591+
592+ cmd = f"git -C { target_dir } submodule sync --recursive"
593+ self .tue_install_debug (f"{ cmd } " )
594+ cmd , cmds = _which_split_cmd (cmd )
595+ sp_results = sp .run (cmds , text = True , stdout = sp .PIPE )
596+ submodule_sync_res = sp_results .stdout .strip ()
597+ self .tue_install_debug (f"{ submodule_sync_res = } " )
598+ if sp_results .returncode != 0 and submodule_sync_res :
599+ res += f"\n { submodule_sync_res } "
600+
601+
602+ cmd = f"git -C { target_dir } submodule update --init --recursive"
603+ self .tue_install_debug (f"{ cmd } " )
604+ cmd , cmds = _which_split_cmd (cmd )
605+ submodule_res = sp .check_output (cmds , stderr = sp .STDOUT , text = True ).strip ()
606+ self .tue_install_debug (f"{ submodule_res = } " )
607+ if submodule_res :
608+ res += f"\n { submodule_res } "
609+
610+ if "Already up to date." in res :
611+ res = ""
612+
613+ self .tue_install_debug (f"Desired version: { version } " )
614+ version_cache_file = os .path .join (self ._version_cache_dir , target_dir .lstrip (os .sep ))
615+ if version :
616+ os .makedirs (os .path .dirname (version_cache_file ), exist_ok = True )
617+ with open (version_cache_file , "w" ) as f :
618+ f .write (version )
619+
620+ try_branch_res = self ._try_branch_git (target_dir , version )
621+ if try_branch_res :
622+ res += f"\n { try_branch_res } "
623+ else :
624+ if os .path .isfile (version_cache_file ):
625+ os .remove (version_cache_file )
626+
627+ if self ._branch :
628+ self .tue_install_debug (f"Desired branch: { self ._branch } " )
629+ try_branch_res = self ._try_branch_git (target_dir , self ._branch )
630+ if try_branch_res :
631+ res += f"\n { try_branch_res } "
632+
633+
634+ self ._show_update_msg (self ._current_target , res )
474635 return True
475636
476637 def tue_install_apply_patch (self , patch_file : str , target_dir : str ) -> bool :
0 commit comments