cli icon indicating copy to clipboard operation
cli copied to clipboard

Autodetect config format based on extension

Open danhunsaker opened this issue 2 years ago • 10 comments

What type of PR is this?

  • feature

What this PR does / why we need it:

  • Allows use of DetectNewSourceFromFlagFunc(flag) to support configs in more than one format for a single application, by autodetecting which format to parse with according to the config file's extension.
  • Allows registration of third-party New*SourceFromFlagFunc() functions to new file extensions for support by the autodetector.
  • Preregisters the three built-in parsers as follows:
    • .yamlNewYamlSourceFromFlagFunc
    • .ymlNewYamlSourceFromFlagFunc
    • .jsonNewJSONSourceFromFlagFunc
    • .tomlNewTomlSourceFromFlagFunc
    • .confNewTomlSourceFromFlagFunc

Testing

  • set up a new CLI project using the following (or similar) configuration:
main.go
func main() {
	app := cli.NewApp()
	app.Name = "dynamic-config"
	app.Version = "0.1.0"
	app.Description = "Showcases how to use the DetectNewSourceFromFlagFunc feature"
	
	app.Authors = []*cli.Author{
		{Name: "Hennik Hunsaker", Email: "[email protected]"},
	}
	
	app.Flags = []cli.Flag{
		altsrc.NewIntFlag(&cli.IntFlag{
			Name:      "number",
			Aliases:   []string{"n"},
			Usage:     "the `answer` to spit out",
			Value:     42,
		}),
		&cli.PathFlag{
			Name:      "config",
			Aliases:   []string{"c"},
			Usage:     "specify the configuration `file` to use",
			Value:     "oa2s.conf",
			TakesFile: true,
		},
	}

	app.AddExtension(altsrc.NewDetectableSourcesAppExtension())

	app.Before = altsrc.InitInputSourceWithContext(app.Flags, altsrc.DetectNewSourceFromFlagFunc("config"))
	
	app.Action = func(c *cli.Context) error {
		fmt.Printf("The answer is %d", c.Int("number"))
		return nil
	}
	
	_ = app.Run(os.Args)
}
  • Create the following config files to test against:
config.yaml
number: 43
config.json
{"number": 44}
config.toml
number = 45
config.conf
number = 46
config.yml
number: 47
  • Try the code using a terminal or console:
go run main.go
go run main.go -- --config config.yaml
go run main.go -- --config config.json
go run main.go -- --config config.toml
go run main.go -- --config config.conf
go run main.go -- --config config.yml
  • Compare the results with the following outputs:
The answer is 42
The answer is 43
The answer is 44
The answer is 45
The answer is 46
The answer is 47

Release Notes

Added support to detect the configuration file format from its extension, rather than predefine it in the code.

danhunsaker avatar Mar 15 '23 00:03 danhunsaker

Should add .yml aswell for yaml

skelouse avatar Mar 15 '23 01:03 skelouse

Should add .yml aswell for yaml

Done!

danhunsaker avatar Mar 15 '23 07:03 danhunsaker

Now to add the new tests.

danhunsaker avatar Mar 15 '23 20:03 danhunsaker

Ahh circular dependencies... Moving the InputSourceContext interface to cli is a backwards compatibility issue. I'm not sure how used it is, maybe someone else can provide some insight. @urfave/cli

I put some time into it, and I'm not sure how it could be done differently. Maybe you have other ideas if the compatibility is an issue @danhunsaker

skelouse avatar Mar 17 '23 18:03 skelouse

If Go offered a way to attach objects to other objects without defining an explicit name first...

Though maybe we could add something more generic for myriad extensions to use... 🤔

danhunsaker avatar Mar 18 '23 22:03 danhunsaker

@danhunsaker v2 is only in maintenance mode right now. No new features/capabilities. Can you do this PR for v3/main ?

dearchap avatar Mar 19 '23 00:03 dearchap

Sure, once v3 is actually out of alpha and into a real release. I can't use/test it until then.

Also, I don't see support for InputSourceContexts (or their equivalent) on v3 in the first place, meaning I'd have to reimplement all of that as well.

danhunsaker avatar Mar 19 '23 00:03 danhunsaker

v3 is the mainline branch. Alpha will be out soon. altsrc has been moved into its own repo for v3 since it is ancillary to cli and not a core.

dearchap avatar Mar 19 '23 23:03 dearchap

There's nothing anywhere pointing it out, so I didn't know there was a separate repository. I'll see what I can do with that.

danhunsaker avatar Mar 20 '23 00:03 danhunsaker

@danhunsaker Thanks for your patience! The transitional state of the ./altsrc ➡️ altsrc move is definitely awkward. Sorry about that! I would love to see this new feature land over there if possible. If you're interested in moving the "altsrc" concepts forward like this, we could really use the help 🙇🏼

meatballhat avatar May 01 '23 12:05 meatballhat

Closing as per the comments above. v2 is in maintenance mode and we don't accept new features for it.

Thank you for the contribution, and if possible, please submit it to https://github.com/urfave/cli-altsrc

bartekpacia avatar May 01 '24 00:05 bartekpacia