diff options
-rw-r--r-- | repo_logging.py | 22 | ||||
-rw-r--r-- | subcmds/sync.py | 191 | ||||
-rw-r--r-- | tests/test_repo_logging.py | 31 |
3 files changed, 102 insertions, 142 deletions
diff --git a/repo_logging.py b/repo_logging.py index b748df4f..e94af7df 100644 --- a/repo_logging.py +++ b/repo_logging.py | |||
@@ -15,7 +15,7 @@ | |||
15 | """Logic for printing user-friendly logs in repo.""" | 15 | """Logic for printing user-friendly logs in repo.""" |
16 | 16 | ||
17 | import logging | 17 | import logging |
18 | import multiprocessing | 18 | from typing import Any, List |
19 | 19 | ||
20 | from color import Coloring | 20 | from color import Coloring |
21 | 21 | ||
@@ -45,31 +45,25 @@ class ConfigMock: | |||
45 | class RepoLogger(logging.Logger): | 45 | class RepoLogger(logging.Logger): |
46 | """Repo Logging Module.""" | 46 | """Repo Logging Module.""" |
47 | 47 | ||
48 | # Aggregates error-level logs. This is used to generate an error summary | 48 | def __init__(self, name: str, config=None, **kwargs): |
49 | # section at the end of a command execution. | ||
50 | errors = multiprocessing.Manager().list() | ||
51 | |||
52 | def __init__(self, name, config=None, **kwargs): | ||
53 | super().__init__(name, **kwargs) | 49 | super().__init__(name, **kwargs) |
54 | self.config = config if config else ConfigMock() | 50 | self.config = config if config else ConfigMock() |
55 | self.colorer = LogColoring(self.config) | 51 | self.colorer = LogColoring(self.config) |
56 | 52 | ||
57 | def error(self, msg, *args, **kwargs): | 53 | def error(self, msg: Any, *args, **kwargs): |
58 | """Print and aggregate error-level logs.""" | 54 | """Print and aggregate error-level logs.""" |
59 | colored_error = self.colorer.error(msg, *args) | 55 | colored_error = self.colorer.error(str(msg), *args) |
60 | RepoLogger.errors.append(colored_error) | ||
61 | |||
62 | super().error(colored_error, **kwargs) | 56 | super().error(colored_error, **kwargs) |
63 | 57 | ||
64 | def warning(self, msg, *args, **kwargs): | 58 | def warning(self, msg: Any, *args, **kwargs): |
65 | """Print warning-level logs with coloring.""" | 59 | """Print warning-level logs with coloring.""" |
66 | colored_warning = self.colorer.warning(msg, *args) | 60 | colored_warning = self.colorer.warning(str(msg), *args) |
67 | super().warning(colored_warning, **kwargs) | 61 | super().warning(colored_warning, **kwargs) |
68 | 62 | ||
69 | def log_aggregated_errors(self): | 63 | def log_aggregated_errors(self, errors: List[Exception]): |
70 | """Print all aggregated logs.""" | 64 | """Print all aggregated logs.""" |
71 | super().error(self.colorer.error(SEPARATOR)) | 65 | super().error(self.colorer.error(SEPARATOR)) |
72 | super().error( | 66 | super().error( |
73 | self.colorer.error("Repo command failed due to following errors:") | 67 | self.colorer.error("Repo command failed due to following errors:") |
74 | ) | 68 | ) |
75 | super().error("\n".join(RepoLogger.errors)) | 69 | super().error("\n".join(map(str, errors))) |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 13c964b2..7ccd680f 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -22,7 +22,6 @@ import netrc | |||
22 | import optparse | 22 | import optparse |
23 | import os | 23 | import os |
24 | import socket | 24 | import socket |
25 | import sys | ||
26 | import tempfile | 25 | import tempfile |
27 | import time | 26 | import time |
28 | from typing import List, NamedTuple, Set | 27 | from typing import List, NamedTuple, Set |
@@ -74,6 +73,7 @@ from project import DeleteWorktreeError | |||
74 | from project import Project | 73 | from project import Project |
75 | from project import RemoteSpec | 74 | from project import RemoteSpec |
76 | from project import SyncBuffer | 75 | from project import SyncBuffer |
76 | from repo_logging import RepoLogger | ||
77 | from repo_trace import Trace | 77 | from repo_trace import Trace |
78 | import ssh | 78 | import ssh |
79 | from wrapper import Wrapper | 79 | from wrapper import Wrapper |
@@ -88,6 +88,8 @@ _AUTO_GC = os.environ.get(_REPO_AUTO_GC) == "1" | |||
88 | 88 | ||
89 | _REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW") | 89 | _REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW") |
90 | 90 | ||
91 | logger = RepoLogger(__file__) | ||
92 | |||
91 | 93 | ||
92 | class _FetchOneResult(NamedTuple): | 94 | class _FetchOneResult(NamedTuple): |
93 | """_FetchOne return value. | 95 | """_FetchOne return value. |
@@ -580,9 +582,10 @@ later is required to fix a server side protocol bug. | |||
580 | superproject_logging_data["superproject"] = False | 582 | superproject_logging_data["superproject"] = False |
581 | superproject_logging_data["noworktree"] = True | 583 | superproject_logging_data["noworktree"] = True |
582 | if opt.use_superproject is not False: | 584 | if opt.use_superproject is not False: |
583 | print( | 585 | logger.warning( |
584 | f"{m.path_prefix}: not using superproject because " | 586 | "%s: not using superproject because there is no " |
585 | "there is no working tree." | 587 | "working tree.", |
588 | m.path_prefix, | ||
586 | ) | 589 | ) |
587 | 590 | ||
588 | if not use_super: | 591 | if not use_super: |
@@ -602,13 +605,13 @@ later is required to fix a server side protocol bug. | |||
602 | need_unload = True | 605 | need_unload = True |
603 | else: | 606 | else: |
604 | if print_messages: | 607 | if print_messages: |
605 | print( | 608 | logger.warning( |
606 | f"{m.path_prefix}: warning: Update of revisionId from " | 609 | "%s: warning: Update of revisionId from superproject " |
607 | "superproject has failed, repo sync will not use " | 610 | "has failed, repo sync will not use superproject to " |
608 | "superproject to fetch the source. ", | 611 | "fetch the source. Please resync with the " |
609 | "Please resync with the --no-use-superproject option " | 612 | "--no-use-superproject option to avoid this repo " |
610 | "to avoid this repo warning.", | 613 | "warning.", |
611 | file=sys.stderr, | 614 | m.path_prefix, |
612 | ) | 615 | ) |
613 | if update_result.fatal and opt.use_superproject is not None: | 616 | if update_result.fatal and opt.use_superproject is not None: |
614 | raise SuperprojectError() | 617 | raise SuperprojectError() |
@@ -676,21 +679,22 @@ later is required to fix a server side protocol bug. | |||
676 | print("\n" + output.rstrip()) | 679 | print("\n" + output.rstrip()) |
677 | 680 | ||
678 | if not success: | 681 | if not success: |
679 | print( | 682 | logger.error( |
680 | "error: Cannot fetch %s from %s" | 683 | "error: Cannot fetch %s from %s", |
681 | % (project.name, project.remote.url), | 684 | project.name, |
682 | file=sys.stderr, | 685 | project.remote.url, |
683 | ) | 686 | ) |
684 | except KeyboardInterrupt: | 687 | except KeyboardInterrupt: |
685 | print(f"Keyboard interrupt while processing {project.name}") | 688 | logger.error("Keyboard interrupt while processing %s", project.name) |
686 | except GitError as e: | 689 | except GitError as e: |
687 | print("error.GitError: Cannot fetch %s" % str(e), file=sys.stderr) | 690 | logger.error("error.GitError: Cannot fetch %s", e) |
688 | errors.append(e) | 691 | errors.append(e) |
689 | except Exception as e: | 692 | except Exception as e: |
690 | print( | 693 | logger.error( |
691 | "error: Cannot fetch %s (%s: %s)" | 694 | "error: Cannot fetch %s (%s: %s)", |
692 | % (project.name, type(e).__name__, str(e)), | 695 | project.name, |
693 | file=sys.stderr, | 696 | type(e).__name__, |
697 | e, | ||
694 | ) | 698 | ) |
695 | del self._sync_dict[k] | 699 | del self._sync_dict[k] |
696 | errors.append(e) | 700 | errors.append(e) |
@@ -887,14 +891,13 @@ later is required to fix a server side protocol bug. | |||
887 | if opt.network_only: | 891 | if opt.network_only: |
888 | # Bail out now; the rest touches the working tree. | 892 | # Bail out now; the rest touches the working tree. |
889 | if err_event.is_set(): | 893 | if err_event.is_set(): |
890 | print( | 894 | e = SyncError( |
891 | "\nerror: Exited sync due to fetch errors.\n", | ||
892 | file=sys.stderr, | ||
893 | ) | ||
894 | raise SyncError( | ||
895 | "error: Exited sync due to fetch errors.", | 895 | "error: Exited sync due to fetch errors.", |
896 | aggregate_errors=errors, | 896 | aggregate_errors=errors, |
897 | ) | 897 | ) |
898 | |||
899 | logger.error(e) | ||
900 | raise e | ||
898 | return _FetchMainResult([], errors) | 901 | return _FetchMainResult([], errors) |
899 | 902 | ||
900 | # Iteratively fetch missing and/or nested unregistered submodules. | 903 | # Iteratively fetch missing and/or nested unregistered submodules. |
@@ -954,22 +957,21 @@ later is required to fix a server side protocol bug. | |||
954 | ) | 957 | ) |
955 | success = syncbuf.Finish() | 958 | success = syncbuf.Finish() |
956 | except GitError as e: | 959 | except GitError as e: |
957 | print( | 960 | logger.error( |
958 | "error.GitError: Cannot checkout %s: %s" | 961 | "error.GitError: Cannot checkout %s: %s", project.name, e |
959 | % (project.name, str(e)), | ||
960 | file=sys.stderr, | ||
961 | ) | 962 | ) |
962 | errors.append(e) | 963 | errors.append(e) |
963 | except Exception as e: | 964 | except Exception as e: |
964 | print( | 965 | logger.error( |
965 | "error: Cannot checkout %s: %s: %s" | 966 | "error: Cannot checkout %s: %s: %s", |
966 | % (project.name, type(e).__name__, str(e)), | 967 | project.name, |
967 | file=sys.stderr, | 968 | type(e).__name__, |
969 | e, | ||
968 | ) | 970 | ) |
969 | raise | 971 | raise |
970 | 972 | ||
971 | if not success: | 973 | if not success: |
972 | print("error: Cannot checkout %s" % (project.name), file=sys.stderr) | 974 | logger.error("error: Cannot checkout %s", project.name) |
973 | finish = time.time() | 975 | finish = time.time() |
974 | return _CheckoutOneResult(success, errors, project, start, finish) | 976 | return _CheckoutOneResult(success, errors, project, start, finish) |
975 | 977 | ||
@@ -1088,25 +1090,27 @@ later is required to fix a server side protocol bug. | |||
1088 | ) | 1090 | ) |
1089 | if expected: | 1091 | if expected: |
1090 | if not opt.quiet: | 1092 | if not opt.quiet: |
1091 | print( | 1093 | logger.info( |
1092 | "\r%s: Shared project %s found, disabling pruning." | 1094 | "%s: Shared project %s found, disabling pruning.", |
1093 | % (relpath, project.name) | 1095 | relpath, |
1096 | project.name, | ||
1094 | ) | 1097 | ) |
1098 | |||
1095 | if git_require((2, 7, 0)): | 1099 | if git_require((2, 7, 0)): |
1096 | project.EnableRepositoryExtension("preciousObjects") | 1100 | project.EnableRepositoryExtension("preciousObjects") |
1097 | else: | 1101 | else: |
1098 | # This isn't perfect, but it's the best we can do with old | 1102 | # This isn't perfect, but it's the best we can do with old |
1099 | # git. | 1103 | # git. |
1100 | print( | 1104 | logger.warning( |
1101 | "\r%s: WARNING: shared projects are unreliable when " | 1105 | "%s: WARNING: shared projects are unreliable when " |
1102 | "using old versions of git; please upgrade to " | 1106 | "using old versions of git; please upgrade to " |
1103 | "git-2.7.0+." % (relpath,), | 1107 | "git-2.7.0+.", |
1104 | file=sys.stderr, | 1108 | relpath, |
1105 | ) | 1109 | ) |
1106 | project.config.SetString("gc.pruneExpire", "never") | 1110 | project.config.SetString("gc.pruneExpire", "never") |
1107 | else: | 1111 | else: |
1108 | if not opt.quiet: | 1112 | if not opt.quiet: |
1109 | print(f"\r{relpath}: not shared, disabling pruning.") | 1113 | logger.info("%s: not shared, disabling pruning.", relpath) |
1110 | project.config.SetString("extensions.preciousObjects", None) | 1114 | project.config.SetString("extensions.preciousObjects", None) |
1111 | project.config.SetString("gc.pruneExpire", None) | 1115 | project.config.SetString("gc.pruneExpire", None) |
1112 | 1116 | ||
@@ -1303,10 +1307,9 @@ later is required to fix a server side protocol bug. | |||
1303 | try: | 1307 | try: |
1304 | old_copylinkfile_paths = json.load(fp) | 1308 | old_copylinkfile_paths = json.load(fp) |
1305 | except Exception: | 1309 | except Exception: |
1306 | print( | 1310 | logger.error( |
1307 | "error: %s is not a json formatted file." | 1311 | "error: %s is not a json formatted file.", |
1308 | % copylinkfile_path, | 1312 | copylinkfile_path, |
1309 | file=sys.stderr, | ||
1310 | ) | 1313 | ) |
1311 | platform_utils.remove(copylinkfile_path) | 1314 | platform_utils.remove(copylinkfile_path) |
1312 | raise | 1315 | raise |
@@ -1341,7 +1344,7 @@ later is required to fix a server side protocol bug. | |||
1341 | 1344 | ||
1342 | manifest_server = manifest.manifest_server | 1345 | manifest_server = manifest.manifest_server |
1343 | if not opt.quiet: | 1346 | if not opt.quiet: |
1344 | print("Using manifest server %s" % manifest_server) | 1347 | logger.info("Using manifest server %s", manifest_server) |
1345 | 1348 | ||
1346 | if "@" not in manifest_server: | 1349 | if "@" not in manifest_server: |
1347 | username = None | 1350 | username = None |
@@ -1363,15 +1366,12 @@ later is required to fix a server side protocol bug. | |||
1363 | if auth: | 1366 | if auth: |
1364 | username, _account, password = auth | 1367 | username, _account, password = auth |
1365 | else: | 1368 | else: |
1366 | print( | 1369 | logger.error( |
1367 | "No credentials found for %s in .netrc" | 1370 | "No credentials found for %s in .netrc", |
1368 | % parse_result.hostname, | 1371 | parse_result.hostname, |
1369 | file=sys.stderr, | ||
1370 | ) | 1372 | ) |
1371 | except netrc.NetrcParseError as e: | 1373 | except netrc.NetrcParseError as e: |
1372 | print( | 1374 | logger.error("Error parsing .netrc file: %s", e) |
1373 | "Error parsing .netrc file: %s" % e, file=sys.stderr | ||
1374 | ) | ||
1375 | 1375 | ||
1376 | if username and password: | 1376 | if username and password: |
1377 | manifest_server = manifest_server.replace( | 1377 | manifest_server = manifest_server.replace( |
@@ -1517,10 +1517,9 @@ later is required to fix a server side protocol bug. | |||
1517 | 1517 | ||
1518 | def ValidateOptions(self, opt, args): | 1518 | def ValidateOptions(self, opt, args): |
1519 | if opt.force_broken: | 1519 | if opt.force_broken: |
1520 | print( | 1520 | logger.warning( |
1521 | "warning: -f/--force-broken is now the default behavior, and " | 1521 | "warning: -f/--force-broken is now the default behavior, and " |
1522 | "the options are deprecated", | 1522 | "the options are deprecated" |
1523 | file=sys.stderr, | ||
1524 | ) | 1523 | ) |
1525 | if opt.network_only and opt.detach_head: | 1524 | if opt.network_only and opt.detach_head: |
1526 | self.OptionParser.error("cannot combine -n and -d") | 1525 | self.OptionParser.error("cannot combine -n and -d") |
@@ -1545,11 +1544,12 @@ later is required to fix a server side protocol bug. | |||
1545 | opt.prune = True | 1544 | opt.prune = True |
1546 | 1545 | ||
1547 | if opt.auto_gc is None and _AUTO_GC: | 1546 | if opt.auto_gc is None and _AUTO_GC: |
1548 | print( | 1547 | logger.error( |
1549 | f"Will run `git gc --auto` because {_REPO_AUTO_GC} is set.", | 1548 | "Will run `git gc --auto` because %s is set. %s is deprecated " |
1550 | f"{_REPO_AUTO_GC} is deprecated and will be removed in a ", | 1549 | "and will be removed in a future release. Use `--auto-gc` " |
1551 | "future release. Use `--auto-gc` instead.", | 1550 | "instead.", |
1552 | file=sys.stderr, | 1551 | _REPO_AUTO_GC, |
1552 | _REPO_AUTO_GC, | ||
1553 | ) | 1553 | ) |
1554 | opt.auto_gc = True | 1554 | opt.auto_gc = True |
1555 | 1555 | ||
@@ -1626,10 +1626,10 @@ later is required to fix a server side protocol bug. | |||
1626 | try: | 1626 | try: |
1627 | platform_utils.remove(smart_sync_manifest_path) | 1627 | platform_utils.remove(smart_sync_manifest_path) |
1628 | except OSError as e: | 1628 | except OSError as e: |
1629 | print( | 1629 | logger.error( |
1630 | "error: failed to remove existing smart sync override " | 1630 | "error: failed to remove existing smart sync override " |
1631 | "manifest: %s" % e, | 1631 | "manifest: %s", |
1632 | file=sys.stderr, | 1632 | e, |
1633 | ) | 1633 | ) |
1634 | 1634 | ||
1635 | err_event = multiprocessing.Event() | 1635 | err_event = multiprocessing.Event() |
@@ -1640,11 +1640,10 @@ later is required to fix a server side protocol bug. | |||
1640 | if cb: | 1640 | if cb: |
1641 | base = rp.GetBranch(cb).merge | 1641 | base = rp.GetBranch(cb).merge |
1642 | if not base or not base.startswith("refs/heads/"): | 1642 | if not base or not base.startswith("refs/heads/"): |
1643 | print( | 1643 | logger.warning( |
1644 | "warning: repo is not tracking a remote branch, so it will " | 1644 | "warning: repo is not tracking a remote branch, so it will " |
1645 | "not receive updates; run `repo init --repo-rev=stable` to " | 1645 | "not receive updates; run `repo init --repo-rev=stable` to " |
1646 | "fix.", | 1646 | "fix." |
1647 | file=sys.stderr, | ||
1648 | ) | 1647 | ) |
1649 | 1648 | ||
1650 | for m in self.ManifestList(opt): | 1649 | for m in self.ManifestList(opt): |
@@ -1667,7 +1666,7 @@ later is required to fix a server side protocol bug. | |||
1667 | if opt.mp_update: | 1666 | if opt.mp_update: |
1668 | self._UpdateAllManifestProjects(opt, mp, manifest_name) | 1667 | self._UpdateAllManifestProjects(opt, mp, manifest_name) |
1669 | else: | 1668 | else: |
1670 | print("Skipping update of local manifest project.") | 1669 | logger.info("Skipping update of local manifest project.") |
1671 | 1670 | ||
1672 | # Now that the manifests are up-to-date, setup options whose defaults | 1671 | # Now that the manifests are up-to-date, setup options whose defaults |
1673 | # might be in the manifest. | 1672 | # might be in the manifest. |
@@ -1719,12 +1718,11 @@ later is required to fix a server side protocol bug. | |||
1719 | if err_event.is_set(): | 1718 | if err_event.is_set(): |
1720 | err_network_sync = True | 1719 | err_network_sync = True |
1721 | if opt.fail_fast: | 1720 | if opt.fail_fast: |
1722 | print( | 1721 | logger.error( |
1723 | "\nerror: Exited sync due to fetch errors.\n" | 1722 | "error: Exited sync due to fetch errors.\n" |
1724 | "Local checkouts *not* updated. Resolve network issues " | 1723 | "Local checkouts *not* updated. Resolve network issues " |
1725 | "& retry.\n" | 1724 | "& retry.\n" |
1726 | "`repo sync -l` will update some local checkouts.", | 1725 | "`repo sync -l` will update some local checkouts." |
1727 | file=sys.stderr, | ||
1728 | ) | 1726 | ) |
1729 | raise SyncFailFastError(aggregate_errors=errors) | 1727 | raise SyncFailFastError(aggregate_errors=errors) |
1730 | 1728 | ||
@@ -1742,10 +1740,7 @@ later is required to fix a server side protocol bug. | |||
1742 | if isinstance(e, DeleteWorktreeError): | 1740 | if isinstance(e, DeleteWorktreeError): |
1743 | errors.extend(e.aggregate_errors) | 1741 | errors.extend(e.aggregate_errors) |
1744 | if opt.fail_fast: | 1742 | if opt.fail_fast: |
1745 | print( | 1743 | logger.error("error: Local checkouts *not* updated.") |
1746 | "\nerror: Local checkouts *not* updated.", | ||
1747 | file=sys.stderr, | ||
1748 | ) | ||
1749 | raise SyncFailFastError(aggregate_errors=errors) | 1744 | raise SyncFailFastError(aggregate_errors=errors) |
1750 | 1745 | ||
1751 | err_update_linkfiles = False | 1746 | err_update_linkfiles = False |
@@ -1756,9 +1751,8 @@ later is required to fix a server side protocol bug. | |||
1756 | errors.append(e) | 1751 | errors.append(e) |
1757 | err_event.set() | 1752 | err_event.set() |
1758 | if opt.fail_fast: | 1753 | if opt.fail_fast: |
1759 | print( | 1754 | logger.error( |
1760 | "\nerror: Local update copyfile or linkfile failed.", | 1755 | "error: Local update copyfile or linkfile failed." |
1761 | file=sys.stderr, | ||
1762 | ) | 1756 | ) |
1763 | raise SyncFailFastError(aggregate_errors=errors) | 1757 | raise SyncFailFastError(aggregate_errors=errors) |
1764 | 1758 | ||
@@ -1781,12 +1775,10 @@ later is required to fix a server side protocol bug. | |||
1781 | 1775 | ||
1782 | # If we saw an error, exit with code 1 so that other scripts can check. | 1776 | # If we saw an error, exit with code 1 so that other scripts can check. |
1783 | if err_event.is_set(): | 1777 | if err_event.is_set(): |
1784 | # Add a new line so it's easier to read. | ||
1785 | print("\n", file=sys.stderr) | ||
1786 | 1778 | ||
1787 | def print_and_log(err_msg): | 1779 | def print_and_log(err_msg): |
1788 | self.git_event_log.ErrorEvent(err_msg) | 1780 | self.git_event_log.ErrorEvent(err_msg) |
1789 | print(err_msg, file=sys.stderr) | 1781 | logger.error("%s", err_msg) |
1790 | 1782 | ||
1791 | print_and_log("error: Unable to fully sync the tree") | 1783 | print_and_log("error: Unable to fully sync the tree") |
1792 | if err_network_sync: | 1784 | if err_network_sync: |
@@ -1799,15 +1791,11 @@ later is required to fix a server side protocol bug. | |||
1799 | print_and_log("error: Checking out local projects failed.") | 1791 | print_and_log("error: Checking out local projects failed.") |
1800 | if err_results: | 1792 | if err_results: |
1801 | # Don't log repositories, as it may contain sensitive info. | 1793 | # Don't log repositories, as it may contain sensitive info. |
1802 | print( | 1794 | logger.error("Failing repos:\n%s", "\n".join(err_results)) |
1803 | "Failing repos:\n%s" % "\n".join(err_results), | ||
1804 | file=sys.stderr, | ||
1805 | ) | ||
1806 | # Not useful to log. | 1795 | # Not useful to log. |
1807 | print( | 1796 | logger.error( |
1808 | 'Try re-running with "-j1 --fail-fast" to exit at the first ' | 1797 | 'Try re-running with "-j1 --fail-fast" to exit at the first ' |
1809 | "error.", | 1798 | "error." |
1810 | file=sys.stderr, | ||
1811 | ) | 1799 | ) |
1812 | raise SyncError(aggregate_errors=errors) | 1800 | raise SyncError(aggregate_errors=errors) |
1813 | 1801 | ||
@@ -1824,14 +1812,13 @@ later is required to fix a server side protocol bug. | |||
1824 | 1812 | ||
1825 | self._local_sync_state.PruneRemovedProjects() | 1813 | self._local_sync_state.PruneRemovedProjects() |
1826 | if self._local_sync_state.IsPartiallySynced(): | 1814 | if self._local_sync_state.IsPartiallySynced(): |
1827 | print( | 1815 | logger.warning( |
1828 | "warning: Partial syncs are not supported. For the best " | 1816 | "warning: Partial syncs are not supported. For the best " |
1829 | "experience, sync the entire tree.", | 1817 | "experience, sync the entire tree." |
1830 | file=sys.stderr, | ||
1831 | ) | 1818 | ) |
1832 | 1819 | ||
1833 | if not opt.quiet: | 1820 | if not opt.quiet: |
1834 | print("repo sync has finished successfully.") | 1821 | logger.info("repo sync has finished successfully.") |
1835 | 1822 | ||
1836 | 1823 | ||
1837 | def _PostRepoUpgrade(manifest, quiet=False): | 1824 | def _PostRepoUpgrade(manifest, quiet=False): |
@@ -1854,7 +1841,7 @@ def _PostRepoUpgrade(manifest, quiet=False): | |||
1854 | 1841 | ||
1855 | def _PostRepoFetch(rp, repo_verify=True, verbose=False): | 1842 | def _PostRepoFetch(rp, repo_verify=True, verbose=False): |
1856 | if rp.HasChanges: | 1843 | if rp.HasChanges: |
1857 | print("info: A new version of repo is available", file=sys.stderr) | 1844 | logger.info("info: A new version of repo is available") |
1858 | wrapper = Wrapper() | 1845 | wrapper = Wrapper() |
1859 | try: | 1846 | try: |
1860 | rev = rp.bare_git.describe(rp.GetRevisionId()) | 1847 | rev = rp.bare_git.describe(rp.GetRevisionId()) |
@@ -1876,18 +1863,14 @@ def _PostRepoFetch(rp, repo_verify=True, verbose=False): | |||
1876 | rp.work_git.reset("--keep", new_rev) | 1863 | rp.work_git.reset("--keep", new_rev) |
1877 | except GitError as e: | 1864 | except GitError as e: |
1878 | raise RepoUnhandledExceptionError(e) | 1865 | raise RepoUnhandledExceptionError(e) |
1879 | print("info: Restarting repo with latest version", file=sys.stderr) | 1866 | logger.info("info: Restarting repo with latest version") |
1880 | raise RepoChangedException(["--repo-upgraded"]) | 1867 | raise RepoChangedException(["--repo-upgraded"]) |
1881 | else: | 1868 | else: |
1882 | print( | 1869 | logger.warning("warning: Skipped upgrade to unverified version") |
1883 | "warning: Skipped upgrade to unverified version", | ||
1884 | file=sys.stderr, | ||
1885 | ) | ||
1886 | else: | 1870 | else: |
1887 | if verbose: | 1871 | if verbose: |
1888 | print( | 1872 | logger.info( |
1889 | "repo version %s is current" % rp.work_git.describe(HEAD), | 1873 | "repo version %s is current", rp.work_git.describe(HEAD) |
1890 | file=sys.stderr, | ||
1891 | ) | 1874 | ) |
1892 | 1875 | ||
1893 | 1876 | ||
diff --git a/tests/test_repo_logging.py b/tests/test_repo_logging.py index 5402a90b..b51e6270 100644 --- a/tests/test_repo_logging.py +++ b/tests/test_repo_logging.py | |||
@@ -23,7 +23,6 @@ class TestRepoLogger(unittest.TestCase): | |||
23 | def test_error_logs_error(self): | 23 | def test_error_logs_error(self): |
24 | """Test if error fn outputs logs.""" | 24 | """Test if error fn outputs logs.""" |
25 | logger = RepoLogger(__name__) | 25 | logger = RepoLogger(__name__) |
26 | RepoLogger.errors[:] = [] | ||
27 | result = None | 26 | result = None |
28 | 27 | ||
29 | def mock_handler(log): | 28 | def mock_handler(log): |
@@ -42,7 +41,6 @@ class TestRepoLogger(unittest.TestCase): | |||
42 | def test_warning_logs_error(self): | 41 | def test_warning_logs_error(self): |
43 | """Test if warning fn outputs logs.""" | 42 | """Test if warning fn outputs logs.""" |
44 | logger = RepoLogger(__name__) | 43 | logger = RepoLogger(__name__) |
45 | RepoLogger.errors[:] = [] | ||
46 | result = None | 44 | result = None |
47 | 45 | ||
48 | def mock_handler(log): | 46 | def mock_handler(log): |
@@ -58,30 +56,9 @@ class TestRepoLogger(unittest.TestCase): | |||
58 | 56 | ||
59 | self.assertEqual(result, "You know the rules and so do I (do I)") | 57 | self.assertEqual(result, "You know the rules and so do I (do I)") |
60 | 58 | ||
61 | def test_error_aggregates_error_msg(self): | ||
62 | """Test if error fn aggregates error logs.""" | ||
63 | logger = RepoLogger(__name__) | ||
64 | RepoLogger.errors[:] = [] | ||
65 | |||
66 | logger.error("A full commitment's what I'm thinking of") | ||
67 | logger.error("You wouldn't get this from any other guy") | ||
68 | logger.error("I just wanna tell you how I'm feeling") | ||
69 | logger.error("Gotta make you understand") | ||
70 | |||
71 | self.assertEqual( | ||
72 | RepoLogger.errors[:], | ||
73 | [ | ||
74 | "A full commitment's what I'm thinking of", | ||
75 | "You wouldn't get this from any other guy", | ||
76 | "I just wanna tell you how I'm feeling", | ||
77 | "Gotta make you understand", | ||
78 | ], | ||
79 | ) | ||
80 | |||
81 | def test_log_aggregated_errors_logs_aggregated_errors(self): | 59 | def test_log_aggregated_errors_logs_aggregated_errors(self): |
82 | """Test if log_aggregated_errors outputs aggregated errors.""" | 60 | """Test if log_aggregated_errors outputs aggregated errors.""" |
83 | logger = RepoLogger(__name__) | 61 | logger = RepoLogger(__name__) |
84 | RepoLogger.errors[:] = [] | ||
85 | result = [] | 62 | result = [] |
86 | 63 | ||
87 | def mock_handler(log): | 64 | def mock_handler(log): |
@@ -96,7 +73,13 @@ class TestRepoLogger(unittest.TestCase): | |||
96 | logger.error("Never gonna give you up") | 73 | logger.error("Never gonna give you up") |
97 | logger.error("Never gonna let you down") | 74 | logger.error("Never gonna let you down") |
98 | logger.error("Never gonna run around and desert you") | 75 | logger.error("Never gonna run around and desert you") |
99 | logger.log_aggregated_errors() | 76 | logger.log_aggregated_errors( |
77 | [ | ||
78 | "Never gonna give you up", | ||
79 | "Never gonna let you down", | ||
80 | "Never gonna run around and desert you", | ||
81 | ] | ||
82 | ) | ||
100 | 83 | ||
101 | self.assertEqual( | 84 | self.assertEqual( |
102 | result, | 85 | result, |