-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add .env file support #66
Conversation
Ah, cool! Let me give this a closer review. Are there existing env file format parsers in Go that I can review as a comparison? |
Maybe in docker as the v3+ compose file must be parsed by it to execute in a docker swarm environment. Otherwise, the logic is in the docker-compose tool that is only in python. Otherwise I found this one: https://github.com/joho/godotenv |
ffenv/env.go
Outdated
index = strings.IndexRune(line, '=') | ||
) | ||
if index < 0 { | ||
name, value = line, "true" // boolean option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in this parser we don't want to interpret lines of the form
FOO_BAR
as setting boolean flags to true. I think they should probably be errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's fair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is fixed in 23a2085
ffenv/env.go
Outdated
name, value = line, "true" // boolean option | ||
} else { | ||
name, value = strings.ToLower(line[:index]), line[index+1:] | ||
name = strings.ReplaceAll(name, "_", "-") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a given that a _
in an env var should match to only a -
in a flag name. Quoting from the docs
Flag names are matched to environment variables by capitalizing the flag name, and replacing separator characters like periods or hyphens with underscores.
We would need the same kind of matching behavior here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for each separator in []string{"-", ".", "/"}
, I should check that a flag exist with that format, or should I set it for each separator?
So given: MY_FOO_LISTEN_ADDR=value
with prefix MY_FOO
, I should set listen.addr
, listen-addr
and listen/addr
, hoping there is one corresponding, and there is no conflict either.
Or iterate through existing flags (how in this context?) and do the other way around (like in the ff.Parse func)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the correct implementation is, my point is that the behavior here should try to be consistent with env vars specified directly. If you're stuck, let me know, and I can dig in to the details and make a more direct suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went on the path where the option needs a flag.FlagSet
passed, so it can match with the env var.
Concerning #69 , when the env var from a .env file is applied, it will apply itself on every flag.
So, FOO_VAR
will get applied to -foo_var
, -foo-var
, -foo.var
and -foo/var
. When using purely the flags, it can determine exactly which to update.
The updated code has been pushed in the branch now.
fftest/vars.go
Outdated
S string | ||
S_S string | ||
SDotS string | ||
SDashS string | ||
SSlashS string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please find a way to test these corner cases of env files without modifying fftest.Vars.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added them in their own local struct and removed reference to them in other part of the module.
Co-authored-by: Peter Bourgon <[email protected]>
I'm interested in seeing this PR resolved, however, after looking at the code I'm curious why PlainParser and EnvParser aren't just merged since I am (mostly) using PlainParser to parse .env files with a couple small tweaks. Original: Lines 231 to 268 in 556df77
|
Looks like the main tweak is swapping |
@peterbourgon yes, you have to exclude the '=' ( Here's a full demo example: https://gist.github.com/Xeoncross/707ee4a6a7fff8b73baa74a1071c382e In fact, I didn't like having all that duplicate code so I just made a wasteful wrapper that reads the whole massive 200-500 byte .env file stream into memory, removes the equals signs, then feeds it to ff.PlainParser.
|
Hi,
|
Yes, I'd rather see proper env config parsing, but I construct the DSN in-app and don't have any other URL params in the config and if I did I'd just use the first function so either of these two methods works for now until this PR or some related one gets merged. |
I explicitly wanted a config file format whose keys were tokenized with spaces, so the PlainParser would have existed in any case. But to be honest I hadn't ever heard of the env file format until people started bringing it up in issues on this repo. Ignorance! 😇 I'll add support for env files shortly. @xeoncross is your "proper" link a good canonical parser? I'll use it as a reference for a local implementation, if so. |
What was missing from this PR to be merged, actually? I thought I dealt with every comments/suggestions. |
@dolanor Lots of stuff :\ ConfigFileParsers don't get access to the flag set, and certainly can't mutate it. You're re-implementing env var name logic rather than reusing it. Using break labels in loops. Other stuff. No big deal, I'm planning on adding support. Thanks for the contribution in any case! 👍 |
Quick update for search results, I still prefer spinning up new services using ff over cobra given the lighter weight codebase, simpler setup, and easier auditability. However, since ff doesn't support environment files (which are commonly used with docker or local dev) an easy workaround is to also use the github.com/joho/godotenv package which you can setup yourself, or just use the default, 1-line autoloader.
Once godotenv loads everything into os.Env, then ff picks it up. |
Fixed by #89. @xeoncross, @dolanor — if you get a chance can you test out the RC I'm about to publish? |
Hi,
Given that I use Docker quite a lot when coding, I also use the .env file to pass configuration to the docker-compose.
But given the speed of
go run
compared todocker-compose up -d --build
, I want to test more with the former.So here is the package that helps me do that without sourcing the
.env
file in my shell (and mostly, forgetting about re-sourcing it).So now, running the app with a
docker-compose up -d --build
orgo run
does not require another workflow.It is a copy paste from the
ff.PlainParser
that use=
as the key/value split.It also has an optional parser that accepts a prefix as the
.env
often has the variable with prefix to avoid conflicts with other services, as in env variables. I'm not sure it's the best way to do it, but I thought it was maybe the less intrusive since it's quite specific to the handling of.env
files. I'm open to suggestions.