plugin

package
v0.7.5 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2026 License: MIT Imports: 10 Imported by: 1

Documentation

Overview

Package plugin provides the compile-time plugin system for TerraCi. Plugins register themselves via init() and blank imports, following the same pattern as database/sql drivers and Caddy modules.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ByCapability

func ByCapability[T Plugin]() []T

ByCapability returns all plugins that implement the given capability interface.

func CollectContributions added in v0.7.3

func CollectContributions() []*pipeline.Contribution

CollectContributions gathers pipeline contributions from all enabled PipelineContributor plugins. Plugins that implement ConfigLoader and are not enabled are skipped (framework-level filtering).

func Register

func Register(p Plugin)

Register adds a plugin to the global registry. Called from init() in plugin packages. Panics on duplicate names (fail-fast at startup).

func Reset

func Reset()

Reset clears the registry. Only for testing.

func ResetPlugins added in v0.7.5

func ResetPlugins()

ResetPlugins resets mutable state on all registered plugins that implement Resettable. The registry itself is NOT cleared — plugins stay registered, only their internal state (config, flags, cached clients) is zeroed. Intended for test isolation.

Types

type AppContext

type AppContext struct {
	Config     *config.Config
	WorkDir    string
	ServiceDir string // resolved absolute path to project service directory
	Version    string
	Reports    *ReportRegistry
	// contains filtered or unexported fields
}

AppContext is the public API available to plugins.

ServiceDir is the resolved absolute path — use it for runtime file I/O. For pipeline artifact paths (CI templates), use Config.ServiceDir which preserves the original relative value from .terraci.yaml.

After initialization, call Freeze() to prevent further mutations.

func (*AppContext) Freeze added in v0.7.5

func (ctx *AppContext) Freeze()

Freeze marks the context as immutable. Subsequent calls to Update will panic.

func (*AppContext) IsFrozen added in v0.7.5

func (ctx *AppContext) IsFrozen() bool

IsFrozen returns whether the context has been frozen.

type BasePlugin added in v0.7.5

type BasePlugin[C any] struct {
	PluginName string
	PluginDesc string
	PluginKey  string       // config key; defaults to PluginName if empty
	EnableMode EnablePolicy // how the framework checks if this plugin is active
	DefaultCfg func() C     // factory for default config

	// IsEnabledFn is an optional custom check for EnabledExplicitly and EnabledByDefault.
	// For EnabledExplicitly: called when configured, must return true to activate.
	// For EnabledByDefault: called when configured, return false to deactivate.
	IsEnabledFn func(C) bool
	// contains filtered or unexported fields
}

BasePlugin provides shared implementation for all plugins that have configuration. C is the plugin's concrete config type. Embedding this gives you:

  • Name(), Description()
  • ConfigKey(), NewConfig(), DecodeAndSet(), IsConfigured(), IsEnabled()
  • Config() (typed access to config)
  • Reset() (resets config state; override to reset custom fields)

func (*BasePlugin[C]) Config added in v0.7.5

func (b *BasePlugin[C]) Config() C

Config returns the typed plugin configuration.

func (*BasePlugin[C]) ConfigKey added in v0.7.5

func (b *BasePlugin[C]) ConfigKey() string

ConfigKey returns the config section key under "plugins:" in .terraci.yaml.

func (*BasePlugin[C]) DecodeAndSet added in v0.7.5

func (b *BasePlugin[C]) DecodeAndSet(decode func(target any) error) error

DecodeAndSet decodes plugin config via the provided decoder and stores it.

func (*BasePlugin[C]) Description added in v0.7.5

func (b *BasePlugin[C]) Description() string

Description returns a human-readable description.

func (*BasePlugin[C]) IsConfigured added in v0.7.5

func (b *BasePlugin[C]) IsConfigured() bool

IsConfigured returns true if config was loaded for this plugin.

func (*BasePlugin[C]) IsEnabled added in v0.7.5

func (b *BasePlugin[C]) IsEnabled() bool

IsEnabled returns whether the plugin should be active, based on EnablePolicy.

func (*BasePlugin[C]) Name added in v0.7.5

func (b *BasePlugin[C]) Name() string

Name returns the plugin's unique identifier.

func (*BasePlugin[C]) NewConfig added in v0.7.5

func (b *BasePlugin[C]) NewConfig() any

NewConfig returns a new instance of the default config for schema generation.

func (*BasePlugin[C]) Reset added in v0.7.5

func (b *BasePlugin[C]) Reset()

Reset resets the config state. Override in your plugin to also reset custom fields.

func (*BasePlugin[C]) SetTypedConfig added in v0.7.5

func (b *BasePlugin[C]) SetTypedConfig(cfg C)

SetTypedConfig sets the typed config directly (used by tests and flag overrides).

type CIMetadata added in v0.7.5

type CIMetadata interface {
	Plugin
	ProviderName() string
	PipelineID() string
	CommitSHA() string
}

CIMetadata provides CI-specific metadata.

