-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Dynamic reconfiguration in Haskell
--   
--   Dyre implements dynamic reconfiguration facilities after the style of
--   Xmonad. Dyre aims to be as simple as possible without sacrificing
--   features, and places an emphasis on simplicity of integration with an
--   application. A full introduction with a complete example project can
--   be found in the documentation for Config.Dyre
@package dyre
@version 0.9.2

-- | Defines the Params datatype which Dyre uses to define all
--   program-specific configuration data. Shouldn't be imported directly,
--   as Dyre re-exports it.
module Config.Dyre.Params

-- | This structure is how all kinds of useful data is fed into Dyre. Of
--   course, only the projectName, realMain, and
--   showError fields are really necessary. By using the set of
--   default values provided as newParams, you can get all the
--   benefits of using Dyre to configure your program in only five or six
--   lines of code.
data Params cfgType a
Params :: String -> Bool -> Maybe (IO FilePath) -> Maybe (IO FilePath) -> (cfgType -> IO a) -> (cfgType -> String -> cfgType) -> [FilePath] -> [String] -> [String] -> Bool -> (String -> IO ()) -> RTSOptionHandling -> Bool -> Params cfgType a

-- | The name of the project. This needs to also be the name of the
--   executable, and the name of the configuration file.
[projectName] :: Params cfgType a -> String

-- | Should Dyre look for and attempt to compile custom configurations?
--   Useful for creating program entry points that bypass Dyre's
--   recompilation, for testing purposes.
[configCheck] :: Params cfgType a -> Bool

-- | The directory to look for a configuration file in.
[configDir] :: Params cfgType a -> Maybe (IO FilePath)

-- | The directory to store build files in, including the final generated
--   executable.
[cacheDir] :: Params cfgType a -> Maybe (IO FilePath)

-- | The main function of the program. When Dyre has completed all of its
--   recompilation, it passes the configuration data to this function and
--   gets out of the way.
[realMain] :: Params cfgType a -> cfgType -> IO a

-- | This function is used to display error messages that occur during
--   recompilation, by allowing the program to modify its initial
--   configuration.
[showError] :: Params cfgType a -> cfgType -> String -> cfgType

-- | Optional extra include dirs to use during compilation. To support
--   installation via cabal-install, include the path returned from
--   Paths_<appName>.getLibDir.
[includeDirs] :: Params cfgType a -> [FilePath]

-- | Packages that need to be hidden during compilation
[hidePackages] :: Params cfgType a -> [String]

-- | Miscellaneous GHC compilation settings go here
[ghcOpts] :: Params cfgType a -> [String]

-- | Should GHC be given the -fforce-recomp flag?
[forceRecomp] :: Params cfgType a -> Bool

-- | A status output function. Will be called with messages when Dyre
--   recompiles or launches anything. A good value is 'hPutStrLn stderr',
--   assuming there is no pressing reason to not put messages on stderr.
[statusOut] :: Params cfgType a -> String -> IO ()

-- | Whether to append, or replace GHC runtime system options with others.
[rtsOptsHandling] :: Params cfgType a -> RTSOptionHandling

-- | Whether to add current directory to include list (set False to prevent
--   name shadowing within project directory.) --
[includeCurrentDirectory] :: Params cfgType a -> Bool

-- | Specify additional or replacement GHC runtime system options
data RTSOptionHandling

-- | replaces RTS options with given list
RTSReplace :: [String] -> RTSOptionHandling

-- | merges given list with RTS options from command line (so that nothing
--   is lost)
RTSAppend :: [String] -> RTSOptionHandling

-- | Handling for the command-line options that can be used to configure
--   Dyre. As of the last count, there are four of them, and more are
--   unlikely to be needed. The only one that a user should ever need to
--   use is the --force-reconf option, so the others all begin
--   with --dyre-option-name.
--   
--   At the start of the program, before anything else occurs, the
--   withDyreOptions function is used to hide Dyre's command-line
--   options. They are loaded into the IO monad using the module
--   System.IO.Storage. This keeps them safely out of the way of the
--   user code and our own.
--   
--   Later, when Dyre needs to access the options, it does so through the
--   accessor functions defined here. When it comes time to pass control
--   over to a new binary, it gets an argument list which preserves the
--   important flags with a call to customOptions.
module Config.Dyre.Options

