hpack-dhall 0.3.0 → 0.4.0
raw patch · 42 files changed
+1111/−111 lines, 42 filesdep +Cabaldep +Diffdep +aeson-prettydep −hspecdep −interpolatedep −mockerydep ~basedep ~dhalldep ~dhall-jsonnew-component:exe:dhall-hpack-cabalnew-component:exe:dhall-hpack-dhallnew-component:exe:dhall-hpack-jsonnew-component:exe:dhall-hpack-yamlnew-uploader
Dependencies added: Cabal, Diff, aeson-pretty, bytestring, filepath, microlens, optparse-applicative, prettyprinter, tasty, tasty-golden, utf8-string, yaml
Dependencies removed: hspec, interpolate, mockery
Dependency ranges changed: base, dhall, dhall-json, hpack, megaparsec
Files
- LICENSE +27/−0
- README.md +149/−0
- changelog.md +5/−0
- driver/Main.hs +0/−6
- exe/dhall-hpack-cabal/CabalMain.hs +69/−0
- exe/dhall-hpack-dhall/DhallMain.hs +44/−0
- exe/dhall-hpack-json/JsonMain.hs +44/−0
- exe/dhall-hpack-yaml/YamlMain.hs +44/−0
- exe/options/Options.hs +57/−0
- hpack-dhall.cabal +202/−32
- library/Hpack/Dhall.hs +132/−0
- package.dhall +131/−0
- src/Hpack/Dhall.hs +0/−35
- test/Hpack/DhallSpec.hs +0/−37
- test/Spec.hs +0/−1
- test/golden/Golden.hs +95/−0
- test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal +11/−0
- test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal.golden +11/−0
- test/golden/hpack-dhall-cabal/empty-inferred/package.dhall +1/−0
- test/golden/hpack-dhall-cabal/empty-inferred/package.dhall.golden +1/−0
- test/golden/hpack-dhall-cabal/empty-inferred/package.json +1/−0
- test/golden/hpack-dhall-cabal/empty-inferred/package.yaml +1/−0
- test/golden/hpack-dhall-cabal/empty-package.cabal +11/−0
- test/golden/hpack-dhall-cabal/empty-package.cabal.golden +11/−0
- test/golden/hpack-dhall-cabal/empty-package.dhall +1/−0
- test/golden/hpack-dhall-cabal/empty-package.dhall.golden +1/−0
- test/golden/hpack-dhall-cabal/empty-package.json +3/−0
- test/golden/hpack-dhall-cabal/empty-package.yaml +1/−0
- test/golden/hpack-dhall-cabal/import-local/import-local.cabal +11/−0
- test/golden/hpack-dhall-cabal/import-local/import-local.cabal.golden +11/−0
- test/golden/hpack-dhall-cabal/import-local/name.dhl +1/−0
- test/golden/hpack-dhall-cabal/import-local/package.dhall +1/−0
- test/golden/hpack-dhall-cabal/import-local/package.dhall.golden +1/−0
- test/golden/hpack-dhall-cabal/import-local/package.json +3/−0
- test/golden/hpack-dhall-cabal/import-local/package.yaml +1/−0
- test/golden/hpack-dhall-cabal/import-relative.dhl +1/−0
- test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal +11/−0
- test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal.golden +11/−0
- test/golden/hpack-dhall-cabal/import-relative/package.dhall +1/−0
- test/golden/hpack-dhall-cabal/import-relative/package.dhall.golden +1/−0
- test/golden/hpack-dhall-cabal/import-relative/package.json +3/−0
- test/golden/hpack-dhall-cabal/import-relative/package.yaml +1/−0
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2018, Phil de Joux+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.++3. Neither the name of the author nor the names of its contributors may be+used to endorse or promote products derived from this software without+specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,149 @@+# hpack-dhall++[](https://travis-ci.org/BlockScope/hpack-dhall)+[](http://hackage.haskell.org/package/hpack-dhall)+[](https://hackage.haskell.org/package/hpack-dhall)++**H**askell **pack**age descriptions in [**Dhall**](https://github.com/dhall-lang/dhall-lang).++This package named `hpack-dhall` as described in+[`package.dhall`](https://github.com/sol/hpack-dhall/blob/master/package.dhall).++```+{ name =+ "hpack-dhall"+...+, library =+ { exposed-modules = "Hpack.Dhall" }+, executables =+ { dhall-hpack-cabal = ...+ , dhall-hpack-json = ...+ , dhall-hpack-yaml = ...+ , dhall-hpack-dhall = ...+ }+}+```++This `.cabal` creating executable can be run over its own package description;++```+> stack install --stack-yaml=stack-8.4.4.yaml+...+Copied executables to /.../hpack-dhall/__bin:+- dhall-hpack-cabal+- dhall-hpack-dhall+- dhall-hpack-json+- dhall-hpack-yaml++> __bin/dhall-hpack-cabal package.dhall+hpack-dhall.cabal is up-to-date++> __bin/dhall-hpack-cabal --force package.dhall+generated hpack-dhall.cabal+```++Using one of the golden tests for example, there are executables to show the+dhall with the imports made as well as json and yaml equivalents;+```+> __bin/dhall-hpack-dhall test/golden/hpack-dhall-cabal/empty-package.dhall+{ name = "empty-package" }++> __bin/dhall-hpack-json test/golden/hpack-dhall-cabal/empty-package.dhall+{+ "name": "empty-package"+}++> __bin/dhall-hpack-yaml test/golden/hpack-dhall-cabal/empty-package.dhall+name: empty-package+```++By going from [hpack package+fields](https://github.com/sol/hpack#top-level-fields) to [cabal package+properties](https://www.haskell.org/cabal/users-guide/developing-packages.html#package-properties),+we are not required to state what can be inferred or defaulted, easing the+burden of completing a package description by hand. For example+`other-modules` can be inferred by taking the set difference between modules on+disk and the set of `exposed-modules`.++By using an hpack-like Dhall dialect here rather than the+[YAML](https://en.wikipedia.org/wiki/YAML) of hpack we're able to;++* Add types to the fields.+* Safely import from other `*.dhall` files.+* Use functions.++## Imports and Functions++With this safer and more capable alternative input format for hpack, we're able+to simply describe the package and by using imports and functions we can do+more such as configuring linting;++```+> cat default-extensions.dhall+{ default-extensions =+ [ "DataKinds"+ , "DeriveFunctor"+ ...+ , "TupleSections"+ , "UndecidableInstances"+ ]+}++> cat hlint.dhall+ let Prelude/List/map =+ https://raw.githubusercontent.com/dhall-lang/Prelude/35deff0d41f2bf86c42089c6ca16665537f54d75/List/map++in let defs = ./default-extensions.dhall++in let f = λ(s : Text) → "-X" ++ s++in { arguments = Prelude/List/map Text Text f defs.default-extensions }++> dhall-to-yaml < ./hlint.dhall > ./.hlint.yaml++> cat .hlint.yaml+arguments:+- -XDataKinds+- -XDeriveFunctor+...+- -XTupleSections+- -XUndecidableInstances+```++We can pull those same `default-extensions` into a package description;++```+> cat package.dhall+ let defs = ./defaults.dhall++in defs+ ⫽ ./default-extensions.dhall+ ⫽ { name =+ "flight-units"+ ...+ , github =+ "blockscope/flare-timing/units"+ ...+ , dependencies =+ defs.dependencies+ # [ "numbers"+ , "fixed"+ , "bifunctors"+ , "text"+ , "formatting"+ , "uom-plugin"+ , "siggy-chardust"+ ]+ ...+ }+```++## Formatting++We can consistently format `package.dhall` and other `*.dhall` imports using+`dhall`;++```+> stack install dhall --stack-yaml=stack-dhall.yaml+> __bin/dhall format --inplace package.dhall+```
+ changelog.md view
@@ -0,0 +1,5 @@+The [latest version](https://github.com/blockscope/hpack-dhall/blob/master/changelog.md) of this changelog.++* Add licence and copyright.+* Rename hpack-dhall to dhall-hpack-cabal.+* Add dhall-hpack-* executables for showing dhall, json and yaml.
− driver/Main.hs
@@ -1,6 +0,0 @@-module Main (main) where--import qualified Hpack.Dhall--main :: IO ()-main = Hpack.Dhall.main
+ exe/dhall-hpack-cabal/CabalMain.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ApplicativeDo #-}++module Main (main) where++import Paths_hpack_dhall (version)+import Data.Version (showVersion)+import Data.Monoid ((<>))+import Data.Foldable (asum)+import qualified Options.Applicative as O+import Options+ ( parsePkgFile, parseNumericVersion, parseVersion+ , parseForce, parseQuiet+ )+import qualified Hpack as H (hpack, version, getOptions, setDecode)+import Hpack.Dhall (fileToJson)++data Command = NumericVersion | Version | Run Options++data Options =+ Options+ { pkgFile :: String+ , force :: Bool+ , quiet :: Bool+ }++parseOptions :: O.Parser Options+parseOptions = O.helper <*> do+ pkgFile <- parsePkgFile+ force <- parseForce+ quiet <- parseQuiet+ return (Options {..})++parserInfo :: O.ParserInfo Command+parserInfo =+ O.info parser $+ O.fullDesc+ <> O.header "Hpack's dhalling"+ <> O.progDesc "Write the .cabal for a .dhall package description, resolving imports."+ where+ parser = asum $+ [ NumericVersion <$ parseNumericVersion+ , Version <$ parseVersion+ , Run <$> parseOptions+ ]++main :: IO ()+main = do+ command <- O.execParser parserInfo++ case command of+ NumericVersion ->+ putStrLn $ showVersion version++ Version -> do+ putStrLn $ "dhall-hpack-cabal-" ++ showVersion version+ putStrLn $ "hpack-" ++ showVersion H.version++ Run (Options {..}) -> do+ opts <- H.getOptions pkgFile $+ mconcat+ [ if force then [ "--force" ] else []+ , if quiet then [ "--silent" ] else []+ ]+ case opts of+ Just (verbose, options) ->+ H.hpack verbose (H.setDecode fileToJson options)+ Nothing ->+ return ()
+ exe/dhall-hpack-dhall/DhallMain.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE RecordWildCards #-}++module Main (main) where++import Paths_hpack_dhall (version)+import Data.Version (showVersion)+import Data.Monoid ((<>))+import Data.Foldable (asum)+import qualified Options.Applicative as O+import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)+import Hpack.Dhall (showDhall)+import qualified Hpack as H (version)++data Command = NumericVersion | Version | Run Options++parserInfo :: O.ParserInfo Command+parserInfo =+ O.info parser $+ O.fullDesc+ <> O.header "Hpack as Dhall"+ <> O.progDesc "Show a package description expression with imports resolved."+ where+ parser = asum $+ [ NumericVersion <$ parseNumericVersion+ , Version <$ parseVersion+ , Run <$> parseOptions+ ]++main :: IO ()+main = do+ command <- O.execParser parserInfo++ case command of+ NumericVersion ->+ putStrLn $ showVersion version++ Version -> do+ putStrLn $ "dhall-hpack-dhall-" ++ showVersion version+ putStrLn $ "hpack-" ++ showVersion H.version++ Run (Options {..}) -> do+ s <- showDhall pkgFile+ putStrLn s+ return ()
+ exe/dhall-hpack-json/JsonMain.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE RecordWildCards #-}++module Main (main) where++import Paths_hpack_dhall (version)+import Data.Version (showVersion)+import Data.Monoid ((<>))+import Data.Foldable (asum)+import qualified Options.Applicative as O+import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)+import Hpack.Dhall (showJson)+import qualified Hpack as H (version)++data Command = NumericVersion | Version | Run Options++parserInfo :: O.ParserInfo Command+parserInfo =+ O.info parser $+ O.fullDesc+ <> O.header "Hpack as JSON"+ <> O.progDesc "Show a package description as JSON."+ where+ parser = asum $+ [ NumericVersion <$ parseNumericVersion+ , Version <$ parseVersion+ , Run <$> parseOptions+ ]++main :: IO ()+main = do+ command <- O.execParser parserInfo++ case command of+ NumericVersion ->+ putStrLn $ showVersion version++ Version -> do+ putStrLn $ "dhall-hpack-json-" ++ showVersion version+ putStrLn $ "hpack-" ++ showVersion H.version++ Run (Options {..}) -> do+ s <- showJson pkgFile+ putStrLn s+ return ()
+ exe/dhall-hpack-yaml/YamlMain.hs view
@@ -0,0 +1,44 @@+{-# LANGUAGE RecordWildCards #-}++module Main (main) where++import Paths_hpack_dhall (version)+import Data.Version (showVersion)+import Data.Monoid ((<>))+import Data.Foldable (asum)+import qualified Options.Applicative as O+import Options (Options(..), parseOptions, parseNumericVersion, parseVersion)+import Hpack.Dhall (showYaml)+import qualified Hpack as H (version)++data Command = NumericVersion | Version | Run Options++parserInfo :: O.ParserInfo Command+parserInfo =+ O.info parser $+ O.fullDesc+ <> O.header "Hpack as YAML"+ <> O.progDesc "Show a package description as YAML."+ where+ parser = asum $+ [ NumericVersion <$ parseNumericVersion+ , Version <$ parseVersion+ , Run <$> parseOptions+ ]++main :: IO ()+main = do+ command <- O.execParser parserInfo++ case command of+ NumericVersion ->+ putStrLn $ showVersion version++ Version -> do+ putStrLn $ "dhall-hpack-yaml-" ++ showVersion version+ putStrLn $ "hpack-" ++ showVersion H.version++ Run (Options {..}) -> do+ s <- showYaml pkgFile+ putStrLn s+ return ()
+ exe/options/Options.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ApplicativeDo #-}++module Options+ ( Options(..)+ , parseNumericVersion+ , parseVersion+ , parseOptions+ , parsePkgFile+ , parseForce+ , parseQuiet+ ) where++import Data.Monoid ((<>))+import Hpack.Dhall (packageConfig)+import Options.Applicative++data Options = Options {pkgFile :: FilePath}++parseOptions :: Parser Options+parseOptions = helper <*> do+ pkgFile <- parsePkgFile+ return (Options {..})++parsePkgFile :: Parser FilePath+parsePkgFile =+ strOption $+ long "package-dhall"+ <> metavar "FILE"+ <> value packageConfig+ <> showDefault+ <> help "A record of hpack fields"++parseNumericVersion :: Parser ()+parseNumericVersion =+ flag' () $+ long "numeric-version"+ <> help "Show version only"++parseVersion :: Parser ()+parseVersion =+ flag' () $+ long "version"+ <> help "Show app name and version"++parseForce :: Parser Bool+parseForce =+ flag False True $+ long "force"+ <> short 'f'+ <> help "Overwrite of the output .cabal file unnecessarily"++parseQuiet :: Parser Bool+parseQuiet =+ flag False True $+ long "silent"+ <> help "Suppress logging"
hpack-dhall.cabal view
@@ -1,67 +1,237 @@-cabal-version: >= 1.10+cabal-version: 1.12 --- This file has been generated from package.dhall by hpack version 0.29.5.+-- This file has been generated from package.dhall by hpack version 0.31.0. -- -- see: https://github.com/sol/hpack ----- hash: 5aa240e82d90764729d6746cb05e32e98ad0acd863464d3e0521a9d58c9185f0+-- hash: 64cfd0522c69d9cf130736447533067efeee2a454d47b7ede022b171105fa273 name: hpack-dhall-version: 0.3.0-synopsis: Dhall support for Hpack-description: This package allows you to use the Dhall configuration language to specify Haskell packages.+version: 0.4.0+synopsis: hpack's dhalling+description: Work with hpack's top-level+ <https://github.com/sol/hpack#top-level-fields fields> in a Dhall+ record with the following executables;+ .+ * with @dhall-hpack-cabal@ write the @.cabal@ for a @.dhall@ package description.+ * with @dhall-hpack-dhall@ show the package description expression, with imports resolved.+ * with @dhall-hpack-json@ show the package description as JSON.+ * with @dhall-hpack-yaml@ show the package description as YAML. category: Development-homepage: https://github.com/sol/hpack-dhall#readme-bug-reports: https://github.com/sol/hpack-dhall/issues-maintainer: Simon Hengel <sol@typeful.net>-license: PublicDomain+homepage: https://github.com/blockscope/hpack-dhall#readme+bug-reports: https://github.com/blockscope/hpack-dhall/issues+maintainer: Phil de Joux <phil.dejoux@blockscope.com>+copyright: © 2018 Phil de Joux, © 2018 Block Scope Limited+license: BSD3+license-file: LICENSE+tested-with: GHC == 8.4.3, GHC == 8.4.4, GHC == 8.6.1 build-type: Simple+extra-source-files:+ package.dhall+ changelog.md+ README.md+ test/golden/hpack-dhall-cabal/empty-inferred/package.dhall+ test/golden/hpack-dhall-cabal/empty-package.dhall+ test/golden/hpack-dhall-cabal/import-local/package.dhall+ test/golden/hpack-dhall-cabal/import-relative/package.dhall+ test/golden/hpack-dhall-cabal/import-local/name.dhl+ test/golden/hpack-dhall-cabal/import-relative.dhl+ test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal+ test/golden/hpack-dhall-cabal/empty-package.cabal+ test/golden/hpack-dhall-cabal/import-local/import-local.cabal+ test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal+ test/golden/hpack-dhall-cabal/empty-inferred/package.json+ test/golden/hpack-dhall-cabal/empty-package.json+ test/golden/hpack-dhall-cabal/import-local/package.json+ test/golden/hpack-dhall-cabal/import-relative/package.json+ test/golden/hpack-dhall-cabal/empty-inferred/package.yaml+ test/golden/hpack-dhall-cabal/empty-package.yaml+ test/golden/hpack-dhall-cabal/import-local/package.yaml+ test/golden/hpack-dhall-cabal/import-relative/package.yaml+ test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal.golden+ test/golden/hpack-dhall-cabal/empty-inferred/package.dhall.golden+ test/golden/hpack-dhall-cabal/empty-package.cabal.golden+ test/golden/hpack-dhall-cabal/empty-package.dhall.golden+ test/golden/hpack-dhall-cabal/import-local/import-local.cabal.golden+ test/golden/hpack-dhall-cabal/import-local/package.dhall.golden+ test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal.golden+ test/golden/hpack-dhall-cabal/import-relative/package.dhall.golden source-repository head type: git- location: https://github.com/sol/hpack-dhall+ location: https://github.com/blockscope/hpack-dhall -executable hpack-dhall- main-is: Main.hs+library+ exposed-modules:+ Hpack.Dhall other-modules:+ Paths_hpack_dhall+ hs-source-dirs:+ library+ ghc-options: -Wall+ build-depends:+ aeson+ , aeson-pretty+ , base ==4.*+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , prettyprinter+ , text+ , transformers+ , yaml+ default-language: Haskell2010++executable dhall-hpack-cabal+ main-is: CabalMain.hs+ other-modules: Hpack.Dhall+ Options Paths_hpack_dhall hs-source-dirs:- src- driver+ library+ exe/options+ exe/dhall-hpack-cabal ghc-options: -Wall build-depends: aeson+ , aeson-pretty , base ==4.*- , dhall- , dhall-json- , hpack >=0.26.0- , megaparsec+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , optparse-applicative+ , prettyprinter , text , transformers+ , yaml default-language: Haskell2010 -test-suite spec- type: exitcode-stdio-1.0- main-is: Spec.hs+executable dhall-hpack-dhall+ main-is: DhallMain.hs other-modules: Hpack.Dhall- Hpack.DhallSpec+ Options Paths_hpack_dhall hs-source-dirs:- src- test+ library+ exe/options+ exe/dhall-hpack-dhall ghc-options: -Wall build-depends: aeson+ , aeson-pretty , base ==4.*- , dhall- , dhall-json- , hpack >=0.26.0- , hspec ==2.*- , interpolate- , megaparsec- , mockery+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , optparse-applicative+ , prettyprinter , text , transformers+ , yaml+ default-language: Haskell2010++executable dhall-hpack-json+ main-is: JsonMain.hs+ other-modules:+ Hpack.Dhall+ Options+ Paths_hpack_dhall+ hs-source-dirs:+ library+ exe/options+ exe/dhall-hpack-json+ ghc-options: -Wall+ build-depends:+ aeson+ , aeson-pretty+ , base ==4.*+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , optparse-applicative+ , prettyprinter+ , text+ , transformers+ , yaml+ default-language: Haskell2010++executable dhall-hpack-yaml+ main-is: YamlMain.hs+ other-modules:+ Hpack.Dhall+ Options+ Paths_hpack_dhall+ hs-source-dirs:+ library+ exe/options+ exe/dhall-hpack-yaml+ ghc-options: -Wall+ build-depends:+ aeson+ , aeson-pretty+ , base ==4.*+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , optparse-applicative+ , prettyprinter+ , text+ , transformers+ , yaml+ default-language: Haskell2010++test-suite golden+ type: exitcode-stdio-1.0+ main-is: Golden.hs+ other-modules:+ Hpack.Dhall+ Hpack.Dhall+ Paths_hpack_dhall+ hs-source-dirs:+ library+ library+ test/golden+ ghc-options: -Wall+ build-depends:+ Cabal+ , Diff+ , aeson+ , aeson-pretty+ , base+ , bytestring+ , dhall >=1.18.0+ , dhall-json >=1.2.4+ , filepath+ , hpack >=0.31.0+ , megaparsec >=7.0.1+ , microlens+ , prettyprinter+ , tasty+ , tasty-golden+ , text+ , transformers+ , utf8-string+ , yaml default-language: Haskell2010
+ library/Hpack/Dhall.hs view
@@ -0,0 +1,132 @@+{-# LANGUAGE TupleSections #-}++{-|+Module: Hpack.Dhall+Copyright:+ © 2018 Phil de Joux+ © 2018 Block Scope Limited+License: BSD3 +Maintainer: Phil de Joux <phil.dejoux@blockscope.com>+Stability: experimental+Instead of working with <https://github.com/sol/hpack#readme hpack> in+<https://en.wikipedia.org/wiki/YAML YAML>, use+<https://github.com/dhall-lang/dhall-lang#readme Dhall>. All functions resolve+imports relative to the location of the given @.dhall@ file.+-}+module Hpack.Dhall+ ( fileToJson+ , showJson+ , showYaml+ , showDhall+ , packageConfig+ ) where++import Data.Function ((&))+import Lens.Micro ((^.), set)+import System.FilePath (takeDirectory)+import Control.Exception (throwIO)+import Control.Monad.Trans.Except (ExceptT(..), runExceptT)+import Control.Monad.IO.Class (liftIO)+import qualified Control.Monad.Trans.State.Strict as State+import Data.Bifunctor (first)+import Data.Aeson (ToJSON, Value)+import Data.Aeson.Encode.Pretty (encodePretty)+import qualified Data.ByteString.Lazy as BSL (toStrict)+import Data.Text.Encoding (decodeUtf8)+import qualified Data.Text as T (Text, unpack)+import qualified Data.Text.IO as T (readFile)+import Dhall+ ( InputSettings, Text+ , rootDirectory, sourceName, defaultInputSettings+ )+import Dhall.Core (Expr)+import Dhall.Parser (Src, exprFromText)+import Dhall.Import (loadWith, emptyStatus)+import Dhall.TypeCheck (X, typeOf)+import Dhall.JSON (dhallToJSON)+import Dhall.Pretty (prettyExpr, layoutOpts)+import Data.Yaml (encode)+import qualified Data.Text.Prettyprint.Doc as PP+import qualified Data.Text.Prettyprint.Doc.Render.Text as PP++-- SEE: http://onoffswitch.net/adventures-pretty-printing-json-haskell/+getJson :: ToJSON a => a -> String+getJson = T.unpack . decodeUtf8 . BSL.toStrict . encodePretty++getYaml :: ToJSON a => a -> String+getYaml = T.unpack . decodeUtf8 . Data.Yaml.encode++-- | The default package file name is @package.dhall@.+packageConfig :: FilePath+packageConfig = "package.dhall"++-- | Pretty prints JSON for the package description.+showJson+ :: FilePath -- ^ Path to a @.dhall@ file+ -> IO String+showJson file = do+ Right (_, v) <- fileToJson file+ return $ getJson v++-- | Pretty prints YAML for the package description.+showYaml+ :: FilePath -- ^ Path to a @.dhall@ file+ -> IO String+showYaml file = do+ Right (_, v) <- fileToJson file+ return $ getYaml v++-- | Pretty prints the package description Dhall expression, resolving imports+-- relative to the location of the @.dhall@ file.+showDhall+ :: FilePath -- ^ Path to a @.dhall@ file+ -> IO String+showDhall file = do+ text <- T.readFile file+ expr <- check (inputSettings file) text+ return . T.unpack $ renderDhall expr++-- | A file decoder for hpack. This should evaluate to a single record with+-- hpack's top-level <https://github.com/sol/hpack#top-level-fields fields>.+fileToJson+ :: FilePath -- ^ Path to a @.dhall@ file+ -> IO (Either String ([String], Value))+fileToJson file =+ liftIO (T.readFile file)+ >>= textToJson (inputSettings file)++inputSettings :: FilePath -> InputSettings+inputSettings file =+ Dhall.defaultInputSettings+ & set rootDirectory (takeDirectory file)+ & set sourceName file++textToJson+ :: InputSettings+ -> T.Text+ -> IO (Either String ([String], Value))+textToJson settings text = runExceptT $ do+ expr <- liftIO $ check settings text+ _ <- liftResult $ typeOf expr+ liftResult $ ([],) <$> dhallToJSON expr+ where+ liftResult :: (Show b, Monad m) => Either b a -> ExceptT String m a+ liftResult = ExceptT . return . first show++check :: InputSettings -> Text -> IO (Expr Src X)+check settings text = do+ expr <- either throwIO return $ exprFromText mempty text++ x <- State.evalStateT+ (loadWith expr)+ (emptyStatus $ settings ^. rootDirectory)++ return x++-- SEE: https://github.com/mstksg/hakyll-dhall+renderDhall :: (PP.Pretty a, Eq a) => Expr Src a -> T.Text+renderDhall =+ PP.renderStrict+ . PP.layoutSmart layoutOpts+ . PP.unAnnotate+ . prettyExpr
+ package.dhall view
@@ -0,0 +1,131 @@+ let deps =+ [ "base == 4.*"+ , "megaparsec >= 7.0.1"+ , "dhall >= 1.18.0"+ , "dhall-json >= 1.2.4"+ , "hpack >= 0.31.0"+ , "transformers"+ , "aeson"+ , "text"+ , "microlens"+ , "filepath"+ , "aeson-pretty"+ , "bytestring"+ , "prettyprinter"+ , "yaml"+ ]++in let exe-deps = deps # [ "optparse-applicative" ]++in { name =+ "hpack-dhall"+ , version =+ "0.4.0"+ , maintainer =+ "Phil de Joux <phil.dejoux@blockscope.com>"+ , copyright =+ "\u00A9 2018 Phil de Joux, \u00A9 2018 Block Scope Limited"+ , license =+ "BSD3"+ , license-file =+ "LICENSE"+ , category =+ "Development"+ , synopsis =+ "hpack's dhalling"+ , description =+ ''+ Work with hpack's top-level+ <https://github.com/sol/hpack#top-level-fields fields> in a Dhall+ record with the following executables;+ + * with @dhall-hpack-cabal@ write the @.cabal@ for a @.dhall@ package description.+ * with @dhall-hpack-dhall@ show the package description expression, with imports resolved.+ * with @dhall-hpack-json@ show the package description as JSON.+ * with @dhall-hpack-yaml@ show the package description as YAML.+ ''+ , github =+ "blockscope/hpack-dhall"+ , tested-with =+ "GHC == 8.4.3, GHC == 8.4.4, GHC == 8.6.1"+ , extra-source-files =+ [ "package.dhall"+ , "changelog.md"+ , "README.md"+ , "test/golden/**/*.dhall"+ , "test/golden/**/*.dhl"+ , "test/golden/**/*.cabal"+ , "test/golden/**/*.json"+ , "test/golden/**/*.yaml"+ , "test/golden/**/*.golden"+ ]+ , ghc-options =+ "-Wall"+ , dependencies =+ deps+ , source-dirs =+ "library"+ , library =+ { exposed-modules = "Hpack.Dhall" }+ , executables =+ { dhall-hpack-cabal =+ { main =+ "CabalMain.hs"+ , source-dirs =+ [ "exe/options", "exe/dhall-hpack-cabal" ]+ , dependencies =+ exe-deps+ }+ , dhall-hpack-json =+ { main =+ "JsonMain.hs"+ , source-dirs =+ [ "exe/options", "exe/dhall-hpack-json" ]+ , dependencies =+ exe-deps+ }+ , dhall-hpack-yaml =+ { main =+ "YamlMain.hs"+ , source-dirs =+ [ "exe/options", "exe/dhall-hpack-yaml" ]+ , dependencies =+ exe-deps+ }+ , dhall-hpack-dhall =+ { main =+ "DhallMain.hs"+ , source-dirs =+ [ "exe/options", "exe/dhall-hpack-dhall" ]+ , dependencies =+ exe-deps+ }+ }+ , tests =+ { golden =+ { main =+ "Golden.hs"+ , source-dirs =+ [ "library", "test/golden" ]+ , dependencies =+ [ "base"+ , "Cabal"+ , "Diff"+ , "dhall"+ , "filepath"+ , "microlens"+ , "prettyprinter"+ , "tasty"+ , "tasty-golden"+ , "text"+ , "megaparsec >= 7.0.1"+ , "dhall >= 1.18.0"+ , "dhall-json >= 1.2.4"+ , "hpack >= 0.31.0"+ , "transformers"+ , "aeson"+ , "utf8-string"+ ]+ }+ }+ }
− src/Hpack/Dhall.hs
@@ -1,35 +0,0 @@-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-module Hpack.Dhall where--import Control.Monad.Trans.Except-import Control.Monad.IO.Class-import Data.Bifunctor-import Data.Aeson-import qualified Data.Text.IO as T-import System.Environment-import qualified Dhall.Parser-import qualified Dhall.Import-import qualified Dhall.TypeCheck-import qualified Dhall.JSON--import qualified Hpack--packageConfig :: FilePath-packageConfig = "package.dhall"--decodeDhall :: FilePath -> IO (Either String Value)-decodeDhall file = runExceptT $ do- expr <- readInput >>= parseExpr >>= liftIO . Dhall.Import.load- _ <- liftResult $ Dhall.TypeCheck.typeOf expr- liftResult $ Dhall.JSON.dhallToJSON expr- where- readInput = liftIO (T.readFile file)- parseExpr = liftResult . Dhall.Parser.exprFromText file- liftResult = ExceptT . return . first show--main :: IO ()-main = do- getArgs >>= Hpack.getOptions packageConfig >>= \ case- Just (verbose, options) -> Hpack.hpack verbose (Hpack.setDecode decodeDhall options)- Nothing -> return ()
− test/Hpack/DhallSpec.hs
@@ -1,37 +0,0 @@-{-# LANGUAGE QuasiQuotes #-}-module Hpack.DhallSpec (spec) where--import Test.Hspec-import Test.Mockery.Directory-import Data.String.Interpolate-import Data.String.Interpolate.Util--import Data.Version (showVersion)-import qualified Hpack--import Hpack.Dhall--spec :: Spec-spec = do- describe "main" $ do- it "generates cabal files" $ do- inTempDirectory $ do- writeFile packageConfig [i|- {- name = "foo"- }- |]- main- readFile "foo.cabal" `shouldReturn` unindent [i|- cabal-version: >= 1.10-- -- This file has been generated from package.dhall by hpack version #{showVersion Hpack.version}.- --- -- see: https://github.com/sol/hpack- --- -- hash: 98987c02e53bcdf76e4c3d2912c868d16f30f3115762548e41d337f436ffc1cc-- name: foo- version: 0.0.0- build-type: Simple- |]
− test/Spec.hs
@@ -1,1 +0,0 @@-{-# OPTIONS_GHC -fforce-recomp -F -pgmF hspec-discover #-}
+ test/golden/Golden.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE MultiWayIf #-}++module Main (main) where++import System.FilePath+ ( (</>), (<.>), (-<.>)+ , takeBaseName, replaceExtension+ , takeDirectory, splitDirectories, joinPath+ )+import Test.Tasty (defaultMain, TestTree, testGroup)+import Test.Tasty.Golden (findByExtension)+import Test.Tasty.Golden (goldenVsFile, goldenVsString)++import Hpack (Verbose(..), Options(..), hpack, defaultOptions, setDecode)+import Hpack.Config (DecodeOptions(..))+import Hpack.Dhall (fileToJson, showDhall, showJson, showYaml)+import Data.ByteString.Lazy.UTF8 (fromString)++main :: IO ()+main =+ defaultMain =<< goldenTests++goldenTests :: IO TestTree+goldenTests = do+ dhallFiles <- findByExtension [".dhall"] "test/golden/hpack-dhall-cabal/"+ return $ testGroup "golden tests"+ [ testGroup ".dhall to .cabal"+ [ goldenVsFile+ (testName dhallFile)+ (cabalFile <.> ".golden")+ cabalFile+ (writeCabal dhallFile)+ | dhallFile <- dhallFiles+ , let cabalFile = cabalFilePath dhallFile+ ]+ , testGroup ".dhall to dhall"+ [ goldenVsString+ (testName dhallFile)+ (dhallFile <.> ".golden")+ (fmap fromString . showDhall $ dhallFile)+ | dhallFile <- dhallFiles+ ]+ , testGroup ".dhall to json"+ [ goldenVsString+ (testName dhallFile)+ (dhallFile -<.> ".json")+ (fmap fromString . showJson $ dhallFile)+ | dhallFile <- dhallFiles+ ]+ , testGroup ".dhall to yaml"+ [ goldenVsString+ (testName dhallFile)+ (dhallFile -<.> ".yaml")+ (fmap fromString . showYaml $ dhallFile)+ | dhallFile <- dhallFiles+ ]+ ]++testName :: FilePath -> FilePath+testName p =+ if | fName == dName -> fName+ | fName == "package" -> dName+ | dName == "hpack-dhall-cabal" -> fName+ | otherwise -> dName </> fName+ where+ dName =+ joinPath+ . take 1+ . reverse+ . splitDirectories+ . takeDirectory+ $ p++ fName = takeBaseName p++writeCabal :: FilePath -> IO ()+writeCabal dhallFile =+ hpack NoVerbose (setDecode fileToJson options)+ where+ d = optionsDecodeOptions defaultOptions+ d' = d {decodeOptionsTarget = dhallFile}+ options = defaultOptions {optionsDecodeOptions = d'}++cabalFilePath :: FilePath -> FilePath+cabalFilePath p+ | takeBaseName p == "package" =+ case reverse . splitDirectories $ ds of+ d : ds' -> joinPath (reverse ds') </> d </> d <.> ".cabal"+ _ -> replaceExtension p ".cabal"++ | otherwise =+ replaceExtension p ".cabal"++ where+ ds = takeDirectory p
+ test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 9f10239d716ef4564587e29b36c0e3b74056721733790211e20061a86a0feb53++name: empty-inferred+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/empty-inferred/empty-inferred.cabal.golden view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 9f10239d716ef4564587e29b36c0e3b74056721733790211e20061a86a0feb53++name: empty-inferred+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/empty-inferred/package.dhall view
@@ -0,0 +1,1 @@+{=}
+ test/golden/hpack-dhall-cabal/empty-inferred/package.dhall.golden view
@@ -0,0 +1,1 @@+{=}
+ test/golden/hpack-dhall-cabal/empty-inferred/package.json view
@@ -0,0 +1,1 @@+{}
+ test/golden/hpack-dhall-cabal/empty-inferred/package.yaml view
@@ -0,0 +1,1 @@+{}
+ test/golden/hpack-dhall-cabal/empty-package.cabal view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from empty-package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: e0a74f511d829cae53cd712664781db312951dd773249603163ba1b1e32afd04++name: empty-package+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/empty-package.cabal.golden view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from empty-package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: e0a74f511d829cae53cd712664781db312951dd773249603163ba1b1e32afd04++name: empty-package+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/empty-package.dhall view
@@ -0,0 +1,1 @@+{ name = "empty-package" }
+ test/golden/hpack-dhall-cabal/empty-package.dhall.golden view
@@ -0,0 +1,1 @@+{ name = "empty-package" }
+ test/golden/hpack-dhall-cabal/empty-package.json view
@@ -0,0 +1,3 @@+{+ "name": "empty-package"+}
+ test/golden/hpack-dhall-cabal/empty-package.yaml view
@@ -0,0 +1,1 @@+name: empty-package
+ test/golden/hpack-dhall-cabal/import-local/import-local.cabal view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: fb3f09267f149cb49eb030ac951c27be9964aa0d51e91460e5b2d59ee1a5082f++name: import-local+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/import-local/import-local.cabal.golden view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: fb3f09267f149cb49eb030ac951c27be9964aa0d51e91460e5b2d59ee1a5082f++name: import-local+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/import-local/name.dhl view
@@ -0,0 +1,1 @@+{ name = "import-local" }
+ test/golden/hpack-dhall-cabal/import-local/package.dhall view
@@ -0,0 +1,1 @@+./name.dhl ⫽ {=}
+ test/golden/hpack-dhall-cabal/import-local/package.dhall.golden view
@@ -0,0 +1,1 @@+{ name = "import-local" } ⫽ {=}
+ test/golden/hpack-dhall-cabal/import-local/package.json view
@@ -0,0 +1,3 @@+{+ "name": "import-local"+}
+ test/golden/hpack-dhall-cabal/import-local/package.yaml view
@@ -0,0 +1,1 @@+name: import-local
+ test/golden/hpack-dhall-cabal/import-relative.dhl view
@@ -0,0 +1,1 @@+{ name = "import-relative" }
+ test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 989056d21c3910e06ec15967716df134a39f43c561858afff828d22802a22005++name: import-relative+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/import-relative/import-relative.cabal.golden view
@@ -0,0 +1,11 @@+cabal-version: 1.12++-- This file has been generated from package.dhall by hpack version 0.31.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 989056d21c3910e06ec15967716df134a39f43c561858afff828d22802a22005++name: import-relative+version: 0.0.0+build-type: Simple
+ test/golden/hpack-dhall-cabal/import-relative/package.dhall view
@@ -0,0 +1,1 @@+../import-relative.dhl ⫽ {=}
+ test/golden/hpack-dhall-cabal/import-relative/package.dhall.golden view
@@ -0,0 +1,1 @@+{ name = "import-relative" } ⫽ {=}
+ test/golden/hpack-dhall-cabal/import-relative/package.json view
@@ -0,0 +1,3 @@+{+ "name": "import-relative"+}
+ test/golden/hpack-dhall-cabal/import-relative/package.yaml view
@@ -0,0 +1,1 @@+name: import-relative