cabal-gild 1.0.0.1 → 1.0.1.0
raw patch · 4 files changed
+75/−64 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- CabalGild.Action.EvaluatePragmas: relevantFieldNames :: Set FieldName
+ CabalGild.Action.EvaluatePragmas: extensions :: Map FieldName (Set String)
+ CabalGild.Action.EvaluatePragmas: stripAnyExtension :: Set String -> FilePath -> Maybe String
Files
- README.md +15/−10
- cabal-gild.cabal +1/−1
- source/library/CabalGild/Action/EvaluatePragmas.hs +21/−13
- source/test-suite/Main.hs +38/−40
README.md view
@@ -5,8 +5,12 @@ [](https://www.stackage.org/package/cabal-gild) Gild is an opinionated command line utility that formats Haskell package-descriptions, which are also known as `*.cabal` files.+descriptions, which are also known as `*.cabal` files. Gild can also be used to+automatically discover `exposed-modules`; see [the pragmas section][] for more+about that. +[the pragmas section]: #pragmas+ To run Gild in CI, consider using [cabal-gild-setup-action][]. [cabal-gild-setup-action]: https://github.com/tfausak/cabal-gild-setup-action@@ -52,11 +56,11 @@ ghc-options: -Wmissing-role-annotations ``` -See the [installation][] section for how to get Gild and the [usage][] section+See [the installation section][] for how to get Gild and [the usage section][] for how to use it. -[installation]: #installation-[usage]: #usage+[the installation section]: #installation+[the usage section]: #usage ## Goals @@ -76,17 +80,18 @@ package descriptions. This means `cabal.project` files can be formatted as well. -- The focus is on formatting only. There should be no effort made to validate- input or provide any checks or lints.+- The focus should be mostly on formatting. There should be no effort made to+ validate input or provide any checks or lints. However some quality of life+ features, like automatic module discovery, are desireable. - The command line utility should be fast enough to run on every save. It should not need network access. ## Installation -Go to the [latest release][] page and download the binary for your platform.+Go to [the latest release page][] and download the binary for your platform. -[latest release]: https://github.com/tfausak/cabal-gild/releases/latest+[the latest release page]: https://github.com/tfausak/cabal-gild/releases/latest ### From Source @@ -157,8 +162,8 @@ before a field. - `-- cabal-gild: discover DIRECTORY`: This pragma will discover any Haskell- files (`*.hs`) in the given directory and use those to populate the list of- modules. For example, given this input:+ files (`*.hs` or `*.lhs`) in the given directory and use those to populate+ the list of modules. For example, given this input: ``` cabal library
cabal-gild.cabal view
@@ -11,7 +11,7 @@ maintainer: Taylor Fausak name: cabal-gild synopsis: Formats package descriptions.-version: 1.0.0.1+version: 1.0.1.0 source-repository head type: git
source/library/CabalGild/Action/EvaluatePragmas.hs view
@@ -6,9 +6,9 @@ import qualified CabalGild.Extra.String as String import qualified CabalGild.Type.Comment as Comment import qualified CabalGild.Type.Pragma as Pragma-import qualified Control.Monad as Monad import qualified Control.Monad.Trans.Class as Trans import qualified Control.Monad.Trans.Maybe as MaybeT+import qualified Data.Map as Map import qualified Data.Maybe as Maybe import qualified Data.Set as Set import qualified Distribution.Fields as Fields@@ -46,7 +46,7 @@ m (Fields.Field [Comment.Comment a]) field p f = case f of Fields.Field n _ -> fmap (Maybe.fromMaybe f) . MaybeT.runMaybeT $ do- Monad.guard $ Set.member (Name.value n) relevantFieldNames+ es <- hoistMaybe . Map.lookup (Name.value n) $ extensions c <- hoistMaybe . Utils.safeLast $ Name.annotation n x <- hoistMaybe . Parsec.simpleParsecBS $ Comment.value c y <- case x of@@ -57,19 +57,27 @@ . Fields.Field n . fmap (ModuleName.toFieldLine []) . Maybe.mapMaybe (ModuleName.fromFilePath . FilePath.makeRelative d)- $ Maybe.mapMaybe (FilePath.stripExtension "hs") fs+ $ Maybe.mapMaybe (stripAnyExtension es) fs Fields.Section n sas fs -> Fields.Section n sas <$> fields p fs --- | These are the names of the fields that can have this action applied to--- them.-relevantFieldNames :: Set.Set Fields.FieldName-relevantFieldNames =- Set.fromList $- fmap- String.toUtf8- [ "exposed-modules",- "other-modules"- ]+-- | Attempts to strip any of the given extensions from the file path. If any+-- of them succeed, the result is returned. Otherwise 'Nothing' is returned.+stripAnyExtension :: Set.Set String -> FilePath -> Maybe String+stripAnyExtension es p =+ Maybe.listToMaybe+ . Maybe.mapMaybe (`FilePath.stripExtension` p)+ $ Set.toList es++-- | A map from field names to the set of extensions that should be discovered+-- for that field.+extensions :: Map.Map Fields.FieldName (Set.Set String)+extensions =+ let (=:) :: String -> [String] -> (Fields.FieldName, Set.Set String)+ k =: v = (String.toUtf8 k, Set.fromList v)+ in Map.fromList+ [ "exposed-modules" =: ["hs", "lhs"],+ "other-modules" =: ["hs", "lhs"]+ ] -- | This was added in @transformers-0.6.0.0@. See -- <https://hub.darcs.net/ross/transformers/issue/49>.
source/test-suite/Main.hs view
@@ -751,53 +751,35 @@ "custom-setup\n setup-depends:\n a,\n b\n" Hspec.it "discovers an exposed module" $ do- let (a, s, w) =- runTest- (Gild.mainWith "" [])- ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:"),- Map.singleton (FilePath.combine "." ".") ["M.hs"]- )- Map.empty- a `Hspec.shouldBe` Right ()- w `Hspec.shouldBe` []- s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules: M\n")+ expectDiscover+ ["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- let (a, s, w) =- runTest- (Gild.mainWith "" [])- ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n other-modules:"),- Map.singleton (FilePath.combine "." ".") ["M.hs"]- )- Map.empty- a `Hspec.shouldBe` Right ()- w `Hspec.shouldBe` []- s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n other-modules: M\n")+ expectDiscover+ ["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- let (a, s, w) =- runTest- (Gild.mainWith "" [])- ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:"),- Map.singleton (FilePath.combine "." ".") [FilePath.combine "N" "O.hs"]- )- Map.empty- a `Hspec.shouldBe` Right ()- w `Hspec.shouldBe` []- s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules: N.O\n")+ 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" Hspec.it "discovers multiple modules" $ do- let (a, s, w) =- runTest- (Gild.mainWith "" [])- ( Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:"),- Map.singleton (FilePath.combine "." ".") ["M.hs", "N.hs"]- )- Map.empty- a `Hspec.shouldBe` Right ()- w `Hspec.shouldBe` []- s `Hspec.shouldBe` Map.singleton Nothing (String.toUtf8 "library\n -- cabal-gild: discover .\n exposed-modules:\n M\n N\n")+ 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" + Hspec.it "discovers a literate haskell module" $ do+ expectDiscover+ ["M.lhs"]+ "library\n -- cabal-gild: discover .\n exposed-modules:"+ "library\n -- cabal-gild: discover .\n exposed-modules: M\n"+ Hspec.it "ignores discover pragma separated by comment" $ do expectGilded "library\n -- cabal-gild: discover .\n -- foo\n exposed-modules: M"@@ -842,6 +824,22 @@ [(Nothing, x)] -> pure x _ -> fail $ "impossible: " <> show s output `Hspec.shouldBe` input++expectDiscover :: [FilePath] -> String -> String -> Hspec.Expectation+expectDiscover files input expected = do+ let (a, s, w) =+ runTest+ (Gild.mainWith "" [])+ ( Map.singleton Nothing (String.toUtf8 input),+ Map.singleton (FilePath.combine "." ".") files+ )+ Map.empty+ a `Hspec.shouldBe` Right ()+ w `Hspec.shouldBe` []+ actual <- case Map.toList s of+ [(Nothing, x)] -> pure x+ _ -> fail $ "impossible: " <> show s+ actual `Hspec.shouldBe` String.toUtf8 expected newtype Problem = Problem { unProblem :: Exception.SomeException