plugins

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2025 License: MIT Imports: 8 Imported by: 4

README

plugins

A flexible and extensible plugin system for Go applications built with modern Go idioms.

Features

  • 🎯 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

Quick Start

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 Interfaces

Core Interfaces
  • Plugin: Basic interface that all plugins must implement
  • Scoper: Plugins that can return scoped plugin collections
  • Feeder/Needer: Plugin communication and dependency injection
  • AvailabilityChecker: Runtime availability checking
I/O and Filesystem
  • IOSetable/IOable: I/O configuration and access
  • FSSetable/FSable: Filesystem configuration and access
Command-line (plugcmd package)
  • Commander: CLI command implementation
  • Namer: Custom naming for commands
  • Flagger: Flag definition and parsing

Advanced Usage

Plugin Validation
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)
}
Runtime Availability
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")
I/O Configuration
// 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)
}

Requirements

  • Go 1.24 or later
  • Modern Go toolchain with generics support

Dependencies

  • github.com/markbates/iox - I/O utilities
  • github.com/stretchr/testify - Testing framework (dev dependency)

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/new-feature)
  3. Commit your changes (git commit -am 'Add new feature')
  4. Push to the branch (git push origin feature/new-feature)
  5. Create a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package plugins provides a flexible and extensible plugin system for Go applications.

The core concept revolves around the Plugin interface, which provides a name for identification. Additional interfaces like Needer, Feeder, AvailabilityChecker, IOSetable, and FSSetable extend functionality.

Basic Usage

Create plugins by implementing the Plugin interface and any additional specialized interfaces:

type MyPlugin struct {
	name string
}

func (p MyPlugin) PluginName() string {
	return p.name
}

Manage a collection of plugins using the Plugins slice type:

plugs := plugins.Plugins{
	MyPlugin{name: "plugin1"},
	MyPlugin{name: "plugin2"},
}

// Find plugins by type
myPlugins := plugins.ByType[MyPlugin](plugs)

// Check availability
available := plugs.Available("/some/path")

// Configure I/O and filesystem
err := plugs.SetStdio(someIO)
err = plugs.SetFileSystem(someFS)

Plugin Types

The package provides several specialized plugin interfaces:

  • Plugin: Basic interface that all plugins must implement
  • Scoper: Plugins that can return scoped plugin collections
  • Feeder/Needer: Plugin communication and dependency injection
  • AvailabilityChecker: Runtime availability checking
  • IOSetable/FSSetable: I/O and filesystem configuration

See the plugcmd subpackage for command-line specific plugin interfaces.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ByType

func ByType[T any](plugs Plugins) []T

ByType finder can be used to find plugins by their type.

func Stderr

func Stderr(plugs ...Plugin) io.Writer

Stderr returns a io.MultiWriter containing all plugins that implement Outer. If none are found, then os.Stderr is returned

func Stdout

func Stdout(plugs ...Plugin) io.Writer

Stdout returns a io.MultiWriter containing all plugins that implement Outer. If none are found, then os.Stdout is returned

Types

type AvailabilityChecker

type AvailabilityChecker interface {
	Plugin
	PluginAvailable(root string) bool
}

AvailabilityChecker can be implemented to check if a plugin is available to be used at the given root.

type FSSetable

type FSSetable interface {
	Plugin
	SetFileSystem(fs.FS) error
}

FSSetable can be implemented to receive an fs.FS

type FSable

type FSable interface {
	Plugin
	FileSystem() (fs.FS, error)
}

FSable can be implemented to return an fs.FS

type Feeder

type Feeder interface {
	Plugin
	PluginFeeder() FeederFn
}

Feeder can be implemented to return a FeederFn.

type FeederFn

type FeederFn func() Plugins

FeederFn is a function that is used to feed plugins into a Needer implementation.

type Findable

type Findable interface {
	Find(plugs Plugins) (Plugins, error)
}

Findable can be implemented to find plugins

func Background

func Background(name string) Findable

Background finder that will search for a plugin based on the plugin's name.

type FinderFn

type FinderFn func(plugs Plugins) (Plugins, error)

FinderFn is a function that can be used to find plugins. It implements the Finder interface.

func (FinderFn) Find

func (f FinderFn) Find(plugs Plugins) (Plugins, error)

Find plugins using the underlying function.

type IO

type IO = iox.IO

type IOSetable

type IOSetable interface {
	Plugin
	iox.IOSetable
}

IOSetable can be implemented to receive an IO.

type IOable

type IOable interface {
	Plugin
	iox.IOable
}

IOable can be implemented to return an IO.

type Needer

type Needer interface {
	Plugin
	WithPlugins(FeederFn) error
}

Needer can be implemented to receive a Feeder function that can be used to gain access to other plugins in the system.

type Plugin

type Plugin interface {
	PluginName() string
}

Plugin is the most basic interface a plugin can implement.

type Plugins

type Plugins []Plugin

Plugins is a slice of type `Plugin` that provides additional useful functionality.

func (Plugins) Available

func (plugs Plugins) Available(root string) Plugins

Available will return plugins that are available to be used at the given root. By default, all plugins are available. The AvailabilityChecker interface can be implemented to give the plugin the ability to check if it is available.

func (Plugins) Find

func (plugs Plugins) Find(fn FinderFn) (Plugins, error)

Find plugins using the given Finder.

func (Plugins) Len

func (plugs Plugins) Len() int

Len is the number of elements in the collection.

func (Plugins) Less

func (plugs Plugins) Less(i int, j int) bool

Less reports whether the element with index i should sort before the element with index j.

func (Plugins) Names added in v1.2.0

func (plugs Plugins) Names() []string

Names returns a slice of all plugin names in the collection.

func (Plugins) PluginFeeder

func (plugs Plugins) PluginFeeder() FeederFn

func (Plugins) PluginName

func (plugs Plugins) PluginName() string

func (Plugins) ScopedPlugins

func (plugs Plugins) ScopedPlugins() Plugins

ScopedPlugins implements Scoper, return itself.

func (Plugins) SetFileSystem

func (plugs Plugins) SetFileSystem(fs fs.FS) error

SetFS for those plugins that implement FSSetable.

func (Plugins) SetStdio

func (plugs Plugins) SetStdio(io IO) error

SetStdio for those plugins that implement IOSetable.

func (Plugins) Swap

func (plugs Plugins) Swap(i int, j int)

Swap swaps the elements with indexes i and j.

func (Plugins) Validate added in v1.2.0

func (plugs Plugins) Validate() error

Validate checks the plugins collection for common issues. It verifies that no duplicate plugin names exist and that all plugins have valid names.

func (Plugins) WithPlugins

func (plugs Plugins) WithPlugins(fn FeederFn) error

WithPlugins will call any Needer plugins with the Feeder function.

type Scoper

type Scoper interface {
	Plugin
	ScopedPlugins() Plugins
}

Scoper can be implemented to return a slice of plugins that are important to the type defining it.

type Stderrer

type Stderrer interface {
	Plugin
	iox.Stderrer
}

type Stdiner

type Stdiner interface {
	Plugin
	iox.Stdiner
}

type Stdioer

type Stdioer interface {
	Plugin
	iox.Stdioer
}

type Stdouter

type Stdouter interface {
	Plugin
	iox.Stdouter
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL