stackctl-1.1.0.0: src/Stackctl/FilterOption.hs
module Stackctl.FilterOption
( FilterOption
, HasFilterOption(..)
, filterOption
, filterOptionFromPaths
, filterFilePaths
) where
import Stackctl.Prelude
import qualified Data.List.NonEmpty as NE
import qualified Data.Text as T
import Options.Applicative
import System.FilePath.Glob
newtype FilterOption = FilterOption
{ unFilterOption :: NonEmpty Pattern
}
instance ToJSON FilterOption where
toJSON = toJSON . showFilterOption
toEncoding = toEncoding . showFilterOption
class HasFilterOption env where
filterOptionL :: Lens' env FilterOption
instance HasFilterOption FilterOption where
filterOptionL = id
filterOption :: String -> Parser FilterOption
filterOption items = option (eitherReader readFilterOption) $ mconcat
[ long "filter"
, metavar "PATTERN[,PATTERN]"
, help $ "Filter " <> items <> " to match PATTERN(s)"
, value defaultFilterOption
, showDefaultWith showFilterOption
]
filterOptionFromPaths :: NonEmpty FilePath -> FilterOption
filterOptionFromPaths = FilterOption . fmap compile
readFilterOption :: String -> Either String FilterOption
readFilterOption =
maybe (Left err) (Right . FilterOption)
. NE.nonEmpty
. map (compile . unpack)
. filter (not . T.null)
. map T.strip
. T.splitOn ","
. pack
where err = "Must be non-empty, comma-separated list of non-empty patterns"
showFilterOption :: FilterOption -> String
showFilterOption =
unpack
. T.intercalate ","
. map (pack . decompile)
. NE.toList
. unFilterOption
defaultFilterOption :: FilterOption
defaultFilterOption = filterOptionFromPaths $ pure "**/*"
filterFilePaths :: FilterOption -> [FilePath] -> [FilePath]
filterFilePaths fo = filter $ \path -> any (`match` path) $ unFilterOption fo