diff options
Diffstat (limited to 'subcmds')
| -rw-r--r-- | subcmds/download.py | 2 | ||||
| -rw-r--r-- | subcmds/sync.py | 159 |
2 files changed, 115 insertions, 46 deletions
diff --git a/subcmds/download.py b/subcmds/download.py index d81d1f8c..475c0bc2 100644 --- a/subcmds/download.py +++ b/subcmds/download.py | |||
| @@ -118,7 +118,7 @@ If no project is specified try to use current directory as a project. | |||
| 118 | ), | 118 | ), |
| 119 | file=sys.stderr, | 119 | file=sys.stderr, |
| 120 | ) | 120 | ) |
| 121 | sys.exit(1) | 121 | raise NoSuchProjectError() |
| 122 | else: | 122 | else: |
| 123 | project = projects[0] | 123 | project = projects[0] |
| 124 | print("Defaulting to cwd project", project.name) | 124 | print("Defaulting to cwd project", project.name) |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 5f8bc2f0..eaca50c9 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -63,9 +63,16 @@ from command import ( | |||
| 63 | MirrorSafeCommand, | 63 | MirrorSafeCommand, |
| 64 | WORKER_BATCH_SIZE, | 64 | WORKER_BATCH_SIZE, |
| 65 | ) | 65 | ) |
| 66 | from error import RepoChangedException, GitError | 66 | from error import ( |
| 67 | RepoChangedException, | ||
| 68 | GitError, | ||
| 69 | RepoExitError, | ||
| 70 | SyncError, | ||
| 71 | UpdateManifestError, | ||
| 72 | RepoUnhandledExceptionError, | ||
| 73 | ) | ||
| 67 | import platform_utils | 74 | import platform_utils |
| 68 | from project import SyncBuffer | 75 | from project import SyncBuffer, DeleteWorktreeError |
| 69 | from progress import Progress, elapsed_str, jobs_str | 76 | from progress import Progress, elapsed_str, jobs_str |
| 70 | from repo_trace import Trace | 77 | from repo_trace import Trace |
| 71 | import ssh | 78 | import ssh |
| @@ -94,6 +101,7 @@ class _FetchOneResult(NamedTuple): | |||
| 94 | """ | 101 | """ |
| 95 | 102 | ||
| 96 | success: bool | 103 | success: bool |
| 104 | errors: List[Exception] | ||
| 97 | project: Project | 105 | project: Project |
| 98 | start: float | 106 | start: float |
| 99 | finish: float | 107 | finish: float |
| @@ -110,6 +118,7 @@ class _FetchResult(NamedTuple): | |||
| 110 | 118 | ||
| 111 | success: bool | 119 | success: bool |
| 112 | projects: Set[str] | 120 | projects: Set[str] |
| 121 | errors: List[Exception] | ||
| 113 | 122 | ||
| 114 | 123 | ||
| 115 | class _FetchMainResult(NamedTuple): | 124 | class _FetchMainResult(NamedTuple): |
| @@ -120,6 +129,7 @@ class _FetchMainResult(NamedTuple): | |||
| 120 | """ | 129 | """ |
| 121 | 130 | ||
| 122 | all_projects: List[Project] | 131 | all_projects: List[Project] |
| 132 | errors: List[Exception] | ||
| 123 | 133 | ||
| 124 | 134 | ||
| 125 | class _CheckoutOneResult(NamedTuple): | 135 | class _CheckoutOneResult(NamedTuple): |
| @@ -133,11 +143,24 @@ class _CheckoutOneResult(NamedTuple): | |||
| 133 | """ | 143 | """ |
| 134 | 144 | ||
| 135 | success: bool | 145 | success: bool |
| 146 | errors: List[Exception] | ||
| 136 | project: Project | 147 | project: Project |
| 137 | start: float | 148 | start: float |
| 138 | finish: float | 149 | finish: float |
| 139 | 150 | ||
| 140 | 151 | ||
| 152 | class SuperprojectError(SyncError): | ||
| 153 | """Superproject sync repo.""" | ||
| 154 | |||
| 155 | |||
| 156 | class SyncFailFastError(SyncError): | ||
| 157 | """Sync exit error when --fail-fast set.""" | ||
| 158 | |||
| 159 | |||
| 160 | class SmartSyncError(SyncError): | ||
| 161 | """Smart sync exit error.""" | ||
| 162 | |||
| 163 | |||
| 141 | class Sync(Command, MirrorSafeCommand): | 164 | class Sync(Command, MirrorSafeCommand): |
| 142 | COMMON = True | 165 | COMMON = True |
| 143 | MULTI_MANIFEST_SUPPORT = True | 166 | MULTI_MANIFEST_SUPPORT = True |
| @@ -588,7 +611,7 @@ later is required to fix a server side protocol bug. | |||
| 588 | file=sys.stderr, | 611 | file=sys.stderr, |
| 589 | ) | 612 | ) |
| 590 | if update_result.fatal and opt.use_superproject is not None: | 613 | if update_result.fatal and opt.use_superproject is not None: |
| 591 | sys.exit(1) | 614 | raise SuperprojectError() |
| 592 | if need_unload: | 615 | if need_unload: |
| 593 | m.outer_client.manifest.Unload() | 616 | m.outer_client.manifest.Unload() |
| 594 | 617 | ||
| @@ -621,6 +644,7 @@ later is required to fix a server side protocol bug. | |||
| 621 | self._sync_dict[k] = start | 644 | self._sync_dict[k] = start |
| 622 | success = False | 645 | success = False |
| 623 | remote_fetched = False | 646 | remote_fetched = False |
| 647 | errors = [] | ||
| 624 | buf = io.StringIO() | 648 | buf = io.StringIO() |
| 625 | try: | 649 | try: |
| 626 | sync_result = project.Sync_NetworkHalf( | 650 | sync_result = project.Sync_NetworkHalf( |
| @@ -644,6 +668,8 @@ later is required to fix a server side protocol bug. | |||
| 644 | ) | 668 | ) |
| 645 | success = sync_result.success | 669 | success = sync_result.success |
| 646 | remote_fetched = sync_result.remote_fetched | 670 | remote_fetched = sync_result.remote_fetched |
| 671 | if sync_result.error: | ||
| 672 | errors.append(sync_result.error) | ||
| 647 | 673 | ||
| 648 | output = buf.getvalue() | 674 | output = buf.getvalue() |
| 649 | if (opt.verbose or not success) and output: | 675 | if (opt.verbose or not success) and output: |
| @@ -659,6 +685,7 @@ later is required to fix a server side protocol bug. | |||
| 659 | print(f"Keyboard interrupt while processing {project.name}") | 685 | print(f"Keyboard interrupt while processing {project.name}") |
| 660 | except GitError as e: | 686 | except GitError as e: |
| 661 | print("error.GitError: Cannot fetch %s" % str(e), file=sys.stderr) | 687 | print("error.GitError: Cannot fetch %s" % str(e), file=sys.stderr) |
| 688 | errors.append(e) | ||
| 662 | except Exception as e: | 689 | except Exception as e: |
| 663 | print( | 690 | print( |
| 664 | "error: Cannot fetch %s (%s: %s)" | 691 | "error: Cannot fetch %s (%s: %s)" |
| @@ -666,11 +693,14 @@ later is required to fix a server side protocol bug. | |||
| 666 | file=sys.stderr, | 693 | file=sys.stderr, |
| 667 | ) | 694 | ) |
| 668 | del self._sync_dict[k] | 695 | del self._sync_dict[k] |
| 696 | errors.append(e) | ||
| 669 | raise | 697 | raise |
| 670 | 698 | ||
| 671 | finish = time.time() | 699 | finish = time.time() |
| 672 | del self._sync_dict[k] | 700 | del self._sync_dict[k] |
| 673 | return _FetchOneResult(success, project, start, finish, remote_fetched) | 701 | return _FetchOneResult( |
| 702 | success, errors, project, start, finish, remote_fetched | ||
| 703 | ) | ||
| 674 | 704 | ||
| 675 | @classmethod | 705 | @classmethod |
| 676 | def _FetchInitChild(cls, ssh_proxy): | 706 | def _FetchInitChild(cls, ssh_proxy): |
| @@ -701,6 +731,7 @@ later is required to fix a server side protocol bug. | |||
| 701 | jobs = opt.jobs_network | 731 | jobs = opt.jobs_network |
| 702 | fetched = set() | 732 | fetched = set() |
| 703 | remote_fetched = set() | 733 | remote_fetched = set() |
| 734 | errors = [] | ||
| 704 | pm = Progress( | 735 | pm = Progress( |
| 705 | "Fetching", | 736 | "Fetching", |
| 706 | len(projects), | 737 | len(projects), |
| @@ -745,6 +776,8 @@ later is required to fix a server side protocol bug. | |||
| 745 | finish, | 776 | finish, |
| 746 | success, | 777 | success, |
| 747 | ) | 778 | ) |
| 779 | if result.errors: | ||
| 780 | errors.extend(result.errors) | ||
| 748 | if result.remote_fetched: | 781 | if result.remote_fetched: |
| 749 | remote_fetched.add(project) | 782 | remote_fetched.add(project) |
| 750 | # Check for any errors before running any more tasks. | 783 | # Check for any errors before running any more tasks. |
| @@ -813,7 +846,7 @@ later is required to fix a server side protocol bug. | |||
| 813 | if not self.outer_client.manifest.IsArchive: | 846 | if not self.outer_client.manifest.IsArchive: |
| 814 | self._GCProjects(projects, opt, err_event) | 847 | self._GCProjects(projects, opt, err_event) |
| 815 | 848 | ||
| 816 | return _FetchResult(ret, fetched) | 849 | return _FetchResult(ret, fetched, errors) |
| 817 | 850 | ||
| 818 | def _FetchMain( | 851 | def _FetchMain( |
| 819 | self, opt, args, all_projects, err_event, ssh_proxy, manifest | 852 | self, opt, args, all_projects, err_event, ssh_proxy, manifest |
| @@ -832,6 +865,7 @@ later is required to fix a server side protocol bug. | |||
| 832 | List of all projects that should be checked out. | 865 | List of all projects that should be checked out. |
| 833 | """ | 866 | """ |
| 834 | rp = manifest.repoProject | 867 | rp = manifest.repoProject |
| 868 | errors = [] | ||
| 835 | 869 | ||
| 836 | to_fetch = [] | 870 | to_fetch = [] |
| 837 | now = time.time() | 871 | now = time.time() |
| @@ -843,6 +877,9 @@ later is required to fix a server side protocol bug. | |||
| 843 | result = self._Fetch(to_fetch, opt, err_event, ssh_proxy) | 877 | result = self._Fetch(to_fetch, opt, err_event, ssh_proxy) |
| 844 | success = result.success | 878 | success = result.success |
| 845 | fetched = result.projects | 879 | fetched = result.projects |
| 880 | if result.errors: | ||
| 881 | errors.extend(result.errors) | ||
| 882 | |||
| 846 | if not success: | 883 | if not success: |
| 847 | err_event.set() | 884 | err_event.set() |
| 848 | 885 | ||
| @@ -854,8 +891,11 @@ later is required to fix a server side protocol bug. | |||
| 854 | "\nerror: Exited sync due to fetch errors.\n", | 891 | "\nerror: Exited sync due to fetch errors.\n", |
| 855 | file=sys.stderr, | 892 | file=sys.stderr, |
| 856 | ) | 893 | ) |
| 857 | sys.exit(1) | 894 | raise SyncError( |
| 858 | return _FetchMainResult([]) | 895 | "error: Exited sync due to fetch errors.", |
| 896 | aggregate_errors=errors, | ||
| 897 | ) | ||
| 898 | return _FetchMainResult([], errors) | ||
| 859 | 899 | ||
| 860 | # Iteratively fetch missing and/or nested unregistered submodules. | 900 | # Iteratively fetch missing and/or nested unregistered submodules. |
| 861 | previously_missing_set = set() | 901 | previously_missing_set = set() |
| @@ -883,11 +923,13 @@ later is required to fix a server side protocol bug. | |||
| 883 | result = self._Fetch(missing, opt, err_event, ssh_proxy) | 923 | result = self._Fetch(missing, opt, err_event, ssh_proxy) |
| 884 | success = result.success | 924 | success = result.success |
| 885 | new_fetched = result.projects | 925 | new_fetched = result.projects |
| 926 | if result.errors: | ||
| 927 | errors.extend(result.errors) | ||
| 886 | if not success: | 928 | if not success: |
| 887 | err_event.set() | 929 | err_event.set() |
| 888 | fetched.update(new_fetched) | 930 | fetched.update(new_fetched) |
| 889 | 931 | ||
| 890 | return _FetchMainResult(all_projects) | 932 | return _FetchMainResult(all_projects, errors) |
| 891 | 933 | ||
| 892 | def _CheckoutOne(self, detach_head, force_sync, project): | 934 | def _CheckoutOne(self, detach_head, force_sync, project): |
| 893 | """Checkout work tree for one project | 935 | """Checkout work tree for one project |
| @@ -905,8 +947,11 @@ later is required to fix a server side protocol bug. | |||
| 905 | project.manifest.manifestProject.config, detach_head=detach_head | 947 | project.manifest.manifestProject.config, detach_head=detach_head |
| 906 | ) | 948 | ) |
| 907 | success = False | 949 | success = False |
| 950 | errors = [] | ||
| 908 | try: | 951 | try: |
| 909 | project.Sync_LocalHalf(syncbuf, force_sync=force_sync) | 952 | project.Sync_LocalHalf( |
| 953 | syncbuf, force_sync=force_sync, errors=errors | ||
| 954 | ) | ||
| 910 | success = syncbuf.Finish() | 955 | success = syncbuf.Finish() |
| 911 | except GitError as e: | 956 | except GitError as e: |
| 912 | print( | 957 | print( |
| @@ -914,6 +959,7 @@ later is required to fix a server side protocol bug. | |||
| 914 | % (project.name, str(e)), | 959 | % (project.name, str(e)), |
| 915 | file=sys.stderr, | 960 | file=sys.stderr, |
| 916 | ) | 961 | ) |
| 962 | errors.append(e) | ||
| 917 | except Exception as e: | 963 | except Exception as e: |
| 918 | print( | 964 | print( |
| 919 | "error: Cannot checkout %s: %s: %s" | 965 | "error: Cannot checkout %s: %s: %s" |
| @@ -925,9 +971,9 @@ later is required to fix a server side protocol bug. | |||
| 925 | if not success: | 971 | if not success: |
| 926 | print("error: Cannot checkout %s" % (project.name), file=sys.stderr) | 972 | print("error: Cannot checkout %s" % (project.name), file=sys.stderr) |
| 927 | finish = time.time() | 973 | finish = time.time() |
| 928 | return _CheckoutOneResult(success, project, start, finish) | 974 | return _CheckoutOneResult(success, errors, project, start, finish) |
| 929 | 975 | ||
| 930 | def _Checkout(self, all_projects, opt, err_results): | 976 | def _Checkout(self, all_projects, opt, err_results, checkout_errors): |
| 931 | """Checkout projects listed in all_projects | 977 | """Checkout projects listed in all_projects |
| 932 | 978 | ||
| 933 | Args: | 979 | Args: |
| @@ -949,6 +995,10 @@ later is required to fix a server side protocol bug. | |||
| 949 | self.event_log.AddSync( | 995 | self.event_log.AddSync( |
| 950 | project, event_log.TASK_SYNC_LOCAL, start, finish, success | 996 | project, event_log.TASK_SYNC_LOCAL, start, finish, success |
| 951 | ) | 997 | ) |
| 998 | |||
| 999 | if result.errors: | ||
| 1000 | checkout_errors.extend(result.errors) | ||
| 1001 | |||
| 952 | # Check for any errors before running any more tasks. | 1002 | # Check for any errors before running any more tasks. |
| 953 | # ...we'll let existing jobs finish, though. | 1003 | # ...we'll let existing jobs finish, though. |
| 954 | if success: | 1004 | if success: |
| @@ -1214,10 +1264,9 @@ later is required to fix a server side protocol bug. | |||
| 1214 | revisionId=None, | 1264 | revisionId=None, |
| 1215 | groups=None, | 1265 | groups=None, |
| 1216 | ) | 1266 | ) |
| 1217 | if not project.DeleteWorktree( | 1267 | project.DeleteWorktree( |
| 1218 | quiet=opt.quiet, force=opt.force_remove_dirty | 1268 | quiet=opt.quiet, force=opt.force_remove_dirty |
| 1219 | ): | 1269 | ) |
| 1220 | return 1 | ||
| 1221 | 1270 | ||
| 1222 | new_project_paths.sort() | 1271 | new_project_paths.sort() |
| 1223 | with open(file_path, "w") as fd: | 1272 | with open(file_path, "w") as fd: |
| @@ -1260,7 +1309,7 @@ later is required to fix a server side protocol bug. | |||
| 1260 | file=sys.stderr, | 1309 | file=sys.stderr, |
| 1261 | ) | 1310 | ) |
| 1262 | platform_utils.remove(copylinkfile_path) | 1311 | platform_utils.remove(copylinkfile_path) |
| 1263 | return False | 1312 | raise |
| 1264 | 1313 | ||
| 1265 | need_remove_files = [] | 1314 | need_remove_files = [] |
| 1266 | need_remove_files.extend( | 1315 | need_remove_files.extend( |
| @@ -1285,12 +1334,10 @@ later is required to fix a server side protocol bug. | |||
| 1285 | 1334 | ||
| 1286 | def _SmartSyncSetup(self, opt, smart_sync_manifest_path, manifest): | 1335 | def _SmartSyncSetup(self, opt, smart_sync_manifest_path, manifest): |
| 1287 | if not manifest.manifest_server: | 1336 | if not manifest.manifest_server: |
| 1288 | print( | 1337 | raise SmartSyncError( |
| 1289 | "error: cannot smart sync: no manifest server defined in " | 1338 | "error: cannot smart sync: no manifest server defined in " |
| 1290 | "manifest", | 1339 | "manifest" |
| 1291 | file=sys.stderr, | ||
| 1292 | ) | 1340 | ) |
| 1293 | sys.exit(1) | ||
| 1294 | 1341 | ||
| 1295 | manifest_server = manifest.manifest_server | 1342 | manifest_server = manifest.manifest_server |
| 1296 | if not opt.quiet: | 1343 | if not opt.quiet: |
| @@ -1368,33 +1415,28 @@ later is required to fix a server side protocol bug. | |||
| 1368 | with open(smart_sync_manifest_path, "w") as f: | 1415 | with open(smart_sync_manifest_path, "w") as f: |
| 1369 | f.write(manifest_str) | 1416 | f.write(manifest_str) |
| 1370 | except IOError as e: | 1417 | except IOError as e: |
| 1371 | print( | 1418 | raise SmartSyncError( |
| 1372 | "error: cannot write manifest to %s:\n%s" | 1419 | "error: cannot write manifest to %s:\n%s" |
| 1373 | % (smart_sync_manifest_path, e), | 1420 | % (smart_sync_manifest_path, e), |
| 1374 | file=sys.stderr, | 1421 | aggregate_errors=[e], |
| 1375 | ) | 1422 | ) |
| 1376 | sys.exit(1) | ||
| 1377 | self._ReloadManifest(manifest_name, manifest) | 1423 | self._ReloadManifest(manifest_name, manifest) |
| 1378 | else: | 1424 | else: |
| 1379 | print( | 1425 | raise SmartSyncError( |
| 1380 | "error: manifest server RPC call failed: %s" % manifest_str, | 1426 | "error: manifest server RPC call failed: %s" % manifest_str |
| 1381 | file=sys.stderr, | ||
| 1382 | ) | 1427 | ) |
| 1383 | sys.exit(1) | ||
| 1384 | except (socket.error, IOError, xmlrpc.client.Fault) as e: | 1428 | except (socket.error, IOError, xmlrpc.client.Fault) as e: |
| 1385 | print( | 1429 | raise SmartSyncError( |
| 1386 | "error: cannot connect to manifest server %s:\n%s" | 1430 | "error: cannot connect to manifest server %s:\n%s" |
| 1387 | % (manifest.manifest_server, e), | 1431 | % (manifest.manifest_server, e), |
| 1388 | file=sys.stderr, | 1432 | aggregate_errors=[e], |
| 1389 | ) | 1433 | ) |
| 1390 | sys.exit(1) | ||
| 1391 | except xmlrpc.client.ProtocolError as e: | 1434 | except xmlrpc.client.ProtocolError as e: |
| 1392 | print( | 1435 | raise SmartSyncError( |
| 1393 | "error: cannot connect to manifest server %s:\n%d %s" | 1436 | "error: cannot connect to manifest server %s:\n%d %s" |
| 1394 | % (manifest.manifest_server, e.errcode, e.errmsg), | 1437 | % (manifest.manifest_server, e.errcode, e.errmsg), |
| 1395 | file=sys.stderr, | 1438 | aggregate_errors=[e], |
| 1396 | ) | 1439 | ) |
| 1397 | sys.exit(1) | ||
| 1398 | 1440 | ||
| 1399 | return manifest_name | 1441 | return manifest_name |
| 1400 | 1442 | ||
| @@ -1436,7 +1478,7 @@ later is required to fix a server side protocol bug. | |||
| 1436 | """ | 1478 | """ |
| 1437 | if not opt.local_only: | 1479 | if not opt.local_only: |
| 1438 | start = time.time() | 1480 | start = time.time() |
| 1439 | success = mp.Sync_NetworkHalf( | 1481 | result = mp.Sync_NetworkHalf( |
| 1440 | quiet=opt.quiet, | 1482 | quiet=opt.quiet, |
| 1441 | verbose=opt.verbose, | 1483 | verbose=opt.verbose, |
| 1442 | current_branch_only=self._GetCurrentBranchOnly( | 1484 | current_branch_only=self._GetCurrentBranchOnly( |
| @@ -1453,19 +1495,24 @@ later is required to fix a server side protocol bug. | |||
| 1453 | ) | 1495 | ) |
| 1454 | finish = time.time() | 1496 | finish = time.time() |
| 1455 | self.event_log.AddSync( | 1497 | self.event_log.AddSync( |
| 1456 | mp, event_log.TASK_SYNC_NETWORK, start, finish, success | 1498 | mp, event_log.TASK_SYNC_NETWORK, start, finish, result.success |
| 1457 | ) | 1499 | ) |
| 1458 | 1500 | ||
| 1459 | if mp.HasChanges: | 1501 | if mp.HasChanges: |
| 1502 | errors = [] | ||
| 1460 | syncbuf = SyncBuffer(mp.config) | 1503 | syncbuf = SyncBuffer(mp.config) |
| 1461 | start = time.time() | 1504 | start = time.time() |
| 1462 | mp.Sync_LocalHalf(syncbuf, submodules=mp.manifest.HasSubmodules) | 1505 | mp.Sync_LocalHalf( |
| 1506 | syncbuf, submodules=mp.manifest.HasSubmodules, errors=errors | ||
| 1507 | ) | ||
| 1463 | clean = syncbuf.Finish() | 1508 | clean = syncbuf.Finish() |
| 1464 | self.event_log.AddSync( | 1509 | self.event_log.AddSync( |
| 1465 | mp, event_log.TASK_SYNC_LOCAL, start, time.time(), clean | 1510 | mp, event_log.TASK_SYNC_LOCAL, start, time.time(), clean |
| 1466 | ) | 1511 | ) |
| 1467 | if not clean: | 1512 | if not clean: |
| 1468 | sys.exit(1) | 1513 | raise UpdateManifestError( |
| 1514 | aggregate_errors=errors, project=mp.name | ||
| 1515 | ) | ||
| 1469 | self._ReloadManifest(manifest_name, mp.manifest) | 1516 | self._ReloadManifest(manifest_name, mp.manifest) |
| 1470 | 1517 | ||
| 1471 | def ValidateOptions(self, opt, args): | 1518 | def ValidateOptions(self, opt, args): |
| @@ -1546,6 +1593,15 @@ later is required to fix a server side protocol bug. | |||
| 1546 | opt.jobs_checkout = min(opt.jobs_checkout, jobs_soft_limit) | 1593 | opt.jobs_checkout = min(opt.jobs_checkout, jobs_soft_limit) |
| 1547 | 1594 | ||
| 1548 | def Execute(self, opt, args): | 1595 | def Execute(self, opt, args): |
| 1596 | errors = [] | ||
| 1597 | try: | ||
| 1598 | self._ExecuteHelper(opt, args, errors) | ||
| 1599 | except RepoExitError: | ||
| 1600 | raise | ||
| 1601 | except (KeyboardInterrupt, Exception) as e: | ||
| 1602 | raise RepoUnhandledExceptionError(e, aggregate_errors=errors) | ||
| 1603 | |||
| 1604 | def _ExecuteHelper(self, opt, args, errors): | ||
| 1549 | manifest = self.outer_manifest | 1605 | manifest = self.outer_manifest |
| 1550 | if not opt.outer_manifest: | 1606 | if not opt.outer_manifest: |
| 1551 | manifest = self.manifest | 1607 | manifest = self.manifest |
| @@ -1695,6 +1751,8 @@ later is required to fix a server side protocol bug. | |||
| 1695 | result = self._FetchMain( | 1751 | result = self._FetchMain( |
| 1696 | opt, args, all_projects, err_event, ssh_proxy, manifest | 1752 | opt, args, all_projects, err_event, ssh_proxy, manifest |
| 1697 | ) | 1753 | ) |
| 1754 | if result.errors: | ||
| 1755 | errors.extend(result.errors) | ||
| 1698 | all_projects = result.all_projects | 1756 | all_projects = result.all_projects |
| 1699 | 1757 | ||
| 1700 | if opt.network_only: | 1758 | if opt.network_only: |
| @@ -1712,36 +1770,47 @@ later is required to fix a server side protocol bug. | |||
| 1712 | "`repo sync -l` will update some local checkouts.", | 1770 | "`repo sync -l` will update some local checkouts.", |
| 1713 | file=sys.stderr, | 1771 | file=sys.stderr, |
| 1714 | ) | 1772 | ) |
| 1715 | sys.exit(1) | 1773 | raise SyncFailFastError(aggregate_errors=errors) |
| 1716 | 1774 | ||
| 1717 | for m in self.ManifestList(opt): | 1775 | for m in self.ManifestList(opt): |
| 1718 | if m.IsMirror or m.IsArchive: | 1776 | if m.IsMirror or m.IsArchive: |
| 1719 | # Bail out now, we have no working tree. | 1777 | # Bail out now, we have no working tree. |
| 1720 | continue | 1778 | continue |
| 1721 | 1779 | ||
| 1722 | if self.UpdateProjectList(opt, m): | 1780 | try: |
| 1781 | self.UpdateProjectList(opt, m) | ||
| 1782 | except Exception as e: | ||
| 1723 | err_event.set() | 1783 | err_event.set() |
| 1724 | err_update_projects = True | 1784 | err_update_projects = True |
| 1785 | errors.append(e) | ||
| 1786 | if isinstance(e, DeleteWorktreeError): | ||
| 1787 | errors.extend(e.aggregate_errors) | ||
| 1725 | if opt.fail_fast: | 1788 | if opt.fail_fast: |
| 1726 | print( | 1789 | print( |
| 1727 | "\nerror: Local checkouts *not* updated.", | 1790 | "\nerror: Local checkouts *not* updated.", |
| 1728 | file=sys.stderr, | 1791 | file=sys.stderr, |
| 1729 | ) | 1792 | ) |
| 1730 | sys.exit(1) | 1793 | raise SyncFailFastError(aggregate_errors=errors) |
| 1731 | 1794 | ||
| 1732 | err_update_linkfiles = not self.UpdateCopyLinkfileList(m) | 1795 | err_update_linkfiles = False |
| 1733 | if err_update_linkfiles: | 1796 | try: |
| 1797 | self.UpdateCopyLinkfileList(m) | ||
| 1798 | except Exception as e: | ||
| 1799 | err_update_linkfiles = True | ||
| 1800 | errors.append(e) | ||
| 1734 | err_event.set() | 1801 | err_event.set() |
| 1735 | if opt.fail_fast: | 1802 | if opt.fail_fast: |
| 1736 | print( | 1803 | print( |
| 1737 | "\nerror: Local update copyfile or linkfile failed.", | 1804 | "\nerror: Local update copyfile or linkfile failed.", |
| 1738 | file=sys.stderr, | 1805 | file=sys.stderr, |
| 1739 | ) | 1806 | ) |
| 1740 | sys.exit(1) | 1807 | raise SyncFailFastError(aggregate_errors=errors) |
| 1741 | 1808 | ||
| 1742 | err_results = [] | 1809 | err_results = [] |
| 1743 | # NB: We don't exit here because this is the last step. | 1810 | # NB: We don't exit here because this is the last step. |
| 1744 | err_checkout = not self._Checkout(all_projects, opt, err_results) | 1811 | err_checkout = not self._Checkout( |
| 1812 | all_projects, opt, err_results, errors | ||
| 1813 | ) | ||
| 1745 | if err_checkout: | 1814 | if err_checkout: |
| 1746 | err_event.set() | 1815 | err_event.set() |
| 1747 | 1816 | ||
| @@ -1784,7 +1853,7 @@ later is required to fix a server side protocol bug. | |||
| 1784 | "error.", | 1853 | "error.", |
| 1785 | file=sys.stderr, | 1854 | file=sys.stderr, |
| 1786 | ) | 1855 | ) |
| 1787 | sys.exit(1) | 1856 | raise SyncError(aggregate_errors=errors) |
| 1788 | 1857 | ||
| 1789 | # Log the previous sync analysis state from the config. | 1858 | # Log the previous sync analysis state from the config. |
| 1790 | self.git_event_log.LogDataConfigEvents( | 1859 | self.git_event_log.LogDataConfigEvents( |
| @@ -1842,7 +1911,7 @@ def _PostRepoFetch(rp, repo_verify=True, verbose=False): | |||
| 1842 | try: | 1911 | try: |
| 1843 | rp.work_git.reset("--keep", new_rev) | 1912 | rp.work_git.reset("--keep", new_rev) |
| 1844 | except GitError as e: | 1913 | except GitError as e: |
| 1845 | sys.exit(str(e)) | 1914 | raise RepoUnhandledExceptionError(e) |
| 1846 | print("info: Restarting repo with latest version", file=sys.stderr) | 1915 | print("info: Restarting repo with latest version", file=sys.stderr) |
| 1847 | raise RepoChangedException(["--repo-upgraded"]) | 1916 | raise RepoChangedException(["--repo-upgraded"]) |
| 1848 | else: | 1917 | else: |