-- | Remove all Dyre's options from the given commandline arguments.
removeDyreOptions :: [String] -> [String]

-- | Store Dyre's command-line options to the IO-Store "dyre", and then
--   execute the provided IO action with all Dyre's options removed from
--   the command-line arguments.
withDyreOptions :: Params c r -> IO a -> IO a

-- | Return the set of options which will be passed to another instance of
--   Dyre. Preserves the master binary, state file, and debug mode flags,
--   but doesn't pass along the forced-recompile flag. Can be passed a set
--   of other arguments to use, or it defaults to using the current
--   arguments when passed Nothing.
customOptions :: Maybe [String] -> IO [String]

-- | Get the value of the --deny-reconf flag, which disables
--   recompilation. This overrides "--force-reconf", too.
getDenyReconf :: IO Bool

-- | Get the value of the --force-reconf flag, which is used to
--   force a recompile of the custom configuration.
getForceReconf :: IO Bool

-- | Get the value of the --dyre-debug flag, which is used to
--   debug a program without installation. Specifically, it forces the
--   application to use .cache as the cache directory, and
--   ./ as the configuration directory.
getDebug :: IO Bool

-- | Get the path to the master binary. This is set to the path of the
--   current binary unless the --dyre-master-binary= flag
--   is set. Obviously, we pass the --dyre-master-binary= flag to
--   the custom configured application from the master binary.
getMasterBinary :: IO (Maybe String)

-- | Get the path to a persistent state file. This is set only when the
--   --dyre-state-persist= flag is passed to the program. It is
--   used internally by Config.Dyre.Relaunch to save and restore
--   state when relaunching the program.
getStatePersist :: IO (Maybe String)

-- | Compatibility code for things that need to be done differently on
--   different systems.
module Config.Dyre.Compat

-- | Called whenever execution needs to be transferred over to a different
--   binary.
customExec :: FilePath -> Maybe [String] -> IO a

-- | What it says on the tin. Gets the current PID as a string. Used to
--   determine the name for the state file during restarts.
getPIDString :: IO String

-- | File paths of interest to Dyre, and related values.
module Config.Dyre.Paths

-- | Data type to make it harder to confuse which path is which.
data PathsConfig
PathsConfig :: FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> PathsConfig
[runningExecutable] :: PathsConfig -> FilePath
[customExecutable] :: PathsConfig -> FilePath

-- | Where Dyre looks for the custom configuration file.
[configFile] :: PathsConfig -> FilePath

-- | configDir/libs. This directory gets added to the GHC
--   include path during compilation, so use configurations can be split up
--   into modules. Changes to files under this directory trigger
--   recompilation.
[libsDirectory] :: PathsConfig -> FilePath

-- | Where the custom executable, object and interface files, errors file
--   and other metadata get stored.
[cacheDirectory] :: PathsConfig -> FilePath

-- | Determine a file name for the compiler to write to, based on the
--   customExecutable path.
outputExecutable :: FilePath -> FilePath

-- | Return a PathsConfig, which records the current binary, the
--   custom binary, the config file, and the cache directory.
getPaths :: Params c r -> IO (FilePath, FilePath, FilePath, FilePath, FilePath)
getPathsConfig :: Params cfg a -> IO PathsConfig

-- | Check if a file exists. If it exists, return Just the modification
--   time. If it doesn't exist, return Nothing.
maybeModTime :: FilePath -> IO (Maybe UTCTime)
checkFilesModified :: PathsConfig -> IO Bool

-- | Recursively find Haskell files (.hs, .lhs) at the
--   given location.
findHaskellFiles :: FilePath -> IO [FilePath]

-- | Compiling the custom executable. The majority of the code actually
--   deals with error handling, and not the compilation itself per
--   se.
module Config.Dyre.Compile

-- | Attempts to compile the configuration file. Will return a string
--   containing any compiler output.
customCompile :: Params cfgType a -> IO ()

