sync: Switch to using self._bloated_projects

Store bloated projects in self._bloated_projects and print warnings at
the end of execution. This sets up for moving the check to workers.

Bug: 498290329
Change-Id: I993f1fd741db2994d480994861588eb18f6c5503
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/574922
Reviewed-by: Becky Siegel <beckysiegel@google.com>
Tested-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 5c39f71..85ead6c 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -1448,7 +1448,6 @@
         if not projects:
             return
 
-        bloated_projects = []
         pm = Progress(
             "Checking for bloat", len(projects), delay=False, quiet=opt.quiet
         )
@@ -1456,7 +1455,7 @@
         def _ProcessResults(pool, pm, results):
             for result in results:
                 if result:
-                    bloated_projects.append(result)
+                    self._bloated_projects.append(result)
                 pm.update(msg="")
 
         with self.ParallelContext():
@@ -1471,15 +1470,6 @@
             )
         pm.end()
 
-        for project_name in bloated_projects:
-            warn_msg = (
-                f'warning: Project "{project_name}" is accumulating '
-                'unoptimized data. Please run "repo sync --auto-gc" or '
-                '"repo gc --repack" to clean up.'
-            )
-            self.git_event_log.ErrorEvent(warn_msg)
-            logger.warning(warn_msg)
-
     def _UpdateRepoProject(self, opt, manifest, errors):
         """Fetch the repo project and check for updates."""
         if opt.local_only:
@@ -2097,6 +2087,7 @@
 
         self._fetch_times = _FetchTimes(manifest)
         self._local_sync_state = LocalSyncState(manifest)
+        self._bloated_projects = []
 
         if opt.interleaved:
             sync_method = self._SyncInterleaved
@@ -2137,6 +2128,15 @@
         if existing:
             self._CheckForBloatedProjects(all_projects, opt)
 
+        for project_name in sorted(self._bloated_projects):
+            warn_msg = (
+                f'warning: Project "{project_name}" is accumulating '
+                'unoptimized data. Please run "repo sync --auto-gc" or '
+                '"repo gc --repack" to clean up.'
+            )
+            self.git_event_log.ErrorEvent(warn_msg)
+            logger.warning(warn_msg)
+
         if not opt.quiet:
             print("repo sync has finished successfully.")
 
diff --git a/tests/test_subcmds_sync.py b/tests/test_subcmds_sync.py
index 07f14b0..a6be080 100644
--- a/tests/test_subcmds_sync.py
+++ b/tests/test_subcmds_sync.py
@@ -490,6 +490,7 @@
         self.project.Exists = True
         self.project.worktree = "worktree"
         self.cmd.git_event_log = mock.MagicMock()
+        self.cmd._bloated_projects = []
 
     @mock.patch("subcmds.sync.git_require")
     def test_git_version_unsupported(self, mock_git_require):
@@ -509,7 +510,7 @@
     @mock.patch("subcmds.sync.git_require")
     @mock.patch("subcmds.sync.Progress")
     def test_bloated_project_found(self, mock_progress, mock_git_require):
-        """Test that it logs warning for bloated project."""
+        """Test that it adds project to _bloated_projects."""
         mock_git_require.return_value = True
 
         self.cmd.get_parallel_context = mock.Mock(
@@ -527,7 +528,7 @@
         with mock.patch.object(self.cmd, "ParallelContext"):
             self.cmd._CheckForBloatedProjects([self.project], self.opt)
 
-        self.cmd.git_event_log.ErrorEvent.assert_called_once()
+        self.assertEqual(self.cmd._bloated_projects, ["project"])
 
 
 class GCProjectsTest(unittest.TestCase):