vcs-ignore 0.0.1.0 → 0.0.2.0
raw patch · 13 files changed
+124/−124 lines, 13 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- LICENSE +1/−1
- README.md +41/−2
- app/Main.hs +1/−1
- app/Main/Options.hs +15/−3
- app/Main/Vendor.hs +1/−1
- src/Data/VCS/Ignore.hs +1/−1
- src/Data/VCS/Ignore/Core.hs +8/−15
- src/Data/VCS/Ignore/FileSystem.hs +11/−21
- src/Data/VCS/Ignore/Repo.hs +10/−19
- src/Data/VCS/Ignore/Repo/Git.hs +24/−49
- src/Data/VCS/Ignore/Types.hs +5/−9
- vcs-ignore.cabal +2/−2
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Changelog for vcs-ignore +## v0.0.2.0 (2021-12-29)+- minor fixes and improvements+- Bump _LTS Haskell_ to `18.20`+ ## v0.0.1.0 (2021-05-10) - initial release
LICENSE view
@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2020-2021, Vaclav Svejcar+Copyright (c) 2020-2022, Vaclav Svejcar All rights reserved. Redistribution and use in source and binary forms, with or without
README.md view
@@ -1,18 +1,25 @@++[](https://hackage.haskell.org/package/vcs-ignore)+[](https://www.stackage.org/package/vcs-ignore) # vcs-ignore `vcs-ignore` is small Haskell library used to find, check and process files ignored by selected _VCS_. ## 1. Table of Contents+<!-- TOC --> - [1. Table of Contents](#1-table-of-contents)-- [2. Example of Use](#2-example-of-use)+- [2. Use as Library](#2-use-as-library) - [2.1. Listing all files/directories ignored by VCS](#21-listing-all-filesdirectories-ignored-by-vcs) - [2.2. Walking files/directories ignored by VCS](#22-walking-filesdirectories-ignored-by-vcs) - [2.3. Checking if path is ignored by VCS](#23-checking-if-path-is-ignored-by-vcs)+- [3. Use as Executable](#3-use-as-executable)+ - [3.1. Checking if path is ignored by VCS](#31-checking-if-path-is-ignored-by-vcs) +<!-- /TOC --> -## 2. Example of Use+## 2. Use as Library Because this library is really simple to use, following example should be enough to understand how to use it for your project. ### 2.1. Listing all files/directories ignored by VCS@@ -63,3 +70,35 @@ repo <- scanRepo @Git "path/to/repo" isIgnored repo "/some/path/.DS_Store" ```++## 3. Use as Executable+While `vcs-ignore` is mainly intended to be used as a library, it also comes with small executable called `ignore` that can be used standalone to verify whether given path is ignored or not.++```+$ ignore --help+vcs-ignore, v0.0.2.0 :: https://github.com/vaclavsvejcar/vcs-ignore++Usage: ignore (-p|--path PATH) [--debug] [-v|--version] [--numeric-version]+ library for handling files ignored by VCS systems++Available options:+ -p,--path PATH path to check+ --debug produce more verbose output+ -v,--version show version info+ --numeric-version show only version number+ -h,--help Show this help text+```++### 3.1. Checking if path is ignored by VCS+To verify if path is ignored by _VCS_, just call the `ignore` executable with `-p` parameter inside the _VCS_ repository like this:++```+$ ignore -p .stack-work/some-file+Found repository at: /path/to/repo+Path '.stack-work/some-file' IS NOT ignored++$ echo $?+1+```++As you can see, `ignore` executable prints result in human readable form as well as it sets the exit code to `1` if the file is __not__ ignored.
app/Main.hs view
@@ -5,7 +5,7 @@ {-| Module : Main Description : Simple application using the /vcs-ignore/ library-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental
app/Main/Options.hs view
@@ -3,7 +3,7 @@ {-| Module : Main.Options Description : Options definitions for "optparse-applicative"-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -19,7 +19,8 @@ ) where -import Main.Vendor ( productDesc+import Main.Vendor ( buildVersion+ , productDesc , productInfo ) import Options.Applicative@@ -36,7 +37,7 @@ optionsParser :: ParserInfo Options-optionsParser = info (options <**> helper)+optionsParser = info (options <**> versionP <**> helper) (fullDesc <> progDesc productDesc <> header productInfo) where options =@@ -48,3 +49,14 @@ ) ) <*> switch (long "debug" <> help "produce more verbose output")+++versionP :: Parser (a -> a)+versionP = versionInfoP <*> versionNumP+ where+ versionInfoP = infoOption+ productInfo+ (long "version" <> short 'v' <> help "show version info")+ versionNumP = infoOption+ buildVersion+ (long "numeric-version" <> help "show only version number")
app/Main/Vendor.hs view
@@ -3,7 +3,7 @@ {-| Module : Main.Vendor Description : Details about the application.-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental
src/Data/VCS/Ignore.hs view
@@ -1,7 +1,7 @@ {-| Module : Data.VCS.Ignore Description : Reexported modules for convenience-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental
src/Data/VCS/Ignore/Core.hs view
@@ -4,7 +4,7 @@ {-| Module : Data.VCS.Ignore.Core Description : Core operations over the repository-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -40,10 +40,8 @@ -- If given path doesn't contain valid repository, it recursively tries in every -- parent directory until the root directory (e.g. @C:@ or @/@) is reached. findRepo :: (MonadIO m, Repo r)- => FilePath- -- ^ path where to start scanning- -> m (Maybe r)- -- ^ scanned 'Repo' (if found)+ => FilePath -- ^ path where to start scanning+ -> m (Maybe r) -- ^ scanned 'Repo' (if found) findRepo = liftIO . go where go dir = do@@ -58,22 +56,17 @@ -- | Resursively lists all non-ignored paths withing the given repository -- (both files and directories). listRepo :: (MonadIO m, Repo r)- => r- -- ^ repository to list- -> m [FilePath]- -- ^ list of non-ignored paths within the repository+ => r -- ^ repository to list+ -> m [FilePath] -- ^ list of non-ignored paths within the repository listRepo repo = walkRepo repo pure -- | Similar to 'listRepo', but allows to perform any action on every -- non-ignored path within the repository. walkRepo :: (MonadIO m, Repo r)- => r- -- ^ repository to walk- -> (FilePath -> m a)- -- ^ action to perform on every non-excluded filepath- -> m [a]- -- ^ list of paths transformed by the action function+ => r -- ^ repository to walk+ -> (FilePath -> m a) -- ^ action to do on every non-excluded filepath+ -> m [a] -- ^ list of transformed paths walkRepo repo fn = do let search path | L.null path = pure Nothing | otherwise = doSearch path
src/Data/VCS/Ignore/FileSystem.hs view
@@ -3,7 +3,7 @@ {-| Module : Data.VCS.Ignore.FileSystem Description : Helper functions for working with file system-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -40,12 +40,9 @@ -- | Recursively finds paths on given path whose filename matches the predicate. findPaths :: MonadIO m- => FilePath- -- ^ path to traverse- -> (FilePath -> m Bool)- -- ^ predicate to match filename (performing possible I/O actions)- -> m [FilePath]- -- ^ list of found paths+ => FilePath -- ^ path to traverse+ -> (FilePath -> m Bool) -- ^ predicate to match filename+ -> m [FilePath] -- ^ list of found paths findPaths entryPath predicate = catMaybes <$> walkPaths entryPath process where process path = (\p -> if p then Just path else Nothing) <$> predicate path@@ -54,10 +51,8 @@ -- | Recursively finds all paths on given path. If file reference is passed -- instead of directory, such path is returned. listPaths :: MonadIO m- => FilePath- -- ^ path to traverse- -> m [FilePath]- -- ^ list of found paths+ => FilePath -- ^ path to traverse+ -> m [FilePath] -- ^ list of found paths listPaths entryPath = walkPaths entryPath pure @@ -70,12 +65,9 @@ -- recursively processed and returned. -- * If the given __path doesn't exist__, empy list will be returned. walkPaths :: MonadIO m- => FilePath- -- ^ path to traverse- -> (FilePath -> m a)- -- ^ function to process path (performing possible I/O actions)- -> m [a]- -- ^ result of traversed & processed paths+ => FilePath -- ^ path to traverse+ -> (FilePath -> m a) -- ^ function to process path+ -> m [a] -- ^ result of traversed & processed paths walkPaths entryPath fn = do isDir <- liftIO $ doesDirectoryExist entryPath isFile <- liftIO $ doesFileExist entryPath@@ -101,9 +93,7 @@ -- -- >>> toPosixPath "foo/bar/x.txt" -- "foo/bar/x.txt"-toPosixPath :: FilePath- -- ^ input filepath to convert- -> FilePath- -- ^ output filepath+toPosixPath :: FilePath -- ^ input filepath to convert+ -> FilePath -- ^ output filepath toPosixPath = replace '\\' '/' where replace a b = fmap $ fromMaybe b . mfilter (/= a) . Just
src/Data/VCS/Ignore/Repo.hs view
@@ -3,7 +3,7 @@ {-| Module : Data.VCS.Ignore.Repo Description : Type class representing the VCS repository-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -37,35 +37,26 @@ class Repo r where -- | Returns name of the repository (e.g. @GIT@).- repoName :: r- -- ^ /VCS/ repository instance- -> Text- -- ^ name of the repository+ repoName :: r -- ^ /VCS/ repository instance+ -> Text -- ^ name of the repository -- | Returns absolute path to the root of the /VCS/ repository.- repoRoot :: r- -- ^ /VCS/ repository instance- -> FilePath- -- ^ absolute path to the repository+ repoRoot :: r -- ^ /VCS/ repository instance+ -> FilePath -- ^ absolute path to the repository -- | Scans repository at given path. If the given path doesn't contain valid -- repository, 'RepoError' may be thrown. scanRepo :: (MonadIO m, MonadThrow m)- => FilePath- -- ^ path to the /VCS/ repository root- -> m r- -- ^ scanned repository (or failure)+ => FilePath -- ^ path to the /VCS/ repository root+ -> m r -- ^ scanned repository (or failure) -- | Checks whether the given path is ignored. The input path is expected to -- be relative to the repository root, it might or might not point to existing -- file or directory. isIgnored :: MonadIO m- => r- -- ^ /VCS/ repository instance- -> FilePath- -- ^ path to check, relative to the repository root- -> m Bool- -- ^ whether the path is ignored or not+ => r -- ^ /VCS/ repository instance+ -> FilePath -- ^ path to check, relative to the repository root+ -> m Bool -- ^ whether the path is ignored or not -- | Represents error related to operations over the /VCS/ repository.
src/Data/VCS/Ignore/Repo/Git.hs view
@@ -6,7 +6,7 @@ {-| Module : Data.VCS.Ignore.Repo.Git Description : Implementation of 'Repo' for /GIT/-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -55,7 +55,6 @@ , toPosixPath ) import Data.VCS.Ignore.Repo ( Repo(..)- , Repo(..) , RepoError(..) ) import System.Directory ( XdgDirectory(XdgConfig)@@ -72,10 +71,8 @@ -- | Data type representing scanned instance of /GIT/ repository. data Git = Git- { gitRepoRoot :: FilePath- -- ^ absolute path to the repository root- , gitPatterns :: [(FilePath, [Pattern])]- -- ^ patterns ignored at given repository paths+ { gitRepoRoot :: FilePath -- ^ absolute path to the repository+ , gitPatterns :: [(FilePath, [Pattern])] -- ^ ignored patterns } deriving (Eq, Show) @@ -87,12 +84,9 @@ -- | Represents single pattern to be used as a rule for ignoring paths. data Pattern = Pattern- { pPatterns :: [G.Pattern]- -- ^ underlying implementation- , pRaw :: Text- -- ^ raw textual representation of the pattern- , pIsNegated :: Bool- -- ^ whether the pattern is the negation (starts with @!@)+ { pPatterns :: [G.Pattern] -- ^ underlying implementation+ , pRaw :: Text -- ^ raw textual representation of the pattern+ , pIsNegated :: Bool -- ^ if the pattern is negation (starts with @!@) } deriving (Eq, Show) @@ -103,10 +97,8 @@ ------------------------------ PUBLIC FUNCTIONS ------------------------------ -- | Compiles pattern.-compilePattern :: Text- -- ^ raw pattern as text- -> Pattern- -- ^ compiled pattern+compilePattern :: Text -- ^ raw pattern as text+ -> Pattern -- ^ compiled pattern compilePattern raw = let woPrefix = fromMaybe raw $ T.stripPrefix "!" raw patterns = r2 . r1 $ woPrefix@@ -123,12 +115,9 @@ -- | Tests whether given path matches against the pattern.-matchesPattern :: Pattern- -- ^ pattern to match against- -> FilePath- -- ^ path to check- -> Bool- -- ^ check result+matchesPattern :: Pattern -- ^ pattern to match against+ -> FilePath -- ^ path to check+ -> Bool -- ^ check result matchesPattern ptn path = any (`G.match` path) (pPatterns ptn) @@ -138,10 +127,8 @@ -- -- >>> parsePatterns "*.xml\n.DS_Store" -- [Pattern {pPatterns = [compile "*.xml",compile "*.xml/*"], pRaw = "*.xml", pIsNegated = False},Pattern {pPatterns = [compile "**/.DS_Store",compile "**/.DS_Store/*"], pRaw = ".DS_Store", pIsNegated = False}]-parsePatterns :: Text- -- ^ text to parse- -> [Pattern]- -- ^ parsed patterns+parsePatterns :: Text -- ^ text to parse+ -> [Pattern] -- ^ parsed patterns parsePatterns = fmap compilePattern . filter (not . excluded) . T.lines where excluded = \line -> or $ fmap ($ T.stripStart line) [comment, T.null]@@ -152,10 +139,8 @@ -- any reason, empty list is returned. See 'parsePatterns' for more details -- about parsing. loadPatterns :: MonadIO m- => FilePath- -- ^ path to text file to parse- -> m [Pattern]- -- ^ parsed /Glob/ patterns+ => FilePath -- ^ path to text file to parse+ -> m [Pattern] -- ^ parsed /Glob/ patterns loadPatterns path = parsePatterns <$> liftIO content where content = catch (T.readFile path) (\(_ :: SomeException) -> pure T.empty)@@ -163,10 +148,8 @@ -- | Recursively finds all @.gitignore@ files within the given directory path. findGitIgnores :: MonadIO m- => FilePath- -- ^ path to the directory to search in- -> m [FilePath]- -- ^ paths of found @.gitignore@ files+ => FilePath -- ^ path to the directory to search in+ -> m [FilePath] -- ^ paths of found @.gitignore@ files findGitIgnores repoDir = findPaths repoDir isGitIgnore where isGitIgnore path = pure $ ".gitignore" `L.isSuffixOf` path @@ -188,17 +171,14 @@ -- | Loads /GIT/ repository specific ignore patterns, present in -- @REPO_ROOT\/info\/exclude@ file. repoPatterns :: MonadIO m- => FilePath- -- ^ path to the /GIT/ repository root- -> m [Pattern]- -- ^ parsed /Glob/ patterns+ => FilePath -- ^ path to the /GIT/ repository root+ -> m [Pattern] -- ^ parsed /Glob/ patterns repoPatterns repoDir = loadPatterns $ repoDir </> "info" </> "exclude" -- | Loads global /GIT/ ignore patterns, present in -- @XDG_CONFIG_GOME\/git\/ignore@ file. globalPatterns :: MonadIO m => m [Pattern]- -- ^ parsed /Glob/ patterns globalPatterns = (liftIO . getXdgDirectory XdgConfig $ ("git" </> "ignore")) >>= loadPatterns @@ -240,12 +220,9 @@ -- | Internal version of 'isIgnored' function. isIgnored' :: MonadIO m- => Git- -- ^ scanned /GIT/ repository- -> FilePath- -- ^ path to check if ignored- -> m Bool- -- @True@ if given path is ignored+ => Git -- ^ scanned /GIT/ repository+ -> FilePath -- ^ path to check if ignored+ -> m Bool -- @True@ if given path is ignored isIgnored' git@(Git _ patterns) path = do np <- toPosixPath <$> normalize (repoRoot git) path let ignored = any (check2 np False) (filtered np)@@ -264,10 +241,8 @@ -- | Checks whether given directory path is valid /GIT/ repository. isGitRepo :: MonadIO m- => FilePath- -- ^ path to the directory to check- -> m Bool- -- ^ @True@ if the given directory is valid /GIT/ repository+ => FilePath -- ^ path to the directory to check+ -> m Bool -- ^ @True@ if the given directory is valid repository isGitRepo path = liftIO . doesDirectoryExist $ path </> ".git"
src/Data/VCS/Ignore/Types.hs view
@@ -4,7 +4,7 @@ {-| Module : Data.VCS.Ignore.Types Description : Shared data types-Copyright : (c) 2020-2021 Vaclav Svejcar+Copyright : (c) 2020-2022 Vaclav Svejcar License : BSD-3-Clause Maintainer : vaclav.svejcar@gmail.com Stability : experimental@@ -42,10 +42,8 @@ -- | Unwraps given exception from 'VCSIgnoreError'. fromVCSIgnoreError :: Exception e- => SomeException- -- ^ exception to unwrap- -> Maybe e- -- ^ unwrapped exception+ => SomeException -- ^ exception to unwrap+ -> Maybe e -- ^ unwrapped exception fromVCSIgnoreError e = do VCSIgnoreError e' <- fromException e cast e'@@ -53,8 +51,6 @@ -- | Wraps given exception from 'VCSIgnoreError'. toVCSIgnoreError :: Exception e- => e- -- ^ exception to wrap- -> SomeException- -- ^ wrapped exception+ => e -- ^ exception to wrap+ -> SomeException -- ^ wrapped exception toVCSIgnoreError = toException . VCSIgnoreError
vcs-ignore.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: vcs-ignore-version: 0.0.1.0+version: 0.0.2.0 synopsis: Library for handling files ignored by VCS systems. description: vcs-ignore is small Haskell library used to find, check and process files ignored by selected VCS. category: Development@@ -13,7 +13,7 @@ bug-reports: https://github.com/vaclavsvejcar/vcs-ignore/issues author: Vaclav Svejcar maintainer: vaclav.svejcar@gmail.com-copyright: Copyright (c) 2020-2021 Vaclav Svejcar+copyright: Copyright (c) 2020-2022 Vaclav Svejcar license: BSD-3-Clause license-file: LICENSE build-type: Simple