Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fumieval/evp
Enviroment Variable Parser
https://github.com/fumieval/evp
Last synced: 23 days ago
JSON representation
Enviroment Variable Parser
- Host: GitHub
- URL: https://github.com/fumieval/evp
- Owner: fumieval
- License: other
- Created: 2023-09-12T06:35:18.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2023-11-30T05:15:20.000Z (about 1 year ago)
- Last Synced: 2024-11-16T23:06:30.518Z (about 1 month ago)
- Language: Haskell
- Size: 23.4 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
EVP: Environment Variable Parser
====EVP is a simple environment parser which focues on these three aspects:
* Ease of use: no complicated machinery is needed
* Observability: for each environment variable, EVP logs the parsed value or an error. An error does not interrupt the parsing process and it checks all the variables exhaustively.
* Composability: environment parsers can be composed via the Applicative structure.Example
----The following code is a complete example demonstrating how to use EVP:
```haskell
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE OverloadedStrings #-}import EVP qualified
main :: IO ()
main = EVP.scan parser-- ApplicativeDo is important here because Scan is not a monad.
parser :: EVP.Scan ()
parser = do
-- @secret@ masks the parsed value
_token <- EVP.secret $ EVP.string "API_TOKEN"
-- parse the environment variable as a YAML value
_port <- EVP.yaml "HTTP_PORT"
-- obtain the environment variable as is
_foo <- EVP.string "FOO"
-- you can also provide a default value
_debug <- EVP.yaml $ "DEBUG_MODE" `EVP.defaultsTo` False
pure ()
```Running this code produces the following output.
```
[EVP Info] API_TOKEN:
[EVP Info] HTTP_PORT: 8080
[EVP Info] FOO: foo
[EVP Info] DEBUG_MODE: False (default)
```Revealing unused variables
----EVP has a mechanism to detect unused variables.
If your application's environment variables has a common prefix `MYAPP_`, you can set `assumePrefix` as a `unusedLogger`.
```haskell
EVP.scanWith EVP.def
{ EVP.unusedLogger = EVP.assumePrefix "MYAPP_" }
parser
```If an environment variable prefixed by `MYAPP_` is set but not referred to, EVP prints the following warning. This is useful for detecting typos too.
```
[EVP Warn] MYAPP_OBSOLETE_FLAG is set but not used
```Alternatively, you can also name unwanted variables individually:
```haskell
EVP.scanWith EVP.def
{ EVP.unusedLogger = EVP.obsolete ["OBSOLETE_VAR"] }
```These can be combined using the `Semigroup` instance.
```haskell
EVP.scanWith EVP.def
{ EVP.unusedLogger = EVP.assumePrefix "MYAPP_" <> EVP.obsolete ["OBSOLETE_VAR"] }
parser
```Parser group
----You can provide an additional context to a parser by applying `group "group name"`.
Group names appear in the log messages:```
[EVP Info] DEBUG_MODE: False (default)
[EVP Info/MySQL] MYSQL_HOST: localhost
[EVP Info/MySQL] MYSQL_PASSWORD:
[EVP Error/MySQL] Failed to parse MYSQL_PORT=blah: Aeson exception:
[EVP Error/MySQL] Error in $: parsing Int failed, expected Number, but encountered String
```Design context
----* If `Scan` were a monad, the parsing process would be non-deterministic. This might cause a burden when there are two or more problems in the environment variables, because it is not possible to reveal all problems in a non-deterministic context.
* It is recommended to avoid falling back to default values expect for debugging features. If the application configuration has an error such as a typo, it is much safer to exit than launching anyway with a default value.