From f70a60b85019766ee0a1cb61fa06c342b48f5172 Mon Sep 17 00:00:00 2001
From: Alexander Foremny <aforemny@posteo.de>
Date: Mon, 25 Mar 2024 14:57:48 +0100
Subject: fix: fix first scramble having to scan all files

---
 app/History/IssueEvents.hs | 26 ++++++++++++++++++--------
 app/History/Issues.hs      | 15 +++++++++++----
 app/History/Scramble.hs    | 13 +------------
 3 files changed, 30 insertions(+), 24 deletions(-)

(limited to 'app/History')

diff --git a/app/History/IssueEvents.hs b/app/History/IssueEvents.hs
index 3fca32a..fc5feff 100644
--- a/app/History/IssueEvents.hs
+++ b/app/History/IssueEvents.hs
@@ -21,7 +21,8 @@ import IssueEvent qualified as E
 
 data IssueEvents = IssueEvents
   { commitHash :: Backend.CommitHash,
-    issueEvents :: [E.IssueEvent]
+    issueEvents :: [E.IssueEvent],
+    filesSeen :: [FilePath]
   }
   deriving (Show, Generic, Binary)
 
@@ -38,6 +39,7 @@ instance Planable IssueEvents where
           [ IssueCreated commitHash issue
             | issue <- M.elems issues
           ],
+        filesSeen = filesChanged,
         ..
       }
 
@@ -129,17 +131,27 @@ propagateIssueEvents log topIssueEvents bottomScramble =
                     ],
                   concat
                     [ -- CASE 4. The issue it not present in the top/earlier history, but contained in the bottom scramble. It had to be deleted by the top/ earlier commit.
-                      [ IssueDeleted topIssueEvents.commitHash bottomIssue {closed = True},
-                        IssueCreated bottomCommitHash bottomIssue
-                      ]
+                      ( if bottomIssue.file `elem` topIssueEvents.filesSeen
+                          then
+                            [ IssueDeleted topIssueEvents.commitHash bottomIssue {closed = True},
+                              IssueCreated bottomCommitHash bottomIssue
+                            ]
+                          else
+                            [ IssueCreated bottomCommitHash bottomIssue
+                            ]
+                      )
                       | bottomIssue <- bottomIssues,
                         all ((`nsym` bottomIssue) . issue . NE.last) issueEventsPerIssue
                     ]
-                ]
+                ],
+      filesSeen = nub (topIssueEvents.filesSeen ++ bottomScramble.filesChanged)
     }
   where
     groupPerIssue =
-      map (NE.sortBy (comparing logOrder)) . NE.groupBy (sym `on` issue) . sortOn ((.id) . issue)
+      map (NE.sortBy (comparing logOrder))
+        . NE.groupBy (sym `on` issue)
+        . sortOn ((.id) . issue)
+    logOrder = fromMaybe (-1) . (`elemIndex` log) . commitHash
 
     topCommitHash = topIssueEvents.commitHash
     bottomCommitHash = bottomScramble.commitHash
@@ -158,5 +170,3 @@ propagateIssueEvents log topIssueEvents bottomScramble =
     issue (IssueChanged _ _ issue) = issue
     issue (IssueCreated _ issue) = issue
     issue (IssueDeleted _ issue) = issue
-
-    logOrder = fromMaybe (-1) . (`elemIndex` log) . commitHash
diff --git a/app/History/Issues.hs b/app/History/Issues.hs
index 1af0084..09f51dd 100644
--- a/app/History/Issues.hs
+++ b/app/History/Issues.hs
@@ -6,6 +6,7 @@ where
 import Backend qualified
 import Data.Binary (Binary)
 import Data.Function (on)
+import Data.List (nub)
 import Data.Map qualified as M
 import Data.Proxy (Proxy)
 import Data.Text qualified as T
@@ -16,7 +17,8 @@ import Issue qualified as I
 
 data Issues = Issues
   { commitHash :: Backend.CommitHash,
-    issues :: M.Map T.Text I.Issue
+    issues :: M.Map T.Text I.Issue,
+    filesSeen :: [FilePath]
   }
   deriving (Show, Generic, Binary)
 
@@ -27,7 +29,7 @@ instance Planable Issues where
   protoOf _ = getScramble
 
   assume :: Scramble -> Issues
-  assume (Scramble {..}) = Issues {..}
+  assume (Scramble {..}) = Issues {filesSeen = filesChanged, ..}
 
   propagate :: [Id Issues] -> Issues -> Scramble -> Issues
   propagate _ topIssues bottomScramble =
@@ -51,9 +53,14 @@ instance Planable Issues where
             (\topIssues -> topIssues)
             ( \bottomIssues ->
                 M.map
-                  (\bottomIssue -> bottomIssue {I.closed = True})
+                  ( \bottomIssue ->
+                      if bottomIssue.file `elem` topIssues.filesSeen
+                        then bottomIssue {I.closed = True}
+                        else bottomIssue
+                  )
                   bottomIssues
             )
             topIssues.issues
-            bottomScramble.issues
+            bottomScramble.issues,
+        filesSeen = nub (topIssues.filesSeen ++ bottomScramble.filesChanged)
       }
diff --git a/app/History/Scramble.hs b/app/History/Scramble.hs
index 093db98..ca4f4f8 100644
--- a/app/History/Scramble.hs
+++ b/app/History/Scramble.hs
@@ -36,18 +36,7 @@ data Scramble = Scramble
   deriving (Show, Binary, Generic)
 
 getScramble :: Backend.CommitHash -> IO Scramble
-getScramble commitHash@Backend.WorkingTree = do
-  filesChanged <- Backend.getFilesOf commitHash
-  issues <- concat <$> mapM (getIssuesOfFile commitHash) filesChanged
-  pure $
-    Scramble
-      { issues =
-          M.unions
-            [ M.singleton issue.id issue | issue <- issues
-            ],
-        ..
-      }
-getScramble commitHash@(Backend.Commit _) = do
+getScramble commitHash = do
   filesChanged <- Backend.getChangedFilesOf commitHash
   issues <- concat <$> mapM (getIssuesOfFile commitHash) filesChanged
   pure $
-- 
cgit v1.2.3