module Shellify (printErrorAndReturnFailure, runShellify, calculateExpectedFiles) where import Prelude hiding (readFile, writeFile) import Options (Options()) import TemplateGeneration ( generateFlakeText, generateShellDotNixText, getRegistryDB) import Control.Monad (guard, when) import Data.Bool (bool) import Data.Maybe (isNothing) import Data.Text (pack, Text(), unpack) import Data.Text.IO (hPutStrLn, readFile, writeFile) import GHC.IO.Exception (ExitCode(ExitSuccess, ExitFailure)) import System.Directory (doesPathExist) import System.Exit (exitWith) import System.IO (stderr) runShellify :: Options -> IO () runShellify :: Options -> IO () runShellify Options opts = IO (Either Text Text) getRegistryDB IO (Either Text Text) -> (Either Text Text -> IO ()) -> IO () forall a b. IO a -> (a -> IO b) -> IO b forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= (Text -> IO ()) -> (Text -> IO ()) -> Either Text Text -> IO () forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either (Text -> IO () forall {b}. Text -> IO b printErrorAndReturnFailure (Text -> IO ()) -> (Text -> Text) -> Text -> IO () forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text "Error calling nix registry: " <>)) (((Text, Text) -> IO ()) -> [(Text, Text)] -> IO () forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ (Text, Text) -> IO () createAFile ([(Text, Text)] -> IO ()) -> (Text -> [(Text, Text)]) -> Text -> IO () forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text -> Options -> [(Text, Text)] `calculateExpectedFiles` Options opts)) createAFile :: (Text, Text) -> IO () createAFile :: (Text, Text) -> IO () createAFile (Text name, Text content) = do ExitCode extCde <- FilePath -> Text -> IO ExitCode createFile (Text -> FilePath unpack Text name) Text content Bool -> IO () -> IO () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (ExitCode extCde ExitCode -> ExitCode -> Bool forall a. Eq a => a -> a -> Bool /= ExitCode ExitSuccess) (IO () -> IO ()) -> IO () -> IO () forall a b. (a -> b) -> a -> b $ ExitCode -> IO () forall a. ExitCode -> IO a exitWith ExitCode extCde where createFile :: FilePath -> Text -> IO ExitCode createFile :: FilePath -> Text -> IO ExitCode createFile FilePath fileName Text expectedContents = do Maybe Text fileContents <- (FilePath -> IO Text) -> Maybe FilePath -> IO (Maybe Text) forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) forall (f :: * -> *) a b. Applicative f => (a -> f b) -> Maybe a -> f (Maybe b) traverse FilePath -> IO Text readFile (Maybe FilePath -> IO (Maybe Text)) -> (Bool -> Maybe FilePath) -> Bool -> IO (Maybe Text) forall b c a. (b -> c) -> (a -> b) -> a -> c . Maybe FilePath -> Maybe FilePath -> Bool -> Maybe FilePath forall a. a -> a -> Bool -> a bool Maybe FilePath forall a. Maybe a Nothing (FilePath -> Maybe FilePath forall a. a -> Maybe a Just FilePath fileName) (Bool -> IO (Maybe Text)) -> IO Bool -> IO (Maybe Text) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b =<< FilePath -> IO Bool doesPathExist FilePath fileName Text -> IO () printError (Text -> IO ()) -> Text -> IO () forall a b. (a -> b) -> a -> b $ Text -> Text -> Maybe Text -> Text actionDescription (FilePath -> Text pack FilePath fileName) Text expectedContents Maybe Text fileContents Bool -> IO () -> IO () forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (Maybe Text -> Bool forall a. Maybe a -> Bool isNothing Maybe Text fileContents) (IO () -> IO ()) -> IO () -> IO () forall a b. (a -> b) -> a -> b $ FilePath -> Text -> IO () writeFile FilePath fileName Text expectedContents ExitCode -> IO ExitCode forall a. a -> IO a forall (m :: * -> *) a. Monad m => a -> m a return (ExitCode -> IO ExitCode) -> ExitCode -> IO ExitCode forall a b. (a -> b) -> a -> b $ Text -> Maybe Text -> ExitCode returnCode Text expectedContents Maybe Text fileContents calculateExpectedFiles :: Text -> Options -> [(Text,Text)] calculateExpectedFiles :: Text -> Options -> [(Text, Text)] calculateExpectedFiles Text registry Options options = (Text "shell.nix", Options -> Text generateShellDotNixText Options options) (Text, Text) -> [(Text, Text)] -> [(Text, Text)] forall a. a -> [a] -> [a] : [(Text, Text)] -> (Text -> [(Text, Text)]) -> Maybe Text -> [(Text, Text)] forall b a. b -> (a -> b) -> Maybe a -> b maybe [] ((Text, Text) -> [(Text, Text)] forall a. a -> [a] forall (f :: * -> *) a. Applicative f => a -> f a pure ((Text, Text) -> [(Text, Text)]) -> (Text -> (Text, Text)) -> Text -> [(Text, Text)] forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text "flake.nix",)) (Text -> Options -> Maybe Text generateFlakeText Text registry Options options) actionDescription :: Text -> Text -> Maybe Text -> Text actionDescription :: Text -> Text -> Maybe Text -> Text actionDescription Text fName Text _ Maybe Text Nothing = Text fName Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " does not exist. Creating one" actionDescription Text fName Text a (Just Text b) | Text a Text -> Text -> Bool forall a. Eq a => a -> a -> Bool == Text b = Text "The existing " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text fName Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " is good already" actionDescription Text fName Text _ Maybe Text _ = Text "A " Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text fName Text -> Text -> Text forall a. Semigroup a => a -> a -> a <> Text " exists already. Delete it or move it and try again" returnCode :: Text -> Maybe Text -> ExitCode returnCode :: Text -> Maybe Text -> ExitCode returnCode Text _ Maybe Text Nothing = ExitCode ExitSuccess returnCode Text a (Just Text b) | Text a Text -> Text -> Bool forall a. Eq a => a -> a -> Bool == Text b = ExitCode ExitSuccess returnCode Text _ Maybe Text _ = Int -> ExitCode ExitFailure Int 1 printErrorAndReturnFailure :: Text -> IO b printErrorAndReturnFailure Text err = Text -> IO () printError Text err IO () -> IO b -> IO b forall a b. IO a -> IO b -> IO b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> ExitCode -> IO b forall a. ExitCode -> IO a exitWith (Int -> ExitCode ExitFailure Int 1) printError :: Text -> IO () printError = Handle -> Text -> IO () hPutStrLn Handle stderr