plugin

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: May 5, 2026 License: MIT Imports: 11 Imported by: 1

Documentation

Overview

Package plugin provides the compile-time plugin system for TerraCi.

Package layout

The plugin system is organized into three packages:

  • pkg/plugin — core interfaces, BasePlugin[C], AppContext, EnablePolicy, RuntimeProvider
  • pkg/plugin/registry — factory catalog and per-command Registry capability resolution
  • pkg/plugin/initwiz — init wizard types (StateMap, InitContributor, InitGroupSpec)

Test helpers live in pkg/plugin/plugintest. Helpers shared between CI provider plugins (gitlab, github, future Bitbucket/Jenkins/Azure DevOps) live in plugins/internal/ciplugin and are not part of the public API.

Plugin file convention

Each runtime-heavy plugin (cost, policy, tfupdate) keeps one file per capability so the file list reads as a capability index:

  • plugin.go — registration shell + typed BasePlugin[C] config
  • lifecycle.go — cheap Preflight checks only (no network, no FS scan)
  • runtime.go — lazy RuntimeProvider implementation
  • usecases.go — command orchestration over typed runtime
  • commands.go — CommandProvider with cobra definitions
  • pipeline.go — PipelineContributor (steps + standalone jobs)
  • init_wizard.go — initwiz.InitContributor (TUI form fields)
  • output.go — CLI rendering helpers
  • report.go — typed CI report assembly via ci.EncodeSection

Smaller plugins (git, diskblob, inmemcache, summary, localexec) only implement the capabilities they need — there is no minimum surface.

Lifecycle

The framework drives every plugin through four stages per command run:

┌─────────────┐
│  Register   │  init() → registry.RegisterFactory(factory)
│             │  Validator.Validate() runs here — misconfigured
│             │  plugins panic at startup, not at first use.
└──────┬──────┘
       │
┌──────▼──────┐
│  Configure  │  ConfigLoader.DecodeAndSet — extensions.<key>
│             │  YAML node decoded into BasePlugin[C].cfg.
└──────┬──────┘
       │
┌──────▼──────┐
│  Preflight  │  Preflightable.Preflight(ctx, appCtx)
│             │  Cheap validation only. No network, no heavy state.
│             │  Skipped on commands with skipPreflight annotation.
└──────┬──────┘
       │
┌──────▼──────┐
│  Execute    │  RunE in command — RuntimeProvider builds heavy
│             │  state lazily; use-cases consume the typed runtime.
└─────────────┘

AppContext is constructed once per command run by the framework and attached to cmd.Context() so plugin RunE callbacks can retrieve it via plugin.FromContext. It is immutable — plugins receive a snapshot of Config / WorkDir / ServiceDir / Resolver that does not change for the duration of the command.

Thread-safety contract

AppContext fields are written exactly once at construction, so concurrent reads from any goroutine are safe without synchronization. Plugins should:

  • Treat ctx.Config() and any field returned by accessors as read-only; mutating returned pointers may surprise other plugins sharing the same context.
  • Treat ctx.Resolver() as never-nil (returns NoopResolver{} when no real one is bound) and idempotent; capability lookups can run from any goroutine.
  • Treat plugin-local Config (BasePlugin[C].cfg) as mutable only via FlagOverridable, ideally before RunE consumes it.

Plugin factories (the function passed to registry.RegisterFactory) MUST be pure: the catalog calls them once at startup for the prototype and once per command for the per-run plugin instance.

Capability discovery

Use registry.ByCapabilityFrom[T](resolver) to enumerate plugins implementing a capability interface inside a plugin's own logic. The canonical capabilities (CI provider, change detector, KV/blob caches, pipeline contributions, preflights) are pre-resolved by the Resolver interface — plugins should call those typed methods rather than type-asserting from raw plugin lists.

Cross-plugin communication

Plugins must never import each other directly. The contract surfaces are:

  • capability interfaces in pkg/plugin (CI provider, change detection, …)
  • shared types in pkg/ci (Report, ReportSection, PlanResult, …)
  • file-based reports under appCtx.ServiceDir() ({producer}-report.json)
  • the in-process ReportRegistry on AppContext (when transient sharing within a single command run is enough)

summary is the canonical consumer of file-based reports; cost/policy/ tfupdate are the canonical producers. The contract test suite for blob backends lives at pkg/cache/blobcache/contracttest.

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.

