digitallyinduced/ihp

Implement `instance EnvVarReader PortNumber` for esier config

amitaibu opened this issue · 0 comments

Dumping Config.hs code here, and later I'll move code to core, and add the docs.

-- Config/Config.hs

import IHP.EnvVar

-- @todo: Move to IHP core
import Network.Socket (PortNumber)
import Data.Word (Word16)

config :: ConfigBuilder
config = do
    -- See https://ihp.digitallyinduced.com/Guide/config.html
    -- for what you can do here
    option customTailwind

    envName :: Maybe Text <- envOrNothing "ENV_NAME"

    case envName of
        Just "qa" -> initS3Storage "eu-west-1" "your-s3-storage"
        -- Static directory.
        _ -> initStaticDirStorage

    smtpHost <- env @Text "SMTP_HOST"
    smtpPort <- env @PortNumber "SMTP_PORT"
    smtpUserMaybe <- envOrNothing "SMTP_USER"
    smtpPasswordMaybe <- envOrNothing "SMTP_PASSWORD"

    -- Determine if credentials are available and set SMTP configuration accordingly.
    let (smtpCredentials, smtpEncryption) = case (smtpUserMaybe, smtpPasswordMaybe) of
            (Just user, Just password) -> (Just (user, password), STARTTLS)
            _ -> (Nothing, Unencrypted)

    liftIO $ putStrLn $ "SMTP HOST: " <> show smtpHost
    liftIO $ putStrLn $ "SMTP PORT: " <> show smtpPort

    -- SMTP to work with MailHog or other SMTP services.
    option $
        SMTP
            { host = cs smtpHost
            , port = smtpPort
            , credentials = smtpCredentials
            , encryption = smtpEncryption
            }

instance EnvVarReader PortNumber where
    envStringToValue string = case textToInt (cs string) of
        Just integer -> Right $ convertIntToPortNumber integer
        Nothing -> Left "Got a String instead of an Int for PortNumber."

convertIntToPortNumber :: Int -> PortNumber
convertIntToPortNumber int = fromIntegral (int :: Int) :: PortNumber

On .envrc

# Add your env vars here

export SMTP_HOST="127.0.0.1" # On some computers may need `127.0.1.1` instead.
export SMTP_PORT="1025"

And on flake.nix we have

                        services.ihp = {
                            domain = "...";
                            migrations = ./Application/Migration;
                            schema = ./Application/Schema.sql;
                            fixtures = ./Application/Fixtures.sql;
                            sessionSecret = "...";
                            additionalEnvVars = {
                                SMTP_HOST = "email-smtp.eu-west-1.amazonaws.com";
                                SMTP_PORT = "587";
                                SMTP_USER = "your-user-name";
                                SMTP_PASSWORD = "your-password";
                                ENV_NAME = "qa";
                                AWS_ACCESS_KEY_ID = "your key ID";
                                AWS_SECRET_ACCESS_KEY = "your secret";
                            };
                        };