A flexible and extensible plugin system for Go applications built with modern Go idioms.
- ๐ฏ Type-safe plugin discovery using Go generics
- ๐ Extensible interfaces for specialized plugin behavior
- ๐๏ธ Builder pattern support for complex configurations
- ๐ Structured logging with slog integration
- ๐ Runtime availability checking for plugins
- โก Performance optimized with modern slice operations
- ๐งช Comprehensive test coverage with benchmarks
package main
import (
"fmt"
"github.com/markbates/plugins"
)
// Define your plugin
type MyPlugin struct {
name string
}
func (p MyPlugin) PluginName() string {
return p.name
}
func main() {
// Create a plugin collection
plugs := plugins.Plugins{
MyPlugin{name: "plugin1"},
MyPlugin{name: "plugin2"},
}
// Validate the collection
if err := plugs.Validate(); err != nil {
panic(err)
}
// Find plugins by type
myPlugins := plugins.ByType[MyPlugin](plugs)
fmt.Printf("Found %d plugins\n", len(myPlugins))
// Get plugin names
names := plugs.Names()
fmt.Printf("Plugin names: %v\n", names)
}Plugin: Basic interface that all plugins must implementScoper: Plugins that can return scoped plugin collectionsFeeder/Needer: Plugin communication and dependency injectionAvailabilityChecker: Runtime availability checking
IOSetable/IOable: I/O configuration and accessFSSetable/FSable: Filesystem configuration and access
Commander: CLI command implementationNamer: Custom naming for commandsFlagger: Flag definition and parsing
plugs := plugins.Plugins{
MyPlugin{name: "plugin1"},
MyPlugin{name: "plugin2"},
}
// Validate for common issues
if err := plugs.Validate(); err != nil {
log.Fatalf("Plugin validation failed: %v", err)
}type ConditionalPlugin struct {
name string
}
func (p ConditionalPlugin) PluginName() string {
return p.name
}
func (p ConditionalPlugin) PluginAvailable(root string) bool {
// Custom logic to determine availability
return true
}
// Filter to only available plugins
available := plugs.Available("/project/root")// Configure I/O for all compatible plugins
io := someIOInstance
if err := plugs.SetStdio(io); err != nil {
log.Fatalf("Failed to configure I/O: %v", err)
}- Go 1.24 or later
- Modern Go toolchain with generics support
github.com/markbates/iox- I/O utilitiesgithub.com/stretchr/testify- Testing framework (dev dependency)
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Create a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.