vcs-ignore-0.1.0.0: app/Main.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
-- |
-- Module : Main
-- Description : Simple application using the /vcs-ignore/ library
-- Copyright : (c) 2020-2026 Vaclav Svejcar
-- License : BSD-3-Clause
-- Maintainer : vaclav.svejcar@gmail.com
-- Stability : experimental
-- Portability : POSIX
--
-- This simple application demonstrates the use of "vcs-ignore" library. It allows
-- to check whether path given as argument is ignored within existing /GIT/ repo.
module Main (
main,
) where
import Control.Monad (when)
import Data.VCS.Ignore (
GitRepository,
PathKind (..),
findGitRepository,
isIgnored,
repositoryRoot,
)
import Main.Options (
Mode (..),
Options (..),
optionsParser,
)
import Options.Applicative (execParser)
import System.Directory (
doesDirectoryExist,
doesFileExist,
getCurrentDirectory,
makeAbsolute,
pathIsSymbolicLink,
)
import System.Exit (
exitFailure,
exitSuccess,
)
import System.FilePath (makeRelative, normalise)
import System.IO.Error (
isDoesNotExistError,
tryIOError,
)
main :: IO ()
main = do
options <- execParser optionsParser
repo <- findRepoOrFail options
executeMode repo options
findRepoOrFail :: Options -> IO GitRepository
findRepoOrFail Options{..} = do
repoDir <- getCurrentDirectory
maybeRepo <- findGitRepository repoDir
case maybeRepo of
Just repo -> do
putStrLn $ "Found repository at: " <> repositoryRoot repo
when oDebug (putStrLn $ "Repository root: " <> repositoryRoot repo)
pure repo
Nothing -> do
putStrLn $ "No repository found for path: " <> repoDir
exitFailure
executeMode :: GitRepository -> Options -> IO ()
executeMode repo (oMode -> Path path) = checkPath repo path
checkPath :: GitRepository -> FilePath -> IO ()
checkPath repo path = do
absolute <- normalise <$> makeAbsolute path
kind <- classifyPath absolute
let relative = makeRelative (repositoryRoot repo) absolute
excluded <- isIgnored repo kind relative
if excluded then reportIgnored else reportNotIgnored
where
reportIgnored = do
putStrLn $ "Path '" <> path <> "' IS ignored"
exitSuccess
reportNotIgnored = do
putStrLn $ "Path '" <> path <> "' IS NOT ignored"
exitFailure
classifyPath :: FilePath -> IO PathKind
classifyPath path = do
symbolicLinkResult <- tryIOError $ pathIsSymbolicLink path
case symbolicLinkResult of
Left error'
| isDoesNotExistError error' -> pure Other
| otherwise -> ioError error'
Right True -> pure SymbolicLink
Right False -> do
directory <- doesDirectoryExist path
regularFile <- doesFileExist path
pure $ if directory then Directory else if regularFile then RegularFile else Other