summaryrefslogtreecommitdiffstats
path: root/subcmds
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds')
-rw-r--r--subcmds/sync.py86
1 files changed, 57 insertions, 29 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index ca4b97b3..808df208 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -368,7 +368,7 @@ later is required to fix a server side protocol bug.
368 368
369 return success 369 return success
370 370
371 def _Fetch(self, projects, opt): 371 def _Fetch(self, projects, opt, err_event):
372 fetched = set() 372 fetched = set()
373 lock = _threading.Lock() 373 lock = _threading.Lock()
374 pm = Progress('Fetching projects', len(projects), 374 pm = Progress('Fetching projects', len(projects),
@@ -380,7 +380,6 @@ later is required to fix a server side protocol bug.
380 380
381 threads = set() 381 threads = set()
382 sem = _threading.Semaphore(self.jobs) 382 sem = _threading.Semaphore(self.jobs)
383 err_event = _threading.Event()
384 for project_list in objdir_project_map.values(): 383 for project_list in objdir_project_map.values():
385 # Check for any errors before running any more tasks. 384 # Check for any errors before running any more tasks.
386 # ...we'll let existing threads finish, though. 385 # ...we'll let existing threads finish, though.
@@ -409,16 +408,11 @@ later is required to fix a server side protocol bug.
409 for t in threads: 408 for t in threads:
410 t.join() 409 t.join()
411 410
412 # If we saw an error, exit with code 1 so that other scripts can check.
413 if err_event.isSet() and opt.fail_fast:
414 print('\nerror: Exited sync due to fetch errors', file=sys.stderr)
415 sys.exit(1)
416
417 pm.end() 411 pm.end()
418 self._fetch_times.Save() 412 self._fetch_times.Save()
419 413
420 if not self.manifest.IsArchive: 414 if not self.manifest.IsArchive:
421 self._GCProjects(projects) 415 self._GCProjects(projects, opt, err_event)
422 416
423 return fetched 417 return fetched
424 418
@@ -504,12 +498,16 @@ later is required to fix a server side protocol bug.
504 498
505 return success 499 return success
506 500
507 def _Checkout(self, all_projects, opt): 501 def _Checkout(self, all_projects, opt, err_event, err_results):
508 """Checkout projects listed in all_projects 502 """Checkout projects listed in all_projects
509 503
510 Args: 504 Args:
511 all_projects: List of all projects that should be checked out. 505 all_projects: List of all projects that should be checked out.
512 opt: Program options returned from optparse. See _Options(). 506 opt: Program options returned from optparse. See _Options().
507 err_event: We'll set this event in the case of an error (after printing
508 out info about the error).
509 err_results: A list of strings, paths to git repos where checkout
510 failed.
513 """ 511 """
514 512
515 # Perform checkouts in multiple threads when we are using partial clone. 513 # Perform checkouts in multiple threads when we are using partial clone.
@@ -528,8 +526,6 @@ later is required to fix a server side protocol bug.
528 526
529 threads = set() 527 threads = set()
530 sem = _threading.Semaphore(syncjobs) 528 sem = _threading.Semaphore(syncjobs)
531 err_event = _threading.Event()
532 err_results = []
533 529
534 for project in all_projects: 530 for project in all_projects:
535 # Check for any errors before running any more tasks. 531 # Check for any errors before running any more tasks.
@@ -560,15 +556,8 @@ later is required to fix a server side protocol bug.
560 t.join() 556 t.join()
561 557
562 pm.end() 558 pm.end()
563 # If we saw an error, exit with code 1 so that other scripts can check.
564 if err_event.isSet():
565 print('\nerror: Exited sync due to checkout errors', file=sys.stderr)
566 if err_results:
567 print('Failing repos:\n%s' % '\n'.join(err_results),
568 file=sys.stderr)
569 sys.exit(1)
570 559
571 def _GCProjects(self, projects): 560 def _GCProjects(self, projects, opt, err_event):
572 gc_gitdirs = {} 561 gc_gitdirs = {}
573 for project in projects: 562 for project in projects:
574 if len(project.manifest.GetProjectsWithName(project.name)) > 1: 563 if len(project.manifest.GetProjectsWithName(project.name)) > 1:
@@ -592,7 +581,6 @@ later is required to fix a server side protocol bug.
592 581
593 threads = set() 582 threads = set()
594 sem = _threading.Semaphore(jobs) 583 sem = _threading.Semaphore(jobs)
595 err_event = _threading.Event()
596 584
597 def GC(bare_git): 585 def GC(bare_git):
598 try: 586 try:
@@ -607,7 +595,7 @@ later is required to fix a server side protocol bug.
607 sem.release() 595 sem.release()
608 596
609 for bare_git in gc_gitdirs.values(): 597 for bare_git in gc_gitdirs.values():
610 if err_event.isSet(): 598 if err_event.isSet() and opt.fail_fast:
611 break 599 break
612 sem.acquire() 600 sem.acquire()
613 t = _threading.Thread(target=GC, args=(bare_git,)) 601 t = _threading.Thread(target=GC, args=(bare_git,))
@@ -618,10 +606,6 @@ later is required to fix a server side protocol bug.
618 for t in threads: 606 for t in threads:
619 t.join() 607 t.join()
620 608
621 if err_event.isSet():
622 print('\nerror: Exited sync due to gc errors', file=sys.stderr)
623 sys.exit(1)
624
625 def _ReloadManifest(self, manifest_name=None): 609 def _ReloadManifest(self, manifest_name=None):
626 if manifest_name: 610 if manifest_name:
627 # Override calls _Unload already 611 # Override calls _Unload already
@@ -902,6 +886,8 @@ later is required to fix a server side protocol bug.
902 print('error: failed to remove existing smart sync override manifest: %s' % 886 print('error: failed to remove existing smart sync override manifest: %s' %
903 e, file=sys.stderr) 887 e, file=sys.stderr)
904 888
889 err_event = _threading.Event()
890
905 rp = self.manifest.repoProject 891 rp = self.manifest.repoProject
906 rp.PreSync() 892 rp.PreSync()
907 893
@@ -955,6 +941,10 @@ later is required to fix a server side protocol bug.
955 missing_ok=True, 941 missing_ok=True,
956 submodules_ok=opt.fetch_submodules) 942 submodules_ok=opt.fetch_submodules)
957 943
944 err_network_sync = False
945 err_update_projects = False
946 err_checkout = False
947
958 self._fetch_times = _FetchTimes(self.manifest) 948 self._fetch_times = _FetchTimes(self.manifest)
959 if not opt.local_only: 949 if not opt.local_only:
960 to_fetch = [] 950 to_fetch = []
@@ -964,10 +954,14 @@ later is required to fix a server side protocol bug.
964 to_fetch.extend(all_projects) 954 to_fetch.extend(all_projects)
965 to_fetch.sort(key=self._fetch_times.Get, reverse=True) 955 to_fetch.sort(key=self._fetch_times.Get, reverse=True)
966 956
967 fetched = self._Fetch(to_fetch, opt) 957 fetched = self._Fetch(to_fetch, opt, err_event)
958
968 _PostRepoFetch(rp, opt.no_repo_verify) 959 _PostRepoFetch(rp, opt.no_repo_verify)
969 if opt.network_only: 960 if opt.network_only:
970 # bail out now; the rest touches the working tree 961 # bail out now; the rest touches the working tree
962 if err_event.isSet():
963 print('\nerror: Exited sync due to fetch errors.\n', file=sys.stderr)
964 sys.exit(1)
971 return 965 return
972 966
973 # Iteratively fetch missing and/or nested unregistered submodules 967 # Iteratively fetch missing and/or nested unregistered submodules
@@ -989,22 +983,56 @@ later is required to fix a server side protocol bug.
989 if previously_missing_set == missing_set: 983 if previously_missing_set == missing_set:
990 break 984 break
991 previously_missing_set = missing_set 985 previously_missing_set = missing_set
992 fetched.update(self._Fetch(missing, opt)) 986 fetched.update(self._Fetch(missing, opt, err_event))
987
988 # If we saw an error, exit with code 1 so that other scripts can check.
989 if err_event.isSet():
990 err_network_sync = True
991 if opt.fail_fast:
992 print('\nerror: Exited sync due to fetch errors.\n'
993 'Local checkouts *not* updated. Resolve network issues & '
994 'retry.\n'
995 '`repo sync -l` will update some local checkouts.',
996 file=sys.stderr)
997 sys.exit(1)
993 998
994 if self.manifest.IsMirror or self.manifest.IsArchive: 999 if self.manifest.IsMirror or self.manifest.IsArchive:
995 # bail out now, we have no working tree 1000 # bail out now, we have no working tree
996 return 1001 return
997 1002
998 if self.UpdateProjectList(opt): 1003 if self.UpdateProjectList(opt):
999 sys.exit(1) 1004 err_event.set()
1005 err_update_projects = True
1006 if opt.fail_fast:
1007 print('\nerror: Local checkouts *not* updated.', file=sys.stderr)
1008 sys.exit(1)
1000 1009
1001 self._Checkout(all_projects, opt) 1010 err_results = []
1011 self._Checkout(all_projects, opt, err_event, err_results)
1012 if err_event.isSet():
1013 err_checkout = True
1014 # NB: We don't exit here because this is the last step.
1002 1015
1003 # If there's a notice that's supposed to print at the end of the sync, print 1016 # If there's a notice that's supposed to print at the end of the sync, print
1004 # it now... 1017 # it now...
1005 if self.manifest.notice: 1018 if self.manifest.notice:
1006 print(self.manifest.notice) 1019 print(self.manifest.notice)
1007 1020
1021 # If we saw an error, exit with code 1 so that other scripts can check.
1022 if err_event.isSet():
1023 print('\nerror: Unable to fully sync the tree.', file=sys.stderr)
1024 if err_network_sync:
1025 print('error: Downloading network changes failed.', file=sys.stderr)
1026 if err_update_projects:
1027 print('error: Updating local project lists failed.', file=sys.stderr)
1028 if err_checkout:
1029 print('error: Checking out local projects failed.', file=sys.stderr)
1030 if err_results:
1031 print('Failing repos:\n%s' % '\n'.join(err_results), file=sys.stderr)
1032 print('Try re-running with "-j1 --fail-fast" to exit at the first error.',
1033 file=sys.stderr)
1034 sys.exit(1)
1035
1008def _PostRepoUpgrade(manifest, quiet=False): 1036def _PostRepoUpgrade(manifest, quiet=False):
1009 wrapper = Wrapper() 1037 wrapper = Wrapper()
1010 if wrapper.NeedSetupGnuPG(): 1038 if wrapper.NeedSetupGnuPG():