aboutsummaryrefslogtreecommitdiffstats
path: root/app/Main.hs
blob: 179c2140b0b1a6784efd24405169e704f4b9d1dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
{-# LANGUAGE OverloadedStrings #-}

module Main where

import Control.Exception (Exception, catch, throw)
import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Lazy qualified as LB
import Data.ByteString.Lazy.Char8 qualified as LB8
import Data.Maybe qualified as Maybe
import Data.String qualified as String
import Options.Applicative ((<**>))
import Options.Applicative qualified as O
import System.FilePath as F
import System.Process.Typed qualified as P

data Options = Options
  { optCommand :: Command
  }
  deriving (Show)

data Command
  = List
  | Show
  deriving (Show)

optionsParser :: O.Parser Options
optionsParser =
  Options
    <$> commandParser

commandParser :: O.Parser Command
commandParser =
  O.subparser
    ( O.command "list" (O.info listCommandParser (O.progDesc "List all issues"))
        <> O.command "show" (O.info showCommandParser (O.progDesc "Show details of all issues"))
    )

listCommandParser :: O.Parser Command
listCommandParser =
  pure List

showCommandParser :: O.Parser Command
showCommandParser =
  pure Show

main :: IO ()
main = do
  options <- O.execParser (O.info (commandParser <**> O.helper) O.idm)
  files <- getFiles
  issues <-
    fmap Maybe.catMaybes $
      mapM
        (\filename -> catch (fmap Just (getIssues filename)) (forgetGetIssuesExceptions))
        files
  print issues

data UnknownFileExtension = UnknownFileExtension
  { extension :: String
  }
  deriving (Show)

instance Exception UnknownFileExtension

forgetGetIssuesExceptions :: UnknownFileExtension -> IO (Maybe String)
forgetGetIssuesExceptions _ =
  pure Nothing

data Issue = Issue {}

getIssues :: String -> IO String
getIssues filename =
  let extension = F.takeExtension filename
      treeGrepperLanguage =
        case extension of
          ".elm" -> "elm"
          ".nix" -> "nix"
          ".sh" -> "sh"
          _ -> throw (UnknownFileExtension extension)
      treeGrepperQuery =
        case extension of
          ".elm" -> "([(line_comment) (block_comment)])"
          ".nix" -> "(comment)"
          ".sh" -> "(comment)"
          _ -> throw (UnknownFileExtension extension)
   in fmap (LB8.unpack . snd) $
        P.readProcessStdout
          ( String.fromString
              ( "tree-grepper --query '"
                  ++ treeGrepperLanguage
                  ++ "' '"
                  ++ treeGrepperQuery
                  ++ "' --format json '"
                  ++ filename
                  ++ "'"
              )
          )

getFiles :: IO [String]
getFiles =
  fmap (lines . LB8.unpack . snd) $
    P.readProcessStdout "git ls-files --cached --exclude-standard --other"