@@ -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