type CIProvider added in v0.7.5

type CIProvider struct {
	// contains filtered or unexported fields
}

CIProvider is the resolved CI provider, assembled from the focused interfaces above. Returned by ResolveProvider().

func NewCIProvider added in v0.7.5

func NewCIProvider(p Plugin, meta CIMetadata, gen GeneratorFactory, comment CommentFactory) *CIProvider

NewCIProvider constructs a CIProvider from a plugin implementing all CI interfaces.

func ResolveProvider

func ResolveProvider() (*CIProvider, error)

ResolveProvider detects the active CI provider. Priority: env detection → TERRACI_PROVIDER env → single registered → configured.

func (*CIProvider) CommitSHA added in v0.7.5

func (c *CIProvider) CommitSHA() string

func (*CIProvider) Description added in v0.7.5

func (c *CIProvider) Description() string

func (*CIProvider) Name added in v0.7.5

func (c *CIProvider) Name() string

func (*CIProvider) NewCommentService added in v0.7.5

func (c *CIProvider) NewCommentService(ctx *AppContext) ci.CommentService

func (*CIProvider) NewGenerator added in v0.7.5

func (c *CIProvider) NewGenerator(ctx *AppContext, depGraph *graph.DependencyGraph, modules []*discovery.Module) pipeline.Generator

func (*CIProvider) PipelineID added in v0.7.5

func (c *CIProvider) PipelineID() string

func (*CIProvider) Plugin added in v0.7.5

func (c *CIProvider) Plugin() Plugin

Plugin returns the underlying plugin instance.

func (*CIProvider) ProviderName added in v0.7.5

func (c *CIProvider) ProviderName() string

type ChangeDetectionProvider

type ChangeDetectionProvider interface {
	Plugin
	DetectChangedModules(ctx context.Context, appCtx *AppContext, baseRef string, moduleIndex *discovery.ModuleIndex) (changed []*discovery.Module, changedFiles []string, err error)
	DetectChangedLibraries(ctx context.Context, appCtx *AppContext, baseRef string, libraryPaths []string) ([]string, error)
}

ChangeDetectionProvider detects changed modules from git (or other VCS).

func ResolveChangeDetector added in v0.7.3

func ResolveChangeDetector() (ChangeDetectionProvider, error)

ResolveChangeDetector returns the active ChangeDetectionProvider. Priority: single registered → configured → first available.

type CommandProvider

type CommandProvider interface {
	Plugin
	Commands(ctx *AppContext) []*cobra.Command
}

CommandProvider adds CLI subcommands to TerraCi.

type CommentFactory added in v0.7.5

type CommentFactory interface {
	Plugin
	NewCommentService(ctx *AppContext) ci.CommentService
}

CommentFactory creates PR/MR comment services.

type ConfigLoader added in v0.7.5

type ConfigLoader interface {
	Plugin
	ConfigKey() string
	NewConfig() any
	DecodeAndSet(decode func(target any) error) error
	IsConfigured() bool
	IsEnabled() bool
}

ConfigLoader declares a config section under "plugins:" in .terraci.yaml. Implemented automatically by embedding BasePlugin[C].

type EnablePolicy added in v0.7.5

type EnablePolicy int

EnablePolicy controls how the framework determines if a plugin is active.

const (
	// EnabledWhenConfigured means the plugin is active if its config section
	// exists in .terraci.yaml (e.g., gitlab, github).
	EnabledWhenConfigured EnablePolicy = iota

	// EnabledExplicitly requires an explicit enabled: true in config (e.g., cost, policy).
	EnabledExplicitly

	// EnabledByDefault means the plugin is active unless enabled: false is set (e.g., summary).
	EnabledByDefault

	// EnabledAlways means the plugin is always active regardless of config (e.g., git).
	EnabledAlways
)

type EnvDetector added in v0.7.5

type EnvDetector interface {
	Plugin
	DetectEnv() bool
}

EnvDetector detects whether this plugin's CI environment is active.

type FlagOverridable added in v0.7.5

type FlagOverridable interface {
	Plugin
	SetPlanOnly(bool)
	SetAutoApprove(bool)
}

FlagOverridable plugins support direct CLI flag overrides on their config.

type GeneratorFactory added in v0.7.5

type GeneratorFactory interface {
	Plugin
	NewGenerator(ctx *AppContext, depGraph *graph.DependencyGraph, modules []*discovery.Module) pipeline.Generator
}

GeneratorFactory creates pipeline generators.

type InitCategory added in v0.7.5

type InitCategory string

InitCategory determines how an InitGroupSpec is rendered in the wizard.

