Currently the root.go file where the root command is created needs to import the packages for all the sub-commands that are created. This makes that file a cyclic dependency hog. I moved it to a solo package called core. There may be ways to solve this w/o a solo package by passing factory functions. As @rhuss mentions below.
Need to investigate if possible and do this refactor.
@maximilien The decoupling works nicely, just as a comment for another approach which might be useful, too, would be to reverse the direction of the commands registration (i.e. letting sub-commands register themselves). It's more a syntactic thing, and I think it can also break dep cycles more easily (maybe even without the introduction of third common package for the KnParams definition).
That's the idea (not fully tested):
package commands
// That unnamed import is crucial here
import _ cmd_service
typ KnParams struct {
// ...
}
var SubCommandFactories = make([]func(*KnParams) *cobra.Command,0)
func NewKnCommand(params ...common.KnParams) *cobra.Command {
for _, fact := range SubCommandFactories {
rootCmd.AddCommand(fact.newCommand(p))
}
}
package cmd_service
import commands
func init() {
commands.SubCommandFactories = append(commands.SubCommandFactories, newServiceCreateFactor)
}
func newServiceCreateFactory(p *commands.KnParams) *cobra.Command {
////
}
You then can easily add new commands by adding an unnamed import which is used to call its init() method.
I've seen that pattern in the wild quite a bit (I darkly remember its used also for collecting k8s resource schemes), so might make sense here, too.
Originally posted by @rhuss in #145 (comment)
Currently the
root.gofile where the root command is created needs to import the packages for all the sub-commands that are created. This makes that file a cyclic dependency hog. I moved it to a solo package calledcore. There may be ways to solve this w/o a solo package by passing factory functions. As @rhuss mentions below.Need to investigate if possible and do this refactor.
@maximilien The decoupling works nicely, just as a comment for another approach which might be useful, too, would be to reverse the direction of the commands registration (i.e. letting sub-commands register themselves). It's more a syntactic thing, and I think it can also break dep cycles more easily (maybe even without the introduction of third
commonpackage for theKnParamsdefinition).That's the idea (not fully tested):
You then can easily add new commands by adding an unnamed import which is used to call its init() method.
I've seen that pattern in the wild quite a bit (I darkly remember its used also for collecting k8s resource schemes), so might make sense here, too.
Originally posted by @rhuss in #145 (comment)