{-# 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"