@@ -14,7 +14,7 @@ module Obelisk.Command.Run where
14import Control.Arrow ((&&&))
14import Control.Arrow ((&&&))
15import Control.Exception (Exception, bracket)
15import Control.Exception (Exception, bracket)
16import Control.Lens (ifor, (.~), (&))
16import Control.Lens (ifor, (.~), (&))
17−import Control.Monad (filterM)
17+import Control.Monad (filterM, unless)
18import Control.Monad.Except (runExceptT, throwError)
18import Control.Monad.Except (runExceptT, throwError)
19import Control.Monad.IO.Class (liftIO)
19import Control.Monad.IO.Class (liftIO)
20import Control.Monad.Reader (MonadIO)
20import Control.Monad.Reader (MonadIO)
@@ -46,7 +46,7 @@ import Distribution.Compiler (CompilerFlavor(..))
46import Distribution.PackageDescription.Parsec (parseGenericPackageDescription)
46import Distribution.PackageDescription.Parsec (parseGenericPackageDescription)
47import Distribution.Parsec.ParseResult (runParseResult)
47import Distribution.Parsec.ParseResult (runParseResult)
48import qualified Distribution.System as Dist
48import qualified Distribution.System as Dist
49−import Distribution.Types.BuildInfo (buildable, cppOptions, defaultExtensions, defaultLanguage, hsSourceDirs, options)
49+import Distribution.Types.BuildInfo (buildable, defaultExtensions, defaultLanguage, hsSourceDirs, options)
50import Distribution.Types.CondTree (simplifyCondTree)
50import Distribution.Types.CondTree (simplifyCondTree)
51import Distribution.Types.GenericPackageDescription (ConfVar (Arch, Impl, OS), condLibrary)
51import Distribution.Types.GenericPackageDescription (ConfVar (Arch, Impl, OS), condLibrary)
52import Distribution.Types.Library (libBuildInfo)
52import Distribution.Types.Library (libBuildInfo)
@@ -94,8 +94,6 @@ data CabalPackageInfo = CabalPackageInfo
94 -- ^ List of globally set languages of the library component
94 -- ^ List of globally set languages of the library component
95 , _cabalPackageInfo_compilerOptions :: [(CompilerFlavor, [String])]
95 , _cabalPackageInfo_compilerOptions :: [(CompilerFlavor, [String])]
96 -- ^ List of compiler-specific options (e.g., the "ghc-options" field of the cabal file)
96 -- ^ List of compiler-specific options (e.g., the "ghc-options" field of the cabal file)
97− , _cabalPackageInfo_cppOptions :: [String]
98− -- ^ List of CPP (C Preprocessor) options (e.g. the "cpp-options" field of the cabal file)
101-- | 'Bool' with a better name for its purpose.
99-- | 'Bool' with a better name for its purpose.
@@ -304,16 +302,15 @@ parseCabalPackage
304 -> m (Maybe CabalPackageInfo)
302 -> m (Maybe CabalPackageInfo)
305parseCabalPackage dir = parseCabalPackage' dir >>= \case
303parseCabalPackage dir = parseCabalPackage' dir >>= \case
306 Left err -> Nothing <$ putLog Error err
304 Left err -> Nothing <$ putLog Error err
307− Right (Just (warnings, pkgInfo)) -> do
305+ Right (warnings, pkgInfo) -> do
308 for_ warnings $ putLog Warning . T.pack . show
306 for_ warnings $ putLog Warning . T.pack . show
309 pure $ Just pkgInfo
307 pure $ Just pkgInfo
310− Right Nothing -> pure Nothing
312-- | Like 'parseCabalPackage' but returns errors and warnings directly so as to avoid 'MonadObelisk'.
309-- | Like 'parseCabalPackage' but returns errors and warnings directly so as to avoid 'MonadObelisk'.
313parseCabalPackage'
310parseCabalPackage'
314 :: (MonadIO m)
311 :: (MonadIO m)
315 => FilePath -- ^ Package directory
312 => FilePath -- ^ Package directory
316− -> m (Either T.Text (Maybe ([Dist.PWarning], CabalPackageInfo)))
313+ -> m (Either T.Text ([Dist.PWarning], CabalPackageInfo))
317parseCabalPackage' pkg = runExceptT $ do
314parseCabalPackage' pkg = runExceptT $ do
318 (cabalContents, packageFile, packageName) <- guessCabalPackageFile pkg >>= \case
315 (cabalContents, packageFile, packageName) <- guessCabalPackageFile pkg >>= \case
319 Left GuessPackageFileError_NotFound -> throwError $ "No .cabal or package.yaml file found in " <> T.pack pkg
316 Left GuessPackageFileError_NotFound -> throwError $ "No .cabal or package.yaml file found in " <> T.pack pkg
@@ -341,7 +338,7 @@ parseCabalPackage' pkg = runExceptT $ do
341 case condLibrary <$> result of
338 case condLibrary <$> result of
342 Right (Just condLib) -> do
339 Right (Just condLib) -> do
343 let (_, lib) = simplifyCondTree evalConfVar condLib
340 let (_, lib) = simplifyCondTree evalConfVar condLib
344− pure $ Just $ (warnings,) $ CabalPackageInfo
341+ pure $ (warnings,) $ CabalPackageInfo
345 { _cabalPackageInfo_packageName = T.pack packageName
342 { _cabalPackageInfo_packageName = T.pack packageName
346 , _cabalPackageInfo_packageFile = packageFile
343 , _cabalPackageInfo_packageFile = packageFile
347 , _cabalPackageInfo_packageRoot = takeDirectory packageFile
344 , _cabalPackageInfo_packageRoot = takeDirectory packageFile
@@ -353,19 +350,18 @@ parseCabalPackage' pkg = runExceptT $ do
353 , _cabalPackageInfo_defaultLanguage =
350 , _cabalPackageInfo_defaultLanguage =
354 defaultLanguage $ libBuildInfo lib
351 defaultLanguage $ libBuildInfo lib
355 , _cabalPackageInfo_compilerOptions = options $ libBuildInfo lib
352 , _cabalPackageInfo_compilerOptions = options $ libBuildInfo lib
356− , _cabalPackageInfo_cppOptions = cppOptions $ libBuildInfo lib
358− Right Nothing -> pure Nothing
354+ Right Nothing -> throwError "Haskell package has no library component"
359 Left (_, errors) ->
355 Left (_, errors) ->
360 throwError $ T.pack $ "Failed to parse " <> packageFile <> ":\n" <> unlines (map show errors)
356 throwError $ T.pack $ "Failed to parse " <> packageFile <> ":\n" <> unlines (map show errors)
362parsePackagesOrFail :: (MonadObelisk m, Foldable f) => f FilePath -> m (NE.NonEmpty CabalPackageInfo)
358parsePackagesOrFail :: (MonadObelisk m, Foldable f) => f FilePath -> m (NE.NonEmpty CabalPackageInfo)
363parsePackagesOrFail dirs' = do
359parsePackagesOrFail dirs' = do
364− packageInfos' <- fmap catMaybes $ for dirs $ \dir -> do
360+ (pkgDirErrs, packageInfos') <- fmap partitionEithers $ for dirs $ \dir -> do
365 flip fmap (parseCabalPackage dir) $ \case
361 flip fmap (parseCabalPackage dir) $ \case
366 Just packageInfo
362 Just packageInfo
367− | _cabalPackageInfo_buildable packageInfo -> Just packageInfo
363+ | _cabalPackageInfo_buildable packageInfo -> Right packageInfo
368− _ -> Nothing
364+ _ -> Left dir
370 -- Sort duplicate packages such that we prefer shorter paths, but fall back to alphabetical ordering.
366 -- Sort duplicate packages such that we prefer shorter paths, but fall back to alphabetical ordering.
371 let packagesByName = Map.map (NE.sortBy $ comparing $ \p -> let n = _cabalPackageInfo_packageFile p in (length n, n))
367 let packagesByName = Map.map (NE.sortBy $ comparing $ \p -> let n = _cabalPackageInfo_packageFile p in (length n, n))
@@ -387,6 +383,9 @@ parsePackagesOrFail dirs' = do
387 "No valid, buildable packages found" <> (if null dirs then "" else " in " <> intercalate ", " dirs)
383 "No valid, buildable packages found" <> (if null dirs then "" else " in " <> intercalate ", " dirs)
388 Just xs -> pure xs
384 Just xs -> pure xs
386+ unless (null pkgDirErrs) $
387+ putLog Warning $ T.pack $ "Failed to find buildable packages in " <> intercalate ", " pkgDirErrs
390 pure packageInfos
389 pure packageInfos
392 dirs = toList dirs'
391 dirs = toList dirs'