-- | Return the path to the error file.
getErrorPath :: Params cfgType a -> IO FilePath

-- | If the error file exists and actually has some contents, return
--   Just the error string. Otherwise return Nothing.
getErrorString :: Params cfgType a -> IO (Maybe String)

-- | Dyre is a library for configuring your Haskell programs. Like Xmonad,
--   programs configured with Dyre will look for a configuration file
--   written in Haskell, which essentially defines a custom program
--   configured exactly as the user wishes it to be. And since the
--   configuration is written in Haskell, the user is free to do anything
--   they might wish in the context of configuring the program.
--   
--   Dyre places emphasis on elegance of operation and ease of integration
--   with existing applications. The wrapMain function is the sole
--   entry point for Dyre. When partially applied with a parameter
--   structure, it wraps around the realMain value from that
--   structure, yielding an almost identical function which has been
--   augmented with dynamic recompilation functionality.
--   
--   The Config.Dyre.Relaunch module provides the ability to restart
--   the program (recompiling if applicable), and persist state across
--   restarts, but it has no impact whatsoever on the rest of the library
--   whether it is used or not.
--   
--   
Writing a program that uses Dyre
--   
--   The following example program uses most of Dyre's major features:
--   
--   
--   -- DyreExample.hs --
--   module DyreExample
--     ( Config(..)
--     , defaultConfig
--     , dyreExample
--     )
--   where
--   
--   import qualified Config.Dyre as Dyre
--   import Config.Dyre.Relaunch
--   
--   import System.IO
--   
--   data Config = Config { message :: String, errorMsg :: Maybe String }
--   data State  = State { bufferLines :: [String] } deriving (Read, Show)
--   
--   defaultConfig :: Config
--   defaultConfig = Config "Dyre Example v0.1" Nothing
--   
--   showError :: Config -> String -> Config
--   showError cfg msg = cfg { errorMsg = Just msg }
--   
--   realMain Config{message = message, errorMsg = errorMsg } = do
--       (State buffer) <- restoreTextState $ State []
--       case errorMsg of
--            Nothing -> return ()
--            Just em -> putStrLn $ "Error: " ++ em
--       putStrLn message
--       traverse putStrLn . reverse $ buffer
--       putStr "> " *> hFlush stdout
--       input <- getLine
--       case input of
--            "exit" -> return ()
--            "quit" -> return ()
--            other  -> relaunchWithTextState (State $ other:buffer) Nothing
--   
--   dyreExample = Dyre.wrapMain $ Dyre.newParams "dyreExample" realMain showError
--   
--   
--   All of the program logic is contained in the DyreExample
--   module. The module exports the Config data type, a
--   defaultConfig, and the dyreExample function which,
--   when applied to a Config, returns an (IO a) value to
--   be used as main.
--   
--   The Main module of the program is trivial. All that is
--   required is to apply dyreExample to the default
--   configuration:
--   
--   
--   -- Main.hs --
--   import DyreExample
--   main = dyreExample defaultConfig
--   
--   
--   
Custom program configuration
--   
--   Users can create a custom configuration file that overrides some or
--   all of the default configuration:
--   
--   
--   -- ~/.config/dyreExample/dyreExample.hs --
--   import DyreExample
--   main = dyreExample $ defaultConfig { message = "Dyre Example v0.1 (Modified)" }
--   
--   
--   When a program that uses Dyre starts, Dyre checks to see if a custom
--   configuration exists. If so, it runs a custom executable. Dyre
--   (re)compiles and caches the custom executable the first time it sees
--   the custom config or whenever the custom config has changed.
--   
--   If a custom configuration grows large, you can extract parts of it
--   into one or more files under lib/. For example:
--   
--   
--   -- ~/.config/dyreExample/dyreExample.hs --
--   import DyreExample
--   import Message
--   main = dyreExample $ defaultConfig { message = Message.msg }
--   
--   
--   
--   -- ~/.config/dyreExample/lib/Message.hs --
--   module Message where
--   msg = "Dyre Example v0.1 (Modified)"
--   
--   
--   
Working with the Cabal store
--   
--   For a Dyre-enabled program to work when installed via cabal
--   install, it needs to add its library directory as an extra
--   include directory for compilation. The library package name
--   must match the Dyre projectName for this to work. For
--   example:
--   
--   
--   import Paths_dyreExample (getLibDir)
--   
--   dyreExample cfg = do
--     libdir <- getLibDir
--     let params = (Dyre.newParams "dyreExample" realMain showError)
--           { Dyre.includeDirs = [libdir] }
--     Dyre.wrapMain params cfg
--   
--   
--   See also the Cabal Paths_pkgname feature documentation.
--   
--   
Specifying the compiler
--   
--   If the compiler that Dyre should use is not available as ghc,
--   set the HC environment variable when running the main
--   program:
--   
--   
--   export HC=/opt/ghc/$GHC_VERSION/bin/ghc
--   dyreExample  # Dyre will use $HC for recompilation
--   
--   
--   
Configuring Dyre
--   
--   Program authors configure Dyre using the Params type. This type
--   controls Dyre's behaviour, not the main program logic (the example
--   uses the Config type for that).
--   
--   Use newParams to construct a Params value. The three
--   arguments are:
--   
--   
--   
- Application name (a String). This affects the
--   names of files and directories that Dyre uses for config, cache and
--   logging.
--   
- The real main function of the program, which has type
--   (cfgType -> IO a). cfgType is the main program
--   config type, and a is usually ().
--   
- The show error function, which has type (cfgType ->
--   String -> cfgType). If compiling the custom program fails,
--   Dyre uses this function to set the compiler output in the main
--   program's configuration. The main program can then display the error
--   string to the user, or handle it however the author sees fit.
--   
--   
--   The Params type has several other fields for modifying Dyre's
--   behaviour. newParams uses reasonable defaults, but behaviours
--   you can change include:
--   
--   
--   
- Where to look for custom configuration (configDir). By
--   default Dyre will look for
--   $XDG_CONFIG_HOME/<appName>/<appName>.hs,
--   
- Where to cache the custom executable and other files
--   (cacheDir). By default Dyre will use
--   $XDG_CACHE_HOME/<appName>/.
--   
- Extra options to pass to GHC when compiling the custom executable
--   (ghcOpts). Default: none.
--   
--   
--   See Params for descriptions of all the fields.
module Config.Dyre

