Dependency Injection (Props)¶
The Props struct is the "Context Object" of GTB. It acts as a dependency injection container that carries global state, service interfaces, and tool metadata throughout your application's lifecycle.
What's in a Name?
The name Props is not merely a shorthand for 'properties' (though we do shove plenty of those in there). It’s a direct reference to a prop—the heavy-duty timber or steel beam that prevents a structure from an embarrassing collapse. For the sports fans, it’s also a lovingly crafted nod to the rugby position: the broad-shouldered stalwarts who provide the primary structural support for the scrum. Much like its on-field namesake, our Props struct isn't here to score the flashy tries; it's here to do the unsung heavy lifting that keeps the entire framework from falling over.
The Props Struct¶
Defined in pkg/props, the Props object typically contains:
Tool: Metadata about your CLI (Name, Summary, GitHub Org/Repo).Logger: A structured logger (charmbracelet/log) for consistent output.Config: The loaded configuration container.FS: An abstraction of the file system (spf13/afero), allowing for easy mocking.Assets: A manager for embedded filesystem resources.Version: Current build information (Version, Commit, Date).ErrorHandler: A centralized handler for fatal and non-fatal errors.
Why use Props?¶
Instead of using global variables or passing dozens of arguments to every function, you pass the Props object. This provides several key benefits:
- Testability: You can easily swap out the
FSfor an in-memory filesystem or provide a mockLoggerduring tests. - Consistency: Global flags like
--debugautomatically update theLoggerlevel insideProps, ensuring all components behave consistently. - Extensibility: Adding new global services to the framework only requires adding them to the
Propsstruct.
Usage in Commands¶
Every command constructor in GTB accepts *props.Props:
func NewCmdExample(props *props.Props) *cobra.Command {
return &cobra.Command{
Use: "example",
Run: func(cmd *cobra.Command, args []string) {
props.Logger.Info("Hello from Props!")
// Use props.FS to read a file
// Use props.Config to get a value
},
}
}