Core types (interfaces, BasePlugin, AppContext) live in this package. Plugin factories and per-command registries live in pkg/plugin/registry. Init wizard types live in pkg/plugin/initwiz.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNoResolver = errors.New("plugin resolver is not configured")

ErrNoResolver is returned by NoopResolver capability lookups. Tests can match it via errors.Is to assert the no-resolver path.

Functions

func BuildRuntime added in v0.9.0

func BuildRuntime[T any](ctx context.Context, p RuntimeProvider, appCtx *AppContext) (T, error)

BuildRuntime calls p.Runtime and type-asserts the result to T in one step. It combines the Runtime() call and RuntimeAs[T]() assertion — the recommended shorthand for plugin use-cases:

func (p *Plugin) runtime(ctx context.Context, appCtx *AppContext) (*myRuntime, error) {
	return plugin.BuildRuntime[*myRuntime](ctx, p, appCtx)
}

func CommandInstance added in v0.10.0

func CommandInstance[T Plugin](ctx *AppContext, name string) (T, error)

CommandInstance returns the command-scoped plugin instance matching name.

func RuntimeAs added in v0.9.0

func RuntimeAs[T any](runtime any) (T, error)

RuntimeAs converts a runtime returned by RuntimeProvider into the expected plugin-local type at the plugin boundary. The framework intentionally treats runtime values as opaque.

func WithContext added in v0.10.0

func WithContext(parent context.Context, appCtx *AppContext) context.Context

WithContext returns a child context.Context carrying appCtx. Used by the framework to attach the per-run AppContext to the cobra command context before RunE fires.

Types

type AppContext

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

AppContext is the public API available to plugins. It is immutable — constructed once per command run by the framework, then read-only.

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.

The Config returned by Config() is shared and must be treated as read-only by plugins. Mutate a deep copy if a plugin needs to derive a configuration.

AppContext is safe for concurrent reads from any goroutine because all fields are written exactly once at construction.

func FromContext added in v0.10.0

func FromContext(ctx context.Context) *AppContext

FromContext retrieves the AppContext attached to ctx, or nil if none is bound. Plugins use this inside cobra RunE callbacks:

appCtx := plugin.FromContext(cmd.Context())

func NewAppContext added in v0.9.0

func NewAppContext(opts AppContextOptions) *AppContext

NewAppContext creates a framework-managed plugin context.

func (*AppContext) Config

func (ctx *AppContext) Config() *config.Config

Config returns the loaded TerraCi configuration. The returned pointer is shared with the framework and must not be mutated by plugins.

func (*AppContext) Reports added in v0.7.5

func (ctx *AppContext) Reports() *ReportRegistry

Reports returns the shared in-process report registry.

func (*AppContext) Resolver added in v0.10.0

func (ctx *AppContext) Resolver() Resolver

Resolver returns the per-run plugin resolver. Always non-nil.

func (*AppContext) ServiceDir added in v0.7.3

func (ctx *AppContext) ServiceDir() string

ServiceDir returns the resolved absolute service directory path.

func (*AppContext) Version

func (ctx *AppContext) Version() string

Version returns the current TerraCi version string.

func (*AppContext) WorkDir

func (ctx *AppContext) WorkDir() string

WorkDir returns the working directory for the current command.

type AppContextOptions added in v0.10.0

type AppContextOptions struct {
	// Config is the loaded TerraCi configuration. Treated as read-only.
	Config *config.Config
	// WorkDir is the project working directory for the current command.
	WorkDir string
	// ServiceDir is the resolved absolute service directory path.
	ServiceDir string
	// Version is the current TerraCi version string.
	Version string
	// Reports is the shared in-process report registry. Defaults to a fresh
	// empty registry if nil.
	Reports *ReportRegistry
	// Resolver is the per-run plugin resolver. Defaults to NoopResolver{}
	// when nil — plugins may always call ctx.Resolver() without nil-checks.
	Resolver Resolver
}

AppContextOptions describes how to construct an AppContext.

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)
  • Validate() (registration-time sanity check; see Validator)

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 "extensions:" 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).

func (*BasePlugin[C]) Validate added in v0.10.0

func (b *BasePlugin[C]) Validate() error

Validate performs registration-time sanity checks on the BasePlugin embedding. It is invoked by registry.RegisterFactory; a non-nil error panics there with a message identifying the misconfigured plugin.

