packages feed

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 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++[![Build Status](https://travis-ci.org/BlockScope/hpack-dhall.svg)](https://travis-ci.org/BlockScope/hpack-dhall)+[![hackage release](https://img.shields.io/hackage/v/hpack-dhall.svg?label=hackage)](http://hackage.haskell.org/package/hpack-dhall)+[![Dependencies of latest version on Hackage](https://img.shields.io/hackage-deps/v/hpack-dhall.svg)](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