const (
	// CategoryProvider groups contain CI-specific infrastructure settings (image, runner).
	// Rendered as separate groups with ShowWhen.
	CategoryProvider InitCategory = "provider"
	// CategoryPipeline groups contain pipeline behavior settings (plan_enabled, auto_approve).
	// Fields from all CategoryPipeline groups are merged into a single "Pipeline" group.
	CategoryPipeline InitCategory = "pipeline"
	// CategoryFeature groups contain optional feature toggles (cost, policy, summary).
	// Fields from all CategoryFeature groups are merged into a single "Features" group.
	CategoryFeature InitCategory = "feature"
	// CategoryDetail groups contain detail settings for enabled features (policy settings).
	// Rendered as separate groups with ShowWhen (typically gated by a feature toggle).
	CategoryDetail InitCategory = "detail"
)

type InitContribution

type InitContribution struct {
	PluginKey string
	Config    map[string]any
}

InitContribution holds the config produced by a plugin's init logic.

type InitContributor

type InitContributor interface {
	Plugin
	InitGroups() []*InitGroupSpec
	BuildInitConfig(state *StateMap) *InitContribution
}

InitContributor plugins contribute fields and config to the init wizard.

type InitField

type InitField struct {
	Key         string
	Title       string
	Description string
	Type        string // "string", "bool", "select"
	Default     any
	Options     []InitOption
	Placeholder string
}

InitField describes a single form field in the init wizard.

type InitGroupSpec

type InitGroupSpec struct {
	Title    string
	Category InitCategory
	Order    int
	Fields   []InitField
	ShowWhen func(*StateMap) bool
}

InitGroupSpec describes a group of form fields contributed by a plugin.

type InitOption

type InitOption struct {
	Label string
	Value string
}

InitOption represents a selectable option for a field.

type Initializable

type Initializable interface {
	Plugin
	Initialize(ctx context.Context, appCtx *AppContext) error
}

Initializable plugins set up resources after config is loaded, before any command runs.

type PipelineContributor

type PipelineContributor interface {
	Plugin
	PipelineContribution() *pipeline.Contribution
}

PipelineContributor plugins add steps or jobs to the generated CI pipeline.

type Plugin

type Plugin interface {
	// Name returns a unique identifier (e.g., "gitlab", "cost", "slack").
	Name() string
	// Description returns a human-readable description.
	Description() string
}

Plugin is the core interface every plugin must implement.

func All

func All() []Plugin

All returns registered plugins in registration order.

func Get

func Get(name string) (Plugin, bool)

Get returns a plugin by name.

type ReportRegistry added in v0.7.5

type ReportRegistry struct {
	// contains filtered or unexported fields
}

ReportRegistry allows plugins to publish and consume reports in-memory. In CI (multi-process), reports are still written to JSON files for artifacts. The registry provides an in-process fast path for single-process runs.

func NewReportRegistry added in v0.7.5

func NewReportRegistry() *ReportRegistry

NewReportRegistry creates a new empty ReportRegistry.

func (*ReportRegistry) All added in v0.7.5

func (r *ReportRegistry) All() []*ci.Report

All returns all published reports.

func (*ReportRegistry) Get added in v0.7.5

func (r *ReportRegistry) Get(pluginName string) (*ci.Report, bool)

Get retrieves a report by plugin name.

func (*ReportRegistry) Publish added in v0.7.5

func (r *ReportRegistry) Publish(report *ci.Report)

Publish stores a report in the registry, keyed by plugin name.

type Resettable added in v0.7.5

type Resettable interface {
	Plugin
	Reset()
}

Resettable plugins can reset their mutable state to zero values. Used by test infrastructure to isolate tests from shared plugin singletons.

type StateMap

type StateMap struct {
	// contains filtered or unexported fields
}

StateMap is the typed init state backed by maps. It provides both typed accessors and stable pointers for huh form field binding.

func NewStateMap

func NewStateMap() *StateMap

NewStateMap creates a new empty StateMap.

func (*StateMap) Binary

func (s *StateMap) Binary() string

Binary returns the current binary name.

func (*StateMap) Bool added in v0.7.5

func (s *StateMap) Bool(key string) bool

Bool returns a bool value for the key, or false if not found.

func (*StateMap) BoolPtr

func (s *StateMap) BoolPtr(key string) *bool

BoolPtr returns a stable *bool pointer for huh form binding. If a value was previously Set for the key, it initializes the pointer with that value.

func (*StateMap) Get

func (s *StateMap) Get(key string) any

Get retrieves a value, preferring pointer-backed values from StringPtr/BoolPtr.

func (*StateMap) Provider

func (s *StateMap) Provider() string

Provider returns the current provider name.

func (*StateMap) Set

func (s *StateMap) Set(key string, val any)

Set stores a value in the state.

func (*StateMap) String added in v0.7.5

func (s *StateMap) String(key string) string

String returns a string value for the key, or empty string if not found.

func (*StateMap) StringPtr

func (s *StateMap) StringPtr(key string) *string

StringPtr returns a stable *string pointer for huh form binding. If a value was previously Set for the key, it initializes the pointer with that value.

type VersionProvider

type VersionProvider interface {
	Plugin
	VersionInfo() map[string]string
}

VersionProvider plugins contribute version info to `terraci version`.

Jump to

Keyboard shortcuts

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