Currently catches the most common silent-disable bug: a plugin that opts into EnabledExplicitly but forgets to set IsEnabledFn — IsEnabled() would always return false, so the plugin appears registered but never runs.

type BlobStoreOptions added in v0.9.4

type BlobStoreOptions struct {
	RootDir string
}

BlobStoreOptions carries optional backend-specific initialization overrides. Pass the zero value to use the backend's defaults.

type BlobStoreProvider added in v0.9.4

type BlobStoreProvider interface {
	Plugin
	NewBlobStore(ctx context.Context, appCtx *AppContext, opts BlobStoreOptions) (blobcache.Store, error)
}

BlobStoreProvider creates a blob store backend for plugin consumers. Pass BlobStoreOptions{} to use the backend's defaults.

type CIInfoProvider added in v0.9.4

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

CIInfoProvider provides CI-specific metadata.

type CapabilityResolver added in v0.10.0

type CapabilityResolver interface {
	// ResolveCIProvider returns the active CI provider in the current set.
	ResolveCIProvider() (*ResolvedCIProvider, error)

	// ResolveChangeDetector returns the active change-detection provider.
	ResolveChangeDetector() (ChangeDetectionProvider, error)

	// ResolveKVCacheProvider returns the named KV cache backend provider.
	ResolveKVCacheProvider(name string) (KVCacheProvider, error)

	// ResolveBlobStoreProvider returns the named blob store backend provider.
	ResolveBlobStoreProvider(name string) (BlobStoreProvider, error)
}

CapabilityResolver resolves the canonical capability backings — CI provider, change detector, named cache backends. Each method returns a typed handle or a sentinel error explaining why no plugin satisfies the capability.

type ChangeDetectionProvider

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

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

type CommandProvider

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

CommandProvider adds CLI subcommands to TerraCi. The framework calls Commands() once during root command registration. Inside RunE, plugins retrieve the per-run AppContext via plugin.FromContext(cmd.Context()).

type CommentServiceFactory added in v0.9.4

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

CommentServiceFactory 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 "extensions:" 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.
	EnabledWhenConfigured EnablePolicy = iota

	// EnabledExplicitly requires an explicit opt-in beyond having config.
	// When IsEnabledFn is set: called after config is loaded, must return true to activate.
	// When IsEnabledFn is nil: always returns false, even if configured.
	EnabledExplicitly

	// EnabledByDefault means the plugin is active unless enabled: false is set.
	EnabledByDefault

	// EnabledAlways means the plugin is always active regardless of config.
	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 KVCache added in v0.9.4

type KVCache interface {
	Get(ctx context.Context, namespace, key string) ([]byte, bool, error)
	Set(ctx context.Context, namespace, key string, value []byte, ttl time.Duration) error
	Delete(ctx context.Context, namespace, key string) error
	DeleteNamespace(ctx context.Context, namespace string) error
}

KVCache is a pluggable key/value cache backend.

Values are stored as opaque bytes. Consumers own serialization, key layout, namespaces, and write-time TTL selection.

type KVCacheProvider added in v0.9.4

type KVCacheProvider interface {
	Plugin
	NewKVCache(ctx context.Context, appCtx *AppContext) (KVCache, error)
}

KVCacheProvider creates a KV cache backend for plugin consumers.

Providers are registered like any other TerraCi plugin and resolved by name through the global plugin registry.

type LifecycleSource added in v0.10.0

type LifecycleSource interface {
	// CollectContributions gathers pipeline contributions from enabled
	// PipelineContributor plugins.
	CollectContributions(ctx *AppContext) []*pipeline.Contribution

	// PreflightsForStartup returns enabled plugins that participate in
	// framework startup preflight for the current configuration state.
	PreflightsForStartup() []Preflightable
}

LifecycleSource exposes plugin-collection hooks the framework uses to drive pipeline construction and startup preflight.

type Lookup added in v0.10.0

type Lookup interface {
	// All returns every plugin in the current command-scoped set.
	All() []Plugin

	// GetPlugin returns a plugin by name from the current set.
	GetPlugin(name string) (Plugin, bool)
}

Lookup is the read-side of the command-scoped plugin set: enumeration and name lookup. External callers (e.g. tests for non-capability code) only need this slice of Resolver and can mock it cheaply.

type NoopResolver added in v0.10.0

type NoopResolver struct{}

NoopResolver is the default-deny Resolver. It is bound to AppContext when no real resolver is supplied (so plugins may always call ctx.Resolver() without nil-checks) and is also intended for tests: embed it and override only the methods relevant to the case at hand.

func (NoopResolver) All added in v0.10.0

func (NoopResolver) All() []Plugin

All returns no plugins.

func (NoopResolver) CollectContributions added in v0.10.0

func (NoopResolver) CollectContributions(*AppContext) []*pipeline.Contribution

CollectContributions returns no contributions.

func (NoopResolver) GetPlugin added in v0.10.0

func (NoopResolver) GetPlugin(string) (Plugin, bool)

GetPlugin returns nothing.

func (NoopResolver) PreflightsForStartup added in v0.10.0

func (NoopResolver) PreflightsForStartup() []Preflightable

PreflightsForStartup returns no preflightables.

func (NoopResolver) ResolveBlobStoreProvider added in v0.10.0

func (NoopResolver) ResolveBlobStoreProvider(string) (BlobStoreProvider, error)

ResolveBlobStoreProvider rejects with ErrNoResolver.

func (NoopResolver) ResolveCIProvider added in v0.10.0

func (NoopResolver) ResolveCIProvider() (*ResolvedCIProvider, error)

ResolveCIProvider rejects with ErrNoResolver.

func (NoopResolver) ResolveChangeDetector added in v0.10.0

func (NoopResolver) ResolveChangeDetector() (ChangeDetectionProvider, error)

ResolveChangeDetector rejects with ErrNoResolver.

func (NoopResolver) ResolveKVCacheProvider added in v0.10.0

func (NoopResolver) ResolveKVCacheProvider(string) (KVCacheProvider, error)

ResolveKVCacheProvider rejects with ErrNoResolver.

type PipelineContributor

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

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

type PipelineGeneratorFactory added in v0.9.4

type PipelineGeneratorFactory interface {
	Plugin
	NewGenerator(ctx *AppContext, ir *pipeline.IR) pipeline.Generator
}

PipelineGeneratorFactory creates pipeline generators bound to a pre-built IR. Core builds the IR once via pipeline.Build(opts) and passes it here, so providers do not need depGraph, target modules, or contributions — they only render the IR.

type Plugin

type Plugin interface {
	// Name returns a unique plugin identifier.
	Name() string
	// Description returns a human-readable description.
	Description() string
}

Plugin is the core interface every plugin must implement.

type Preflightable added in v0.9.0

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

Preflightable plugins run cheap validation after config is loaded, before any command runs. Preflight should stay side-effect-light: do not cache mutable command state or perform heavy runtime setup that can be created lazily inside plugin use-cases.

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(producer string) (*ci.Report, bool)

Get retrieves a report by producer 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 its producer.

type ResolvedCIProvider added in v0.9.4

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

ResolvedCIProvider is the resolved CI provider, assembled from the focused interfaces above. Returned by ResolveCIProvider(). CommentServiceFactory is optional — not all CI providers support PR/MR comments.

func NewResolvedCIProvider added in v0.9.4

func NewResolvedCIProvider(p Plugin, meta CIInfoProvider, gen PipelineGeneratorFactory, comment CommentServiceFactory) *ResolvedCIProvider

NewResolvedCIProvider constructs a ResolvedCIProvider. The comment parameter may be nil for CI providers that do not support PR/MR comments.

func (*ResolvedCIProvider) CommitSHA added in v0.9.4

func (c *ResolvedCIProvider) CommitSHA() string

func (*ResolvedCIProvider) Description added in v0.9.4

func (c *ResolvedCIProvider) Description() string

func (*ResolvedCIProvider) Name added in v0.9.4

func (c *ResolvedCIProvider) Name() string

func (*ResolvedCIProvider) NewCommentService added in v0.9.4

func (c *ResolvedCIProvider) NewCommentService(ctx *AppContext) (ci.CommentService, bool)

NewCommentService returns the comment service and true, or nil and false if the CI provider does not support PR/MR comments.

func (*ResolvedCIProvider) NewGenerator added in v0.9.4

func (c *ResolvedCIProvider) NewGenerator(ctx *AppContext, ir *pipeline.IR) pipeline.Generator

NewGenerator returns a pipeline generator bound to the supplied IR.

func (*ResolvedCIProvider) PipelineID added in v0.9.4

func (c *ResolvedCIProvider) PipelineID() string

func (*ResolvedCIProvider) Plugin added in v0.9.4

func (c *ResolvedCIProvider) Plugin() Plugin

Plugin returns the underlying plugin instance.

func (*ResolvedCIProvider) ProviderName added in v0.9.4

func (c *ResolvedCIProvider) ProviderName() string

type Resolver added in v0.10.0

type Resolver interface {
	Lookup
	CapabilityResolver
	LifecycleSource
}

Resolver is the full command-scoped plugin surface exposed to plugins through AppContext. It composes Lookup, CapabilityResolver, and LifecycleSource — split apart so test mocks only need to implement the sub-interface their callee depends on.

type RuntimeProvider added in v0.9.0

type RuntimeProvider interface {
	Plugin
	Runtime(ctx context.Context, appCtx *AppContext) (any, error)
}

RuntimeProvider is the preferred pattern for plugins with heavy command-time setup. Runtime creation is lazy and command-driven; the framework does not invoke it automatically during startup or preflight.

Use Preflightable for cheap validation and environment checks. Use RuntimeProvider for typed runtime construction inside plugin commands and use-cases.

Typical shape:

func (p *Plugin) Runtime(_ context.Context, appCtx *AppContext) (any, error) {
	return newRuntime(appCtx, p.Config(), runtimeOptions{})
}

func (p *Plugin) runtime(ctx context.Context, appCtx *AppContext, opts runtimeOptions) (*myRuntime, error) {
	if opts == (runtimeOptions{}) {
		rawRuntime, err := p.Runtime(ctx, appCtx)
		if err != nil {
			return nil, err
		}
		return RuntimeAs[*myRuntime](rawRuntime)
	}
	return newRuntime(appCtx, p.Config(), opts)
}
Example
package main

import (
	"context"
	"fmt"

	"github.com/edelwud/terraci/pkg/plugin"
)

type exampleRuntime struct {
	workDir string
}

type exampleRuntimePlugin struct {
	plugin.BasePlugin[*exampleRuntimeConfig]
}

type exampleRuntimeConfig struct {
	Enabled bool
}

func (p *exampleRuntimePlugin) Runtime(_ context.Context, appCtx *plugin.AppContext) (any, error) {
	if p.Config() == nil || !p.Config().Enabled {
		return nil, fmt.Errorf("example runtime is not enabled")
	}
	return &exampleRuntime{workDir: appCtx.WorkDir()}, nil
}

func main() {
	p := &exampleRuntimePlugin{
		BasePlugin: plugin.BasePlugin[*exampleRuntimeConfig]{
			PluginName:  "example",
			PluginDesc:  "example runtime plugin",
			EnableMode:  plugin.EnabledExplicitly,
			DefaultCfg:  func() *exampleRuntimeConfig { return &exampleRuntimeConfig{} },
			IsEnabledFn: func(cfg *exampleRuntimeConfig) bool { return cfg != nil && cfg.Enabled },
		},
	}
	p.SetTypedConfig(&exampleRuntimeConfig{Enabled: true})

	appCtx := plugin.NewAppContext(plugin.AppContextOptions{
		WorkDir:    "/repo",
		ServiceDir: "/repo/.terraci",
		Version:    "test",
	})
	rawRuntime, _ := p.Runtime(context.Background(), appCtx)
	runtime, _ := plugin.RuntimeAs[*exampleRuntime](rawRuntime)

	fmt.Println(runtime.workDir)
}
Output:
/repo

type Validator added in v0.10.0

type Validator interface {
	Validate() error
}

Validator is implemented by plugins that want the registry to perform a startup sanity check. The framework calls Validate() once after the plugin is constructed by its factory; a non-nil error panics in RegisterFactory with a clear message identifying the misconfigured plugin.

type VersionProvider

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

VersionProvider plugins contribute version info to `terraci version`.

Directories

Path Synopsis
Package initwiz provides init wizard state management and types for TerraCi.
Package initwiz provides init wizard state management and types for TerraCi.
Package registry provides TerraCi's plugin catalog and per-run plugin sets.
Package registry provides TerraCi's plugin catalog and per-run plugin sets.

Jump to

Keyboard shortcuts

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