stackbuilders / dotenv-hs

Load environment variables from dotenv files for Haskell
https://hackage.haskell.org/package/dotenv
MIT License
65 stars 14 forks source link

Parse configuration file from current directory for additional flags #197

Open aloussase opened 1 week ago

aloussase commented 1 week ago

This is tackling #160

I added a separate record Flags to hold the flags that can be parsed from a configuration file, tentatively dotenv.config in the current directory.

At first, I tried to reuse the Options record, but this became messy when dealing with the program argument. I could not find a non-hacky way to deal with that and thought that it would be best to have a separate parser for the flags.

Having said that, I extracted the option parsers to separate definitions to reuse as much code as possible and also so that the parsers for flags and options keep in sync.

applyFlags takes care of combining the flags from command line arguments and the configuration file. <> for list arguments is a natural combination, and I believe || for booleans also works correctly.

Some execution examples:

# dotenv.config
-x .env.example
-f .env
# .env.example
API_URL=
# .env

Command:

dotenv echo hello

Output:

dotenv: The following variables are present in .env.example, but not set in the current environment, or .env: API_URL
CallStack (from HasCallStack):
  error, called at src/Configuration/Dotenv.hs:82:16 in dotenv-0.12.0.0-inplace:Configuration.Dotenv

Another example:

# dotenv.config
echo hello

Command:

dotenv echo hello

Output:

There were errors while parsing the configuration file
Invalid argument `echo'

Usage: dotenv [-v|--version] [-f|--dotenv DOTENV] [-x|--example DOTENV_EXAMPLE] 
              [-o|--overload] [--verbose] [--dry-run] [-D|--no-dups]

  Runs PROGRAM after loading options from FILE

I print a special message when errors come from the config file so the user knows where to look.

I might be missing something, what do you think?

Also, I had to add directory as a dependency to check for the file existence, but if there is a better way to do this without adding an extra dependency that would be great.

aloussase commented 5 hours ago

Hi @CristhianMotoche , fixed the CI issue. Let me know if you need anything else :)