-- | wrapMain is how Dyre receives control of the program. It is
--   expected that it will be partially applied with its parameters to
--   yield a main entry point, which will then be called by the
--   main function, as well as by any custom configurations.
--   
--   wrapMain returns whatever value is returned by the
--   realMain function in the params (if it returns at
--   all). In the common case this is () but you can use Dyre with
--   any IO action.
wrapMain :: Params cfgType a -> cfgType -> IO a

-- | This structure is how all kinds of useful data is fed into Dyre. Of
--   course, only the projectName, realMain, and
--   showError fields are really necessary. By using the set of
--   default values provided as newParams, you can get all the
--   benefits of using Dyre to configure your program in only five or six
--   lines of code.
data Params cfgType a
Params :: String -> Bool -> Maybe (IO FilePath) -> Maybe (IO FilePath) -> (cfgType -> IO a) -> (cfgType -> String -> cfgType) -> [FilePath] -> [String] -> [String] -> Bool -> (String -> IO ()) -> RTSOptionHandling -> Bool -> Params cfgType a

-- | The name of the project. This needs to also be the name of the
--   executable, and the name of the configuration file.
[projectName] :: Params cfgType a -> String

-- | Should Dyre look for and attempt to compile custom configurations?
--   Useful for creating program entry points that bypass Dyre's
--   recompilation, for testing purposes.
[configCheck] :: Params cfgType a -> Bool

-- | The directory to look for a configuration file in.
[configDir] :: Params cfgType a -> Maybe (IO FilePath)

-- | The directory to store build files in, including the final generated
--   executable.
[cacheDir] :: Params cfgType a -> Maybe (IO FilePath)

