Open SamuelMarks opened 1 year ago
The approach I'm hoping to take to enable this is the one from #197. Need to get that PR up to date with all recent changes to this repo, and finish a few things before publishing it as "github.com/alexflint/go-arg/v2"
Heya Alex!
I've been doing a little exploration of the command-line parsing libraries in golang... I'm currently using urfave/cli for https://github.com/purpleidea/mgmt/ ... I've noticed their new "v3" API is generics ridden and really clunky. I thought there must be a better way... I found this project...
...And I think the "struct populating" approach is excellent and very close to what I was looking for!
My two main concerns were:
I'd actually love to be more involved, but I'm fairly busy working on https://github.com/purpleidea/mgmt/ so, I don't expect too many hours.
In any case, I just figured I'd check in, say that I like what you've been doing, and in case you're still hacking at your monastery, please keep it up!
Cheers
@SamuelMarks -- if you're hacking on adding your config work into core or helping with Alex's v2 approach and need a hand, please LMK.
@purpleidea Actually after my #RewriteInRust I decided to #RewriteInC
Thanks for the note @purpleidea. Care to jump on a call some time to say hi / chat? Any chance you're free at 3pm US Eastern time one day this week?
@SamuelMarks would be great to meet you face-to-face at some point, too, though I know you're busy!
Good idea! Send me an invite: my name at gmail.com
@alexflint
Thanks for the note @purpleidea. Care to jump on a call some time to say hi / chat? Any chance you're free at 3pm US Eastern time one day this week?
Sure! I'm free either today or tomorrow at that time, otherwise TBD. Send me your preferred meeting thing, I've got signal, jitsi, gmeet or anything that works in a web browser. my username at gmail. Cheers!
I've been thinking about how to pull values from config file into go-arg. Here's what I've come up with.
1) It's silly to directly support json, yaml, toml, etc, etc, since someone will always be missing what they want.
2) Instead, we should have a new struct tag. Let's pretend it's called file
. You specify the "key" that you want to use.
3) In the parser, we have the ability for the user to pass in a function of the signature:
func(ctx context string key) (*string, error)
When the library is looking for a value to use, it calls that function with the key from the struct. If it gets a value back, it passes it through the usual parsing that we use for the default
tag. If it has an issue pulling a value (io error or whatever) we error. If it doesn't find a value then we return nil, nil.
That way everyone can have their own parser. And of course if we really want to, we can add one or two common ones as a util package.
HTH
In the next little while, I'd really like to be able to do this for https://github.com/purpleidea/mgmt/ ... I've landed all my new CLI patches, and they look great! Mostly here: https://github.com/purpleidea/mgmt/commit/589a5f9aeb5663b3e00107f3ae8a311903c20298
But also to show how other code then simplifies, look at:
https://github.com/purpleidea/mgmt/commit/d537c3d523c202e81895d6cad0ca512f6a6f1ee5 https://github.com/purpleidea/mgmt/commit/601fcf40c4b0150f0545e453d8c149c2a854f7b1 https://github.com/purpleidea/mgmt/commit/51d21b8dab99e0b30a7fff0496064055683891e8 https://github.com/purpleidea/mgmt/commit/9527d0dcbdfc9919a0fd5db1440c95b2128dd231
It's really an improvement! Thanks Alex for this great library!
So instead of bolting config file reading onto mgmt, I'd rather bolt it onto this go-arg lib where it belongs. I would send a patch, but if that would conflict with your v2 patch, then maybe that generates more work for you which I don't want to do if you're not up for it. This patch also wouldn't need a v2 API change, so I think it's safe to add in before it.
I also don't know how receptive to this idea you are and how many cycles you have to review and merge this.
So please let me know how you'd like me to proceed.
Thanks again!
I needed a quick way to support config through a file and just used an ".env" file approach and env variables. To make this an easy add I just hacked the ".env" variables into my program using some simple load. Here is the initial code I generated using claude.ai, because I was feeling very lazy.
package main
import (
"bufio"
"os"
"strings"
)
func init() {
loadEnv()
}
func loadEnv() {
file, err := os.Open(".env")
if err != nil {
// Silently ignore if the file doesn't exist
return
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if equal := strings.Index(line, "="); equal >= 0 {
if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
value := ""
if len(line) > equal {
value = strings.TrimSpace(line[equal+1:])
}
os.Setenv(key, value)
}
}
}
}
func main() {
var args struct {
Server string `arg:"env:GITEA_SERVER" default:"localhost:3000" help:"gitea server address"`
UserName string `arg:"required,env:GITEA_USERNAME" help:"gitea user name"`
Password string `arg:"required,env:GITEA_PASSWORD" help:"gitea password"`
}
arg.MustParse(&args)
// Your program logic here
}
I added config file support to my go-arg using project but due to #94 I could not determine when to read the config.
My project hacks support with the builtin json package. Specifically here: https://github.com/offscale/postgres-version-manager-go/blob/master/pvm/config_utils.go (with go-arg annotated
struct
here: config.go)Any chance we can get support for a configuration file in your project directly?
Thanks
EDIT: Got it working in my latest commit
48cba8
but it was a major hack; here's a taste [from that commit]:Issues with this design include: