package local import ( "context" "io" "log/slog" "code.icb4dc0.de/buildr/buildr/modules/state" "code.icb4dc0.de/buildr/buildr/internal/logging" "code.icb4dc0.de/buildr/buildr/modules" ) var _ modules.ExecutionContext = (*DefaultExecutionContext)(nil) type DefaultExecutionContextOption interface { ApplyToDefaultExecutionContext(ctx *DefaultExecutionContext) } type defaultExecutionContextOptionFunc func(ctx *DefaultExecutionContext) func (f defaultExecutionContextOptionFunc) ApplyToDefaultExecutionContext(ctx *DefaultExecutionContext) { f(ctx) } func WithLoggerFactory(factory func() *slog.Logger) defaultExecutionContextOptionFunc { return func(ctx *DefaultExecutionContext) { ctx.loggerFactory = factory } } func NewDefaultExecutionContext( ctx context.Context, store state.Store, mod modules.ModuleWithMeta, workingDir, outDir, binDir, logsDir string, logToStdErr bool, opts ...DefaultExecutionContextOption, ) (DefaultExecutionContext, error) { execCtx := DefaultExecutionContext{ Context: ctx, mod: mod, workingDir: workingDir, outDir: outDir, binDir: binDir, store: store, } for i := range opts { opts[i].ApplyToDefaultExecutionContext(&execCtx) } outputSink, err := logging.NewTaskOutputSink(logsDir, logToStdErr, modules.LogFileNameFormatter(mod)) if err != nil { return DefaultExecutionContext{}, err } execCtx.outputSink = outputSink return execCtx, nil } type DefaultExecutionContext struct { context.Context outputSink logging.TaskOutputSink mod modules.ModuleWithMeta store state.Store loggerFactory func() *slog.Logger workingDir string outDir string binDir string } func (d DefaultExecutionContext) Name() string { return d.mod.Name() } func (d DefaultExecutionContext) GetState(ctx context.Context, key string) ([]byte, state.Metadata, error) { k := state.KeyOfStrings(d.mod.Category(), d.mod.Name(), key) return d.store.Get(ctx, k) } func (d DefaultExecutionContext) SetState(ctx context.Context, key string, value []byte) error { k := state.KeyOfStrings(d.mod.Category(), d.mod.Name(), key) return d.store.Set(ctx, k, value) } func (d DefaultExecutionContext) WorkingDir() string { return d.workingDir } func (d DefaultExecutionContext) OutDir() string { return d.outDir } func (d DefaultExecutionContext) BinariesDir() string { return d.binDir } func (d DefaultExecutionContext) StdOut() io.Writer { return d.outputSink.StdOut() } func (d DefaultExecutionContext) StdErr() io.Writer { return d.outputSink.StdErr() } func (d DefaultExecutionContext) Logger() *slog.Logger { if d.loggerFactory != nil { return d.loggerFactory() } return slog.Default() } func (d DefaultExecutionContext) Close() error { return d.outputSink.Close() }