-- |Description: Utilities for extracting stack info to the canonical types in "Data.Prune.Types".
module Data.Prune.Stack where

import Prelude

import qualified Data.ByteString as BS
import qualified Data.Yaml as Yaml

import qualified Data.Prune.Types as T

-- |Parse stack.yaml by file path, filter by explicit package names (if provided), and return the parsed packages.
parseStackYaml :: FilePath -> IO (T.BuildSystem, [FilePath])
parseStackYaml :: FilePath -> IO (BuildSystem, [FilePath])
parseStackYaml FilePath
stackYamlFile = do
  (ParseException -> IO (BuildSystem, [FilePath]))
-> (StackYaml -> IO (BuildSystem, [FilePath]))
-> Either ParseException StackYaml
-> IO (BuildSystem, [FilePath])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (FilePath -> IO (BuildSystem, [FilePath])
forall (m :: * -> *) a. MonadFail m => FilePath -> m a
fail (FilePath -> IO (BuildSystem, [FilePath]))
-> (ParseException -> FilePath)
-> ParseException
-> IO (BuildSystem, [FilePath])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath
"Couldn't parse stack.yaml due to " FilePath -> FilePath -> FilePath
forall a. Semigroup a => a -> a -> a
<>) (FilePath -> FilePath)
-> (ParseException -> FilePath) -> ParseException -> FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseException -> FilePath
forall a. Show a => a -> FilePath
show) ((BuildSystem, [FilePath]) -> IO (BuildSystem, [FilePath])
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((BuildSystem, [FilePath]) -> IO (BuildSystem, [FilePath]))
-> (StackYaml -> (BuildSystem, [FilePath]))
-> StackYaml
-> IO (BuildSystem, [FilePath])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BuildSystem
T.Stack,) ([FilePath] -> (BuildSystem, [FilePath]))
-> (StackYaml -> [FilePath])
-> StackYaml
-> (BuildSystem, [FilePath])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackYaml -> [FilePath]
T.stackYamlPackages) (Either ParseException StackYaml -> IO (BuildSystem, [FilePath]))
-> (ByteString -> Either ParseException StackYaml)
-> ByteString
-> IO (BuildSystem, [FilePath])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either ParseException StackYaml
forall a. FromJSON a => ByteString -> Either ParseException a
Yaml.decodeEither' (ByteString -> IO (BuildSystem, [FilePath]))
-> IO ByteString -> IO (BuildSystem, [FilePath])
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> IO ByteString
BS.readFile FilePath
stackYamlFile