cabal-gild 1.3.1.3 → 1.3.2.0
raw patch · 4 files changed
+138/−127 lines, 4 filesdep +filepatterndep ~directoryPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: filepattern
Dependency ranges changed: directory
API changes (from Hackage documentation)
- CabalGild.Unstable.Class.MonadWalk: listDirectoryRecursively :: FilePath -> IO [FilePath]
- CabalGild.Unstable.Class.MonadWalk: walk :: MonadWalk m => FilePath -> m [FilePath]
+ CabalGild.Unstable.Class.MonadWalk: walk :: MonadWalk m => FilePath -> [FilePattern] -> [FilePattern] -> m [FilePath]
Files
- cabal-gild.cabal +4/−3
- source/library/CabalGild/Unstable/Action/EvaluatePragmas.hs +17/−11
- source/library/CabalGild/Unstable/Class/MonadWalk.hs +5/−22
- source/test-suite/Main.hs +112/−91
cabal-gild.cabal view
@@ -11,7 +11,7 @@ maintainer: Taylor Fausak name: cabal-gild synopsis: Formats package descriptions.-version: 1.3.1.3+version: 1.3.2.0 source-repository head type: git@@ -58,9 +58,9 @@ Cabal-syntax ^>=3.10.1.0 || ^>=3.12.0.0, bytestring ^>=0.11.4.0 || ^>=0.12.0.2, containers ^>=0.6.7 || ^>=0.7,- directory ^>=1.3.8.1, exceptions ^>=0.10.7, filepath ^>=1.4.100.1 || ^>=1.5.2.0,+ filepattern ^>=0.1.3, parsec ^>=3.1.16.1, pretty ^>=1.1.3.6, text ^>=2.0.2 || ^>=2.1,@@ -145,9 +145,10 @@ build-depends: bytestring, containers,- directory,+ directory ^>=1.3.8.1, exceptions, filepath,+ filepattern, hspec ^>=2.11.8, temporary ^>=1.3, transformers,
source/library/CabalGild/Unstable/Action/EvaluatePragmas.hs view
@@ -13,6 +13,7 @@ import qualified Control.Monad.Catch as Exception import qualified Control.Monad.Trans.Class as Trans import qualified Control.Monad.Trans.Maybe as MaybeT+import qualified Data.Containers.ListUtils as List import qualified Data.Maybe as Maybe import qualified Data.Set as Set import qualified Distribution.Compat.Lens as Lens@@ -62,30 +63,35 @@ let (strs, args, opts, errs) = GetOpt.getOpt' GetOpt.Permute- [ GetOpt.Option [] ["exclude"] (GetOpt.ReqArg id "FILE") ""+ [ GetOpt.Option [] ["exclude"] (GetOpt.ReqArg id "PATTERN") "" ] ds mapM_ (Exception.throwM . UnknownOption.fromString) opts mapM_ (Exception.throwM . InvalidOption.fromString) errs let root = FilePath.takeDirectory p directories =- FilePath.dropTrailingPathSeparator- . normalize- . FilePath.combine root- <$> if null args then ["."] else args- files <- Trans.lift . fmap mconcat $ traverse MonadWalk.walk directories+ List.nubOrd+ . fmap+ ( FilePath.dropTrailingPathSeparator+ . normalize+ . FilePath.combine root+ )+ $ if null args then ["."] else args+ let exclusions = List.nubOrd $ fmap (normalize . FilePath.combine root) strs+ files <-+ Trans.lift $+ MonadWalk.walk+ "."+ (fmap (\d -> normalize $ FilePath.joinPath [d, "**"]) directories)+ exclusions let comments = concatMap (snd . FieldLine.annotation) fls position = maybe (fst $ Name.annotation n) (fst . FieldLine.annotation) $ Maybe.listToMaybe fls- -- Exclusion must be computed relative to the directory containing the cabal file (see #71)- excludedFiles = Set.fromList $ fmap (normalize . FilePath.combine root) strs fieldLines = zipWith ModuleName.toFieldLine ((,) position <$> comments : repeat []) . Maybe.mapMaybe (toModuleName directories)- . Maybe.mapMaybe (stripAnyExtension extensions)- . filter (`Set.notMember` excludedFiles)- $ fmap normalize files+ $ Maybe.mapMaybe (stripAnyExtension extensions . normalize) files -- This isn't great, but the comments have to go /somewhere/. name = if null fieldLines
source/library/CabalGild/Unstable/Class/MonadWalk.hs view
@@ -1,28 +1,11 @@ module CabalGild.Unstable.Class.MonadWalk where -import qualified System.Directory as Directory-import qualified System.FilePath as FilePath+import qualified System.FilePattern as FilePattern+import qualified System.FilePattern.Directory as FilePattern --- | A 'Monad' that can also walk the file system.+-- | A wrapper around 'FilePattern.getDirectoryFilesIgnore'. class (Monad m) => MonadWalk m where- -- | Lists all files in the given directory and its subdirectories- -- recursively.- walk :: FilePath -> m [FilePath]+ walk :: FilePath -> [FilePattern.FilePattern] -> [FilePattern.FilePattern] -> m [FilePath] --- | Uses 'listDirectoryRecursively'. instance MonadWalk IO where- walk = listDirectoryRecursively---- | Lists all files in the given directory and its subdirectories recursively.--- The order is not guaranteed and may change between different calls. It's--- also not specified if the results are breadth-first or depth-first.-listDirectoryRecursively :: FilePath -> IO [FilePath]-listDirectoryRecursively d = do- es <- Directory.listDirectory d- let f e = do- let p = FilePath.combine d e- b <- Directory.doesDirectoryExist p- if b- then listDirectoryRecursively p- else pure [p]- mconcat <$> traverse f es+ walk = FilePattern.getDirectoryFilesIgnore
source/test-suite/Main.hs view
@@ -28,6 +28,7 @@ import qualified System.Directory as Directory import qualified System.Exit as Exit import qualified System.FilePath as FilePath+import qualified System.FilePattern as FilePattern import qualified System.IO.Temp as Temp import qualified Test.Hspec as Hspec @@ -217,11 +218,11 @@ let (a, s, w) = runGild ["--stdin", "d/p.cabal"]- [(Input.Stdin, String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:")]- [("d", ["M.hs"])]+ [(Input.Stdin, String.toUtf8 "library\n -- cabal-gild: discover\n exposed-modules:")]+ [["d", "M.hs"]] a `Hspec.shouldSatisfy` Either.isRight w `Hspec.shouldBe` []- s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules: M\n")+ s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n -- cabal-gild: discover\n exposed-modules: M\n") Hspec.it "succeeds with empty input" $ do expectGilded@@ -1070,178 +1071,183 @@ Hspec.it "discovers an exposed module" $ do expectDiscover- [(".", ["M.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers an other module" $ do expectDiscover- [(".", ["M.hs"])]- "library\n -- cabal-gild: discover .\n other-modules:"- "library\n -- cabal-gild: discover .\n other-modules: M\n"+ [["M.hs"]]+ "library\n -- cabal-gild: discover\n other-modules:"+ "library\n -- cabal-gild: discover\n other-modules: M\n" Hspec.it "discovers a nested module" $ do expectDiscover- [(".", [FilePath.combine "N" "O.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: N.O\n"+ [["N", "O.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: N.O\n" Hspec.it "discovers multiple modules" $ do expectDiscover- [(".", ["M.hs", "N.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules:\n M\n N\n"+ [["M.hs"], ["N.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules:\n M\n N\n" Hspec.it "discovers no modules" $ do- expectDiscover- [(".", [])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules:\n"+ expectGilded+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules:\n" Hspec.it "discovers a .lhs file" $ do expectDiscover- [(".", ["M.lhs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.lhs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .gc file" $ do expectDiscover- [(".", ["M.gc"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.gc"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .chs file" $ do expectDiscover- [(".", ["M.chs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.chs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .hsc file" $ do expectDiscover- [(".", ["M.hsc"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.hsc"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .y file" $ do expectDiscover- [(".", ["M.y"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.y"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .ly file" $ do expectDiscover- [(".", ["M.ly"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.ly"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .x file" $ do expectDiscover- [(".", ["M.x"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.x"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .cpphs file" $ do expectDiscover- [(".", ["M.cpphs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.cpphs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .hsig file" $ do expectDiscover- [(".", ["M.hsig"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.hsig"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a .lhsig file" $ do expectDiscover- [(".", ["M.lhsig"])]- "library\n -- cabal-gild: discover .\n exposed-modules:"- "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ [["M.lhsig"]]+ "library\n -- cabal-gild: discover\n exposed-modules:"+ "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "discovers a signature" $ do expectDiscover- [(".", ["S.hsig"])]- "library\n -- cabal-gild: discover .\n signatures:"- "library\n -- cabal-gild: discover .\n signatures: S\n"+ [["S.hsig"]]+ "library\n -- cabal-gild: discover\n signatures:"+ "library\n -- cabal-gild: discover\n signatures: S\n" Hspec.it "ignores discover pragma separated by comment" $ do expectGilded- "library\n -- cabal-gild: discover .\n -- foo\n exposed-modules: M"- "library\n -- cabal-gild: discover .\n -- foo\n exposed-modules: M\n"+ "library\n -- cabal-gild: discover\n -- foo\n exposed-modules: M"+ "library\n -- cabal-gild: discover\n -- foo\n exposed-modules: M\n" Hspec.it "ignores misplaced discover pragma" $ do expectGilded- "-- cabal-gild: discover .\nname: p"- "-- cabal-gild: discover .\nname: p\n"+ "-- cabal-gild: discover\nname: p"+ "-- cabal-gild: discover\nname: p\n" Hspec.it "ignores unknown pragma" $ do expectGilded "-- cabal-gild: unknown" "-- cabal-gild: unknown\n" + Hspec.it "discovers from the currently directory explicitly" $ do+ expectDiscover+ [["M.hs"]]+ "library\n -- cabal-gild: discover .\n exposed-modules:"+ "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ Hspec.it "discovers from multiple directories" $ do expectDiscover- [("d", ["M.hs"]), ("e", ["N.hs"])]+ [["d", "M.hs"], ["e", "N.hs"]] "library\n -- cabal-gild: discover d e\n exposed-modules:" "library\n -- cabal-gild: discover d e\n exposed-modules:\n M\n N\n" Hspec.it "discovers from a quoted directory" $ do expectDiscover- [("d", ["M.hs"])]+ [["d", "M.hs"]] "library\n -- cabal-gild: discover \"d\"\n exposed-modules:" "library\n -- cabal-gild: discover \"d\"\n exposed-modules: M\n" Hspec.it "discovers from a directory with a space" $ do expectDiscover- [("s p", ["M.hs"])]+ [["s p", "M.hs"]] "library\n -- cabal-gild: discover \"s p\"\n exposed-modules:" "library\n -- cabal-gild: discover \"s p\"\n exposed-modules: M\n" Hspec.it "discovers from the current directory by default" $ do expectDiscover- [(".", ["M.hs"])]+ [["M.hs"]] "library\n -- cabal-gild: discover\n exposed-modules:" "library\n -- cabal-gild: discover\n exposed-modules: M\n" Hspec.it "allows excluding a path when discovering" $ do expectDiscover- [(".", ["M.hs", "N.hs"])]+ [["M.hs"], ["N.hs"]] "library\n -- cabal-gild: discover --exclude M.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude M.hs\n exposed-modules: N\n" Hspec.it "allows excluding a nested POSIX path" $ do expectDiscover- [(".", [FilePath.combine "A" "M.hs", FilePath.combine "B" "M.hs"])]+ [["A", "M.hs"], ["B", "M.hs"]] "library\n -- cabal-gild: discover --exclude B/M.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude B/M.hs\n exposed-modules: A.M\n" Hspec.it "allows excluding a nested Windows path" $ do expectDiscover- [(".", [FilePath.combine "A" "M.hs", FilePath.combine "B" "M.hs"])]+ [["A", "M.hs"], ["B", "M.hs"]] "library\n -- cabal-gild: discover --exclude B\\M.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude B\\M.hs\n exposed-modules: A.M\n" Hspec.it "allows excluding a relative POSIX path" $ do expectDiscover- [(".", ["M.hs", "N.hs"])]+ [["M.hs"], ["N.hs"]] "library\n -- cabal-gild: discover --exclude ./M.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude ./M.hs\n exposed-modules: N\n" Hspec.it "allows excluding a relative Windows path" $ do expectDiscover- [(".", ["M.hs", "N.hs"])]+ [["M.hs"], ["N.hs"]] "library\n -- cabal-gild: discover --exclude .\\M.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude .\\M.hs\n exposed-modules: N\n" Hspec.it "allows excluding multiple paths" $ do expectDiscover- [(".", ["M.hs", "N.hs", "O.hs"])]+ [["M.hs"], ["N.hs"], ["O.hs"]] "library\n -- cabal-gild: discover --exclude M.hs --exclude O.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude M.hs --exclude O.hs\n exposed-modules: N\n" Hspec.it "allows excluding paths that don't match anything" $ do expectDiscover- [(".", ["M.hs"])]+ [["M.hs"]] "library\n -- cabal-gild: discover --exclude N.hs\n exposed-modules:" "library\n -- cabal-gild: discover --exclude N.hs\n exposed-modules: M\n" @@ -1251,11 +1257,23 @@ runGild ["--input", FilePath.combine d "io.cabal"] [(Input.File $ FilePath.combine d "io.cabal", String.toUtf8 "library\n -- cabal-gild: discover src --exclude src/N.hs\n exposed-modules:")]- [(FilePath.combine d "src", ["M.hs", "N.hs"])]+ [[d, "src", "M.hs"], [d, "src", "N.hs"]] a `Hspec.shouldSatisfy` Either.isRight w `Hspec.shouldBe` [] s `Hspec.shouldBe` Map.singleton Output.Stdout (String.toUtf8 "library\n -- cabal-gild: discover src --exclude src/N.hs\n exposed-modules: M\n") + Hspec.it "allows excluding simple wildcards" $ do+ expectDiscover+ [["M.hs"], ["MSpec.hs"]]+ "library\n -- cabal-gild: discover --exclude *Spec.hs\n exposed-modules:"+ "library\n -- cabal-gild: discover --exclude *Spec.hs\n exposed-modules: M\n"++ Hspec.it "allows excluding complex wildcards" $ do+ expectDiscover+ [["A.hs"], ["A", "B.hs"], ["X", "C.hs"], ["A", "X", "D.hs"]]+ "library\n -- cabal-gild: discover --exclude **/X/**/*.hs\n exposed-modules:"+ "library\n -- cabal-gild: discover --exclude **/X/**/*.hs\n exposed-modules:\n A\n A.B\n"+ Hspec.it "fails when discovering with an unknown option" $ do let (a, s, w) = runGild@@ -1272,27 +1290,26 @@ [] [(Input.Stdin, String.toUtf8 "-- cabal-gild: discover --exclude\nsignatures:")] []- a `shouldBeFailure` InvalidOption.InvalidOption "option `--exclude' requires an argument FILE"+ a `shouldBeFailure` InvalidOption.InvalidOption "option `--exclude' requires an argument PATTERN" w `Hspec.shouldBe` [] s `Hspec.shouldBe` Map.empty Hspec.it "retains comments when discovering" $ do expectDiscover- [(".", ["M.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:\n -- c\n N"- "library\n -- cabal-gild: discover .\n exposed-modules:\n -- c\n M\n"+ [["M.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:\n -- c\n N"+ "library\n -- cabal-gild: discover\n exposed-modules:\n -- c\n M\n" Hspec.it "concatenates comments when discovering" $ do expectDiscover- [(".", ["M.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:\n -- c\n N\n -- d\n O"- "library\n -- cabal-gild: discover .\n exposed-modules:\n -- c\n -- d\n M\n"+ [["M.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:\n -- c\n N\n -- d\n O"+ "library\n -- cabal-gild: discover\n exposed-modules:\n -- c\n -- d\n M\n" Hspec.it "retains comments even when no modules are discovered" $ do- expectDiscover- [(".", [])]- "library\n -- cabal-gild: discover .\n exposed-modules:\n -- c\n N"- "library\n -- c\n -- cabal-gild: discover .\n exposed-modules:\n"+ expectGilded+ "library\n -- cabal-gild: discover\n exposed-modules:\n -- c\n N"+ "library\n -- c\n -- cabal-gild: discover\n exposed-modules:\n" Hspec.it "parses an empty brace section" $ do expectGilded@@ -1371,9 +1388,9 @@ Hspec.it "keeps output on multiple lines for pragmas" $ do expectDiscover- [(".", ["M.hs"])]- "library\n -- cabal-gild: discover .\n exposed-modules:\n ..."- "library\n -- cabal-gild: discover .\n exposed-modules:\n M\n"+ [["M.hs"]]+ "library\n -- cabal-gild: discover\n exposed-modules:\n ..."+ "library\n -- cabal-gild: discover\n exposed-modules:\n M\n" Hspec.it "does not put a blank line after an empty field" $ do expectGilded@@ -1428,7 +1445,7 @@ expectStable :: (Stack.HasCallStack) =>- [(FilePath, [FilePath])] ->+ [[String]] -> ByteString.ByteString -> Hspec.Expectation expectStable files input = do@@ -1442,7 +1459,7 @@ expectDiscover :: (Stack.HasCallStack) =>- [(FilePath, [FilePath])] ->+ [[String]] -> String -> String -> Hspec.Expectation@@ -1459,13 +1476,13 @@ runGild :: [String] -> [(Input.Input, ByteString.ByteString)] ->- [(FilePath, [FilePath])] ->+ [[String]] -> (Either E (), S, W) runGild arguments inputs files = runTest (Gild.mainWith arguments) ( Map.fromList inputs,- Map.mapWithKey (\d fs -> FilePath.combine d <$> fs) $ Map.fromList files+ Map.singleton "." (fmap FilePath.joinPath files) ) Map.empty @@ -1501,11 +1518,15 @@ throwM = TestT . ExceptT.throwE . Exception.toException instance (Monad m) => MonadWalk.MonadWalk (TestT m) where- walk p = do- m <- TestT . Trans.lift . RWST.asks $ Map.lookup p . snd- case m of- Nothing -> Exception.throwM . userError $ "walk " <> show p- Just x -> pure x+ walk d i x = do+ result <- TestT . Trans.lift . RWST.asks $ Map.lookup d . snd+ case result of+ Nothing -> Exception.throwM . userError $ "walk " <> show d+ Just fs ->+ pure $+ filter+ (\f -> any (FilePattern.?== f) i && not (any (FilePattern.?== f) x))+ fs instance (Monad m) => MonadWrite.MonadWrite (TestT m) where write k = TestT . Trans.lift . RWST.modify . Map.insert k