aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorLibravatar Fabian Kirchner <kirchner@posteo.de>2023-11-07 14:21:33 +0100
committerLibravatar Fabian Kirchner <kirchner@posteo.de>2023-11-07 14:25:47 +0100
commit59ddbdb3d54de4009c2b3238661272f7e9fb80bc (patch)
tree9b62c8b9f81cb6f5a9f27b7a5dfe5746cbce05e1 /app
parent3bdaff7c176bdf00da9177a87819dad2c50c25b8 (diff)
add --group-by option
Diffstat (limited to 'app')
-rw-r--r--app/Issue/GroupBy.hs65
-rw-r--r--app/Main.hs67
2 files changed, 88 insertions, 44 deletions
diff --git a/app/Issue/GroupBy.hs b/app/Issue/GroupBy.hs
new file mode 100644
index 0000000..0e8941f
--- /dev/null
+++ b/app/Issue/GroupBy.hs
@@ -0,0 +1,65 @@
+module Issue.GroupBy
+ ( groupByArg,
+ groupIssuesBy,
+ )
+where
+
+import Data.Map (Map)
+import Data.Map qualified as M
+import Data.Maybe (mapMaybe)
+import Data.Text qualified as T
+import Issue (Issue (..))
+import Issue.Tag (Tag (..))
+import Issue.Tag qualified as I
+import Options.Applicative qualified as O
+
+
+-- FIXME Parse group by using @topic syntax
+
+-- TODO Display number of issues within one group
+--
+-- ```
+-- Issue D
+-- Issue E
+--
+-- @topic tags (2 issues)
+-- Issue A
+-- Issue B @topic ids
+--
+-- @topic ids (2 issues)
+-- Issue B @topic tags
+-- Issue C
+-- ```
+
+-- TODO Add issues marker as internal tags
+--
+-- The internal makers `TODO`, `FIXME`, etc. should be available via the
+-- internal tag @type
+
+-- TODO Add author and editor as internal tags
+
+groupByArg :: O.Parser (Maybe T.Text)
+groupByArg =
+ O.optional
+ ( O.strOption
+ ( O.long "group-by"
+ <> O.metavar "TAG"
+ <> O.help "Group selected issues."
+ )
+ )
+
+groupIssuesBy :: T.Text -> [Issue] -> Map T.Text [Issue]
+groupIssuesBy groupBy issues =
+ foldl
+ ( \collected issue ->
+ foldl
+ (flip $ M.alter (Just . maybe [issue] (issue :)))
+ collected
+ (groupsOfIssue groupBy issue)
+ )
+ M.empty
+ issues
+ where
+ groupsOfIssue group issue =
+ mapMaybe I.tagValue $
+ filter (\(Tag key _) -> key == group) (issue.tags ++ issue.internalTags)
diff --git a/app/Main.hs b/app/Main.hs
index 3e9dc1d..ee9e850 100644
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -249,48 +249,6 @@
-- allow that). The first marker should have priority in case we have to pick
-- one.
--- TODO Add option to group issue list
---
--- When running `anissue list` with the `--group-by` option, the output
--- will be grouped. E.g. running `anissue list --group-by topic` would
--- produce
---
--- ```
--- Issue D
--- Issue E
---
--- @topic tags (2 issues)
--- Issue A
--- Issue B @topic ids
---
--- @topic ids (2 issues)
--- Issue B @topic tags
--- Issue C
--- ```
---
--- Other possible grouping options could be
---
--- type
--- : the issue type, i.e. `TODO`, `FIXME`, `QUESTION`, etc.
---
--- priority
--- : the priority, groups should be sorted with the highest priority
--- first
---
--- author
--- : the person which created the issue
---
--- editor
--- : the person who updated the issue last
---
--- @topic options
---
--- COMMENT For consistency, I would like the option to use `--group-by @topic`.
--- Arbitrary tag grouping seems sufficient for this, assuming we add the
--- respective *internal tags*.
---
--- COMMENT Sounds good!
-
-- TODO Support issue comments
-- Currently, comments do not get picked up in issue descriptions; see the
-- issue below.
@@ -437,6 +395,7 @@ module Main where
import Control.Applicative ((<|>))
import Data.Function ((&))
import Data.List (find, isPrefixOf)
+import Data.Map qualified as M
import Data.Maybe (catMaybes)
import Data.Text qualified as T
import Data.Text.IO qualified as T
@@ -450,6 +409,7 @@ import Issue (Issue (..))
import Issue qualified as I
import Issue.Filter (Filter, applyFilters)
import Issue.Filter qualified as I
+import Issue.GroupBy qualified as I
import Issue.Provenance qualified as I
import Issue.Sort (Sort, applySorts)
import Issue.Sort qualified as I
@@ -539,7 +499,8 @@ data Command
= List
{ files :: [String],
filters :: [Filter],
- sort :: [Sort]
+ sort :: [Sort],
+ groupBy :: Maybe T.Text
}
| Log
| Show
@@ -565,6 +526,7 @@ listCmd =
<$> filesArg
<*> I.filterArg
<*> I.sortArg
+ <*> I.groupByArg
logCmd :: O.Parser Command
logCmd =
@@ -603,7 +565,24 @@ main :: IO ()
main = do
settings <- readSettings
O.execParser (O.info (options <**> O.helper) O.idm) >>= \case
- Options {colorize, noPager, width, command = List {sort, filters, files}} -> do
+ Options {colorize, noPager, width, command = List {sort, filters, files, groupBy = Just groupBy}} -> do
+ let withinPath issue = if null files then True else any (\file -> file `isPrefixOf` issue.file) files
+ ungroupedIssues <- applySorts sort . applyFilters filters . filter withinPath . fst <$> getHistory
+ let groupedIssues = I.groupIssuesBy groupBy ungroupedIssues
+ putDoc colorize noPager width . P.vsep $
+ map
+ ( \(name, issues) ->
+ P.vsep $
+ P.hardline
+ : P.annotate (P.color P.Red) (P.pretty name)
+ : map
+ ( \issue ->
+ P.indent 4 $ P.annotate P.bold $ P.pretty issue.title
+ )
+ issues
+ )
+ (M.toList groupedIssues)
+ Options {colorize, noPager, width, command = List {sort, filters, files, groupBy = Nothing}} -> do
let withinPath issue = if null files then True else any (\file -> file `isPrefixOf` issue.file) files
issues <- applySorts sort . applyFilters filters . filter withinPath . fst <$> getHistory
putDoc colorize noPager width . P.vsep $