module Shellify (parseOptionsAndCalculateExpectedFiles, runShellify) where import Prelude hiding (writeFile) import Constants import FlakeTemplate import Options import ShellifyTemplate import TemplateGeneration import Control.Monad (when, (>=>)) import Data.Bool (bool) import Data.Text (pack, Text(), unpack) import Data.Text.IO (hPutStrLn, writeFile) import qualified Data.Text.IO as Text import GHC.IO.Exception (ExitCode(ExitSuccess, ExitFailure)) import System.Directory (doesPathExist) import System.Exit (exitWith) import System.IO (stderr) createAFile :: (Text, Text) -> IO () createAFile (Text name, Text content) = do ExitCode extCde <- FilePath -> Text -> IO ExitCode createFile (Text -> FilePath unpack Text name) Text content forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (ExitCode extCde forall a. Eq a => a -> a -> Bool /= ExitCode ExitSuccess) forall a b. (a -> b) -> a -> b $ forall a. ExitCode -> IO a exitWith ExitCode extCde runShellify :: [Text] -> IO () runShellify :: [Text] -> IO () runShellify(Text pName:[Text] args) = IO (Either Text Text) getRegistryDB forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either ((Text -> IO ExitCode printErrorAndReturnFailure forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text "Error calling nix registry: " <>) ) forall (m :: * -> *) a b c. Monad m => (a -> m b) -> (b -> m c) -> a -> m c >=> forall a. ExitCode -> IO a exitWith) (\Text registryDB -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c either Text -> IO () printError (forall (t :: * -> *) (m :: * -> *) a b. (Foldable t, Monad m) => (a -> m b) -> t a -> m () mapM_ (Text, Text) -> IO () createAFile) forall a b. (a -> b) -> a -> b $ Text -> Text -> [Text] -> Either Text [(Text, Text)] parseOptionsAndCalculateExpectedFiles Text registryDB Text pName [Text] args) parseOptionsAndCalculateExpectedFiles :: Text -> Text -> [Text] -> Either Text [(Text,Text)] parseOptionsAndCalculateExpectedFiles :: Text -> Text -> [Text] -> Either Text [(Text, Text)] parseOptionsAndCalculateExpectedFiles Text registry Text programName = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap (\Options opts -> (Text "shell.nix", Options -> Text generateShellDotNixText Options opts) forall a. a -> [a] -> [a] : forall b a. b -> (a -> b) -> Maybe a -> b maybe [] (forall (f :: * -> *) a. Applicative f => a -> f a pure forall b c a. (b -> c) -> (a -> b) -> a -> c . (Text "flake.nix",)) (Text -> Options -> Maybe Text generateFlakeText Text registry Options opts)) forall b c a. (b -> c) -> (a -> b) -> a -> c . Text -> [Text] -> Either Text Options options Text programName createFile :: FilePath -> Text -> IO ExitCode createFile :: FilePath -> Text -> IO ExitCode createFile FilePath fileName Text expectedContents = do Maybe Text fileContents <- FilePath -> IO Bool doesPathExist FilePath fileName forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= forall a. a -> a -> Bool -> a bool (forall (m :: * -> *) a. Monad m => a -> m a return forall a. Maybe a Nothing) (forall a. a -> Maybe a Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> FilePath -> IO Text Text.readFile FilePath fileName) Text -> IO () printError forall a b. (a -> b) -> a -> b $ Text -> Text -> Maybe Text -> Text actionDescription (FilePath -> Text pack FilePath fileName) Text expectedContents Maybe Text fileContents forall (f :: * -> *). Applicative f => Bool -> f () -> f () when (Maybe Text -> Bool shouldGenerateNewFile Maybe Text fileContents) forall a b. (a -> b) -> a -> b $ FilePath -> Text -> IO () writeFile FilePath fileName Text expectedContents forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ Text -> Maybe Text -> ExitCode returnCode Text expectedContents Maybe Text fileContents actionDescription :: Text -> Text -> Maybe Text -> Text actionDescription :: Text -> Text -> Maybe Text -> Text actionDescription Text fName Text _ Maybe Text Nothing = Text fName forall a. Semigroup a => a -> a -> a <> Text " does not exist. Creating one" actionDescription Text fName Text a (Just Text b) | Text a forall a. Eq a => a -> a -> Bool == Text b = Text "The existing " forall a. Semigroup a => a -> a -> a <> Text fName forall a. Semigroup a => a -> a -> a <> Text " is good already" actionDescription Text fName Text _ Maybe Text _ = Text "A " forall a. Semigroup a => a -> a -> a <> Text fName 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 forall a. Eq a => a -> a -> Bool == Text b = ExitCode ExitSuccess returnCode Text _ Maybe Text _ = Int -> ExitCode ExitFailure Int 1 shouldGenerateNewFile :: Maybe Text -> Bool shouldGenerateNewFile :: Maybe Text -> Bool shouldGenerateNewFile = (forall a. Eq a => a -> a -> Bool == forall a. Maybe a Nothing) printErrorAndReturnFailure :: Text -> IO ExitCode printErrorAndReturnFailure Text err = Text -> IO () printError Text err forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall (m :: * -> *) a. Monad m => a -> m a return (Int -> ExitCode ExitFailure Int 1) printError :: Text -> IO () printError = Handle -> Text -> IO () hPutStrLn Handle stderr