Closed Ilyes512 closed 5 years ago
Hey @Ilyes512 - thanks for using flaggy!
I think its entirely up to users as to how they structure their flag commands. However, as a personal example, here is how I use flaggy in one of my programs. This function is executed from my init()
.
func setupFlaggy() {
// setup basic app settings
flaggy.SetName("ContainerCron.com CLI Client")
flaggy.SetVersion("0.0.0")
flaggy.SetDescription("The official CLI interface for ContainerCron.com")
flaggy.DefaultParser.AdditionalHelpAppend = `
Environment Variables:
CCRON_SERVER: The API server URL to use.
`
// debug mode option
flaggy.Bool(&debug, "", "debug", "Enable debug output")
// set a different server url
flaggy.String(&serverAPIURL, "", "server", "Specify a different server URL")
// flaggy.DefaultParser.Flags[len(flaggy.DefaultParser.Flags)-1].Hidden = true
// TODO - imageSecret flag
// TODO - server flag (target cc-server server to connect to)
// CREATE
// ccron create hellodocker '* * * * *' -- pass-in --arguments -h
createCmd = flaggy.NewSubcommand("create")
createCmd.Description = "Creates cron jobs."
createCmd.AdditionalHelpAppend = `
Set the schedule using single quotes:
'* * * * *'
Set the arguments for your container's run by using the -- delimiter:
ccron create busybox '* * * * *' -- ls -al
`
createCmd.AddPositionalValue(&imageURL, "imageURL", 1, true, "The URL of the container to run")
createCmd.AddPositionalValue(&schedule, "schedule", 2, true, "The schedule to run the container on. Use single quotes: '* * * * *'")
flaggy.AttachSubcommand(createCmd, 1)
// LIST
// ccron list
listCmd = flaggy.NewSubcommand("list")
listCmd.Description = "Lists active cron jobs."
listCmd.AdditionalHelpAppend = ``
flaggy.AttachSubcommand(listCmd, 1)
// DELETE
// ccron delete jobID
deleteCmd = flaggy.NewSubcommand("delete")
deleteCmd.Description = "Deletes cron jobs."
deleteCmd.AddPositionalValue(&cronjobID, "jobID", 1, true, "The ID of the cron job to delete")
flaggy.AttachSubcommand(deleteCmd, 1)
// parse the user inputs and return any errors
flaggy.Parse()
}
I prefer to do things one step at a time, so it's easy to read. I go through each subcommand, create it, assign properties, then attach it to the right place. If a subcommand also has subcommands, I do those right after I setup the parent subcommand.
Then, in the main of my program, I check which subcommand has been used and execute the right function. This can't be any shorter than a switch on the .Used
properties of the subcommands. I prefer not to pass in functions to be run because that assumes too much, and the function would have to conform to some interface, which I think makes messier programs.
It is idiomatic to simply use a switch to determine which subcommand was used:
switch {
case createCmd.Used:
runCronJobCreate()
case listCmd.Used:
runCronJobList()
case deleteCmd.Used:
runCronJobDelete()
default:
flaggy.ShowHelpAndExit("Invalid command")
}
Does that help?
I like what I see except I don't know how to actually structure you app.
For instance... let's imagine I have an app with 5 command that each have there own (3?) subcommands.
I would like to have a single file per command. How would I nicely call the different modules without having allot of
if statements like
if subcommand.Used`.