on master help sign in
Add support for hpack
commit37ebf60bd013ca1471cdf23bd3e13be1e770705e authorKen Micklas <kmicklas@gmail.com> dateWed 26 Sep 2018, 18:15 (8 years ago) parent3c34272
3 files changed+48−26
default.nix+4 lib/command/obelisk-command.cabal+1 lib/command/src/Obelisk/Command/Run.hs+43−26
default.nix+4
@@ -66,6 +66,10 @@ let
6666 sha256 = "0dpwi5ffs88brl3lz51bwb004c6zm8ds8pkw1vzsg2a6aaiyhlzl";
6767 }) {});
6868
69+ # Default hpack in the package set does not evaluate.
70+ # TODO: Remove this override after reunification with upstream nixpkgs.
71+ hpack = pkgs.haskell.lib.dontCheck (self.callHackage "hpack" "0.28.2" {});
72+
6973 monoidal-containers =
7074 let src = pkgs.fetchFromGitHub {
7175 owner = "obsidiansystems";
lib/command/obelisk-command.cabal+1
@@ -24,6 +24,7 @@ library
2424 , github
2525 , here
2626 , hit
27+ , hpack
2728 , io-streams
2829 , exceptions
2930 , logging-effect
lib/command/src/Obelisk/Command/Run.hs+43−26
@@ -21,7 +21,10 @@ import Distribution.Types.BuildInfo
2121import Distribution.Types.CondTree
2222import Distribution.Types.GenericPackageDescription
2323import Distribution.Types.Library
24−import Distribution.Utils.Generic (withUTF8FileContents, toUTF8BS)
24+import Distribution.Utils.Generic
25+import Hpack.Config
26+import Hpack.Render
27+import Hpack.Yaml
2528import Language.Haskell.Extension
2629import Network.Socket
2730import System.Directory
@@ -68,31 +71,46 @@ getLocalPkgs = pure ["backend", "common", "frontend"]
6871
6972parseCabalPackage
7073 :: (MonadObelisk m)
71− => FilePath -- ^ package cabal file path
74+ => FilePath -- ^ package directory
7275 -> m (Maybe CabalPackageInfo)
73−parseCabalPackage cabalFp = do
74− exists <- liftIO $ doesFileExist cabalFp
75− if exists
76+parseCabalPackage dir = do
77+ let hpackFp = dir </> "package.yaml"
78+ cabalFp = dir </> (takeBaseName dir <> ".cabal")
79+ hasHpack <- liftIO $ doesFileExist hpackFp
80+ mCabalContents <- if hasHpack
7681 then do
77− withUTF8FileContentsM cabalFp $ \cabal -> do
78− let (warnings, result) = runParseResult $ parseGenericPackageDescription cabal
79− mapM_ (putLog Warning) $ fmap (T.pack . show) warnings
80− case result of
81− Right gpkg -> do
82− return $ do
83− (_, lib) <- simplifyCondTree (const $ pure True) <$> condLibrary gpkg
84− pure $ CabalPackageInfo
85− { _cabalPackageInfo_packageRoot = takeDirectory cabalFp
86− , _cabalPackageInfo_sourceDirs =
87− fromMaybe (pure ".") $ NE.nonEmpty $ hsSourceDirs $ libBuildInfo lib
88− , _cabalPackageInfo_defaultExtensions =
89− defaultExtensions $ libBuildInfo lib
90− }
91− Left (_, errors) -> do
92− putLog Error $ T.pack "Failed to parse cabal file: "
93− mapM_ (putLog Error) $ fmap (T.pack . show) errors
94− return Nothing
95− else return Nothing
82+ let decodeOptions = DecodeOptions hpackFp Nothing decodeYaml
83+ liftIO (readPackageConfig decodeOptions) >>= \case
84+ Left err -> do
85+ putLog Error $ T.pack $ "Failed to parse " <> hpackFp <> ": " <> err
86+ return Nothing
87+ Right (DecodeResult hpackPackage _ _) -> do
88+ return $ Just $ renderPackage [] hpackPackage
89+ else do
90+ hasCabal <- liftIO $ doesFileExist cabalFp
91+ if hasCabal
92+ then Just <$> liftIO (readUTF8File cabalFp)
93+ else return Nothing
94+
95+ fmap join $ forM mCabalContents $ \cabalContents -> do
96+ let (warnings, result) = runParseResult $ parseGenericPackageDescription $
97+ toUTF8BS $ cabalContents
98+ mapM_ (putLog Warning) $ fmap (T.pack . show) warnings
99+ case result of
100+ Right gpkg -> do
101+ return $ do
102+ (_, lib) <- simplifyCondTree (const $ pure True) <$> condLibrary gpkg
103+ pure $ CabalPackageInfo
104+ { _cabalPackageInfo_packageRoot = takeDirectory cabalFp
105+ , _cabalPackageInfo_sourceDirs =
106+ fromMaybe (pure ".") $ NE.nonEmpty $ hsSourceDirs $ libBuildInfo lib
107+ , _cabalPackageInfo_defaultExtensions =
108+ defaultExtensions $ libBuildInfo lib
109+ }
110+ Left (_, errors) -> do
111+ putLog Error $ T.pack $ "Failed to parse " <> cabalFp <> ":"
112+ mapM_ (putLog Error) $ fmap (T.pack . show) errors
113+ return Nothing
96114
97115withUTF8FileContentsM :: (MonadIO m, HasCliConfig m) => FilePath -> (ByteString -> CliT IO a) -> m a
98116withUTF8FileContentsM fp f = do
@@ -107,8 +125,7 @@ withGhciScript
107125 -> m ()
108126withGhciScript pkgs f = do
109127 (pkgDirErrs, packageInfos) <- fmap partitionEithers $ forM pkgs $ \pkg -> do
110− let cabalFp = pkg </> pkg <.> "cabal"
111− flip fmap (parseCabalPackage cabalFp) $ \case
128+ flip fmap (parseCabalPackage pkg) $ \case
112129 Nothing -> Left pkg
113130 Just packageInfo -> Right packageInfo
114131