aboutsummaryrefslogtreecommitdiffstats
path: root/app/History.hs
diff options
context:
space:
mode:
Diffstat (limited to 'app/History.hs')
-rw-r--r--app/History.hs61
1 files changed, 34 insertions, 27 deletions
diff --git a/app/History.hs b/app/History.hs
index 252380d..f1d3e97 100644
--- a/app/History.hs
+++ b/app/History.hs
@@ -30,15 +30,15 @@ import Prelude qualified as Prelude
listIssues :: [Filter] -> [FilePath] -> IO [Issue]
listIssues filters paths = do
- commits <- getCommits
- currentIssues <- listIssuesCurrent paths
- historicalIssues <- fmap concat $ parMapM (\commit -> cached commit (\_ -> listIssuesOf commit)) commits
- let currentIssuesFiltered = filter (applyFilter filters) currentIssues
+ commitHashes <- getCommitHashes
+ issuesWorkingTreeAll <- getIssuesWorkingTreeAll paths
+ historicalIssues <- fmap concat $ parMapM (\hash -> cached hash (\_ -> getIssuesCommitChanged hash)) commitHashes
+ let currentIssuesFiltered = filter (applyFilter filters) issuesWorkingTreeAll
pure $ map (fixProvenance historicalIssues) currentIssuesFiltered
-getCommits :: IO [Text]
-getCommits =
- fmap (lines . decodeUtf8 . L8.toStrict) $ sh ("git log --format=%H")
+getCommitHashes :: IO [Text]
+getCommitHashes =
+ fmap (lines . decodeUtf8 . L8.toStrict) $ sh "git log --format=%H"
fixProvenance :: [Issue] -> Issue -> Issue
fixProvenance historicalIssues =
@@ -59,21 +59,13 @@ merge (issue, issues) =
provenance : _ ->
issue {provenance = Just provenance}
-listIssuesCurrent :: [FilePath] -> IO [Issue]
-listIssuesCurrent paths = do
- worktree <- getCurrentDirectory
- files <- getFiles worktree paths
- concat <$> (catch (getIssuesPar worktree files) dieOfInvalidTreeGrepperResult)
-
-listIssuesOf :: Text -> IO [Issue]
-listIssuesOf commit = do
- withSystemTempDirectory "history" $ \tmp -> do
- worktree <- do
- let worktree = tmp </> unpack commit
- sh_ (fromString (printf "git worktree add --detach %s %s" (quote worktree) (quote (unpack commit))))
- pure worktree
- files <- getFilesChanged worktree
- concat <$> catch (getIssuesPar worktree files) (dieOfInvalidTreeGrepperResult)
+-- | Gets issues in all files in your current [working
+-- - tree](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefworkingtreeaworkingtree)
+getIssuesWorkingTreeAll :: [FilePath] -> IO [Issue]
+getIssuesWorkingTreeAll paths = do
+ cwd <- getCurrentDirectory
+ files <- getFiles cwd paths
+ concat <$> catch (getIssuesPar cwd files) dieOfInvalidTreeGrepperResult
getFiles :: FilePath -> [String] -> IO [FilePath]
getFiles cwd paths =
@@ -89,6 +81,18 @@ getFiles cwd paths =
& setWorkingDir cwd
)
+-- | Given the hash of a commit, get all issues in the files which have
+-- been changed by this commit.
+getIssuesCommitChanged :: Text -> IO [Issue]
+getIssuesCommitChanged hash = do
+ withSystemTempDirectory "history" $ \tmp -> do
+ cwd <- do
+ let cwd = tmp </> unpack hash
+ sh_ $ fromString $ printf "git worktree add --detach %s %s" (quote cwd) (quote $ unpack hash)
+ pure cwd
+ files <- getFilesChanged cwd
+ concat <$> catch (getIssuesPar cwd files) (dieOfInvalidTreeGrepperResult)
+
getFilesChanged :: FilePath -> IO [FilePath]
getFilesChanged cwd =
Prelude.lines . L8.unpack
@@ -97,9 +101,11 @@ getFilesChanged cwd =
& setWorkingDir cwd
)
+-- | Get all issues in the given directory and files. Runs
+-- parallelized.
getIssuesPar :: FilePath -> [FilePath] -> IO [[Issue]]
-getIssuesPar worktree =
- parMapM (handle forgetGetIssuesExceptions . getIssues worktree)
+getIssuesPar cwd files =
+ parMapM (handle forgetGetIssuesExceptions . getIssues cwd) files
data UnknownFileExtension = UnknownFileExtension
{ extension :: String
@@ -122,6 +128,7 @@ dieOfInvalidTreeGrepperResult :: InvalidTreeGrepperResult -> IO a
dieOfInvalidTreeGrepperResult (InvalidTreeGrepperResult e) =
die e
+-- | Get all issues in the given directory and file.
getIssues :: FilePath -> FilePath -> IO [Issue]
getIssues cwd filename = do
let extension = takeExtension filename
@@ -170,15 +177,15 @@ fixTreeGrepper treeGrepperResult =
treeGrepperResult {G.matches = G.merge treeGrepperResult.matches}
cached :: Binary a => Text -> (Text -> IO a) -> IO a
-cached commit func = do
+cached hash func = do
cwd <- getCurrentDirectory
createDirectoryIfMissing True (cwd ++ "/.anissue")
- let file = (cwd ++ "/.anissue/" ++ unpack commit)
+ let file = (cwd ++ "/.anissue/" ++ unpack hash)
fileExists <- doesFileExist file
if fileExists
then decodeFile file
else do
- blob <- func commit
+ blob <- func hash
encodeFile file blob
pure blob