-- | The main function of the program. When Dyre has completed all of its
--   recompilation, it passes the configuration data to this function and
--   gets out of the way.
[realMain] :: Params cfgType a -> cfgType -> IO a

-- | This function is used to display error messages that occur during
--   recompilation, by allowing the program to modify its initial
--   configuration.
[showError] :: Params cfgType a -> cfgType -> String -> cfgType

-- | Optional extra include dirs to use during compilation. To support
--   installation via cabal-install, include the path returned from
--   Paths_<appName>.getLibDir.
[includeDirs] :: Params cfgType a -> [FilePath]

-- | Packages that need to be hidden during compilation
[hidePackages] :: Params cfgType a -> [String]

-- | Miscellaneous GHC compilation settings go here
[ghcOpts] :: Params cfgType a -> [String]

-- | Should GHC be given the -fforce-recomp flag?
[forceRecomp] :: Params cfgType a -> Bool

-- | A status output function. Will be called with messages when Dyre
--   recompiles or launches anything. A good value is 'hPutStrLn stderr',
--   assuming there is no pressing reason to not put messages on stderr.
[statusOut] :: Params cfgType a -> String -> IO ()

-- | Whether to append, or replace GHC runtime system options with others.
[rtsOptsHandling] :: Params cfgType a -> RTSOptionHandling

-- | Whether to add current directory to include list (set False to prevent
--   name shadowing within project directory.) --
[includeCurrentDirectory] :: Params cfgType a -> Bool

-- | Construct a Params with the required values as given, and
--   reasonable defaults for everything else.
newParams :: String -> (cfg -> IO a) -> (cfg -> String -> cfg) -> Params cfg a

-- | A set of reasonable defaults for configuring Dyre. The fields that
--   have to be filled are projectName, realMain, and
--   showError (because their initial value is undefined).
--   
--   Deprecated in favour of newParams which takes the required
--   fields as arguments.

-- | Deprecated: Use newParams instead
defaultParams :: Params cfgType a

-- | This is the only other module aside from Config.Dyre which
--   needs to be imported specially. It contains functions for restarting
--   the program (which, usefully, will cause a recompile if the config has
--   been changed), as well as saving and restoring state across said
--   restarts.
--   
--   The impossibly simple function arguments are a consequence of a little
--   cheating we do using the System.IO.Storage library. Of course,
--   we can't use the stored data unless something else put it there, so
--   this module will probably explode horribly if used outside of a
--   program whose recompilation is managed by Dyre.
--   
--   The functions for saving and loading state come in two variants: one
--   which uses the Read and Show typeclasses, and one which
--   uses Data.Binary to serialize it. The Read and
--   Show versions are much easier to use thanks to automatic
--   deriving, but the binary versions offer more control over saving and
--   loading, as well as probably being a bit faster.
module Config.Dyre.Relaunch

-- | Just relaunch the master binary. We don't have any important state to
--   worry about. (Or, like when relaunchWith<X>State calls
--   it, we're managing state on our own). It takes an argument which can
--   optionally specify a new set of arguments. If it is given a value of
--   Nothing, the current value of getArgs will be used.
relaunchMaster :: Maybe [String] -> IO ()

-- | Relaunch the master binary, but first preserve the program state so
--   that we can use the restoreTextState functions to get it back
--   again later.
relaunchWithTextState :: Show a => a -> Maybe [String] -> IO ()

-- | Serialize the state for later restoration with
--   restoreBinaryState, and then relaunch the master binary.
relaunchWithBinaryState :: Binary a => a -> Maybe [String] -> IO ()

-- | Serialize a state as text, for later loading with the
--   restoreTextState function.
saveTextState :: Show a => a -> IO ()

-- | Serialize a state as binary data, for later loading with the
--   restoreBinaryState function.
saveBinaryState :: Binary a => a -> IO ()

-- | Restore state which has been serialized through the
--   saveTextState function. Takes a default which is returned if
--   the state doesn't exist.
restoreTextState :: Read a => a -> IO a

-- | Restore state which has been serialized through the
--   saveBinaryState function. Takes a default which is returned if
--   the state doesn't exist.
restoreBinaryState :: Binary a => a -> IO a
