Skip to content
This repository has been archived by the owner on Aug 1, 2023. It is now read-only.

Configuration

Kristijan Šarić edited this page Aug 1, 2019 · 3 revisions

The configuration is currently located in Cardano.Shell.Constants.Types. It is quite large and contains a large number of parameters (roughly 50).

Of course, not all of them are required, they have defaults.

Defaults have been filled in using a pattern which can be found here - https://medium.com/@jonathangfischoff/the-partial-options-monoid-pattern-31914a71fc67 and was/is used quite heavily in Cabal (https://github.com/haskell/cabal/blob/master/cabal-install/Distribution/Client/ProjectConfig/Types.hs).

The initial values come from the module Presets where we have constants some of which can be empty and they can be overridden or filled in using the CLI found in CLI. There is still an option in between these two using Dhall configuration, but it's still not clear if that is going to be required.

So it currently goes:

Constants <-> CLI

But it could go like this in the future:

Constants <-> Dhall <-> CLI

The use of the pattern

The way we make use of the actual pattern can be seen in a simple example. Say we have this bizarre configuration for one reason or another:

data FullConfiguration = FullConfiguration
    { version   :: !(Last Int)
    , subConfig :: !SubConfiguration
    } deriving (Eq, Show, Semigroup, Monoid)

data SubConfiguration = SubConfiguration
    { first      :: !SubSubConfigurationFirst
    , second     :: !SubSubConfigurationSecond
    } deriving (Eq, Show, Semigroup, Monoid)

data SubSubConfigurationFirst = SubSubConfigurationFirst
    { fooF       :: !(Last Text)
    , barF       :: !(Last Int)
    } deriving (Eq, Show, Semigroup, Monoid)

data SubSubConfigurationSecond = SubSubConfigurationSecond
    { fooS       :: !(Last Text)
    , barS       :: !(Last Int)
    } deriving (Eq, Show, Semigroup, Monoid)

defaultFullConfiguration :: FullConfiguration
defaultFullConfiguration = FullConfiguration
    { version   = pure 15
    , subConfig = 
        SubConfiguration
            { first      =  SubSubConfigurationFirst
                                { fooF       = mempty
                                , barF       = pure 15
                                }
            , second     =  SubSubConfigurationSecond
                                { fooS       = pure "TEXT"
                                , barS       = pure 15
                                }
            }
    }

First of all, you can see that fooF was marked empty and it should be provided (using a CLI or what have you).

The full configuration would look something like:

finalConfiguration :: FullConfiguration
finalConfiguration = defaultFullConfiguration <> cliConfiguration

The defaultFullConfiguration is what we have in the Constants. If you want to have the ability to override the values in the configuration, you need to "mark" only the leaves with the Last constructor (if you imagine the whole thing being a tree). Why?

Well, say we do something like this:

data FullConfiguration = FullConfiguration
    { version   :: !(Last Int)
    , subConfig :: !(Last SubConfiguration)
    } deriving (Eq, Show, Semigroup, Monoid)

data SubConfiguration = SubConfiguration
    { first      :: !(Last Int)
    , second     :: !(Last String)
    } deriving (Eq, Show, Semigroup, Monoid)

Now you cannot simply provide a piece of the configuration for SubConfiguration since the whole branch will be replaced! This is an important bit which people should consider and one of the reasons why I would prefer to have everything flattened out, which avoids this problem (essentially, the problem of thinking more than you need).

Having said that, if you do want to override a piece of the optional configuration, you could use something like this - say you want to override just the first and not the second:

finalConfiguration :: FullConfiguration
finalConfiguration = defaultFullConfiguration <> 
    mempty {
        subConfig = mempty {
            first = pure 10
        }
    }

See here for the example from the codebase - https://github.com/input-output-hk/cardano-node/commit/2efea38f50beb729e718ccda691a770643ac0a48#diff-ba9f0f06843a3a67a21c656d60e82bc8R257