Define adapter interfaces and fake implementations
This commit is contained in:
@@ -7,6 +7,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/analyzer"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/audita"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/notify"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/seriatim"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/storage"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/adapters/whisperx"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifacts"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/logging"
|
||||
@@ -16,6 +22,7 @@ import (
|
||||
|
||||
type RunOptions struct {
|
||||
Force bool
|
||||
Env *Env
|
||||
}
|
||||
|
||||
type RunSummary struct {
|
||||
@@ -25,36 +32,64 @@ type RunSummary struct {
|
||||
}
|
||||
|
||||
func executeStages(ctx context.Context, cfg *config.Config, stages []stage.Stage, opts RunOptions) (*RunSummary, error) {
|
||||
store := artifacts.NewLocalStore(cfg.Pipeline.Workspace.Root)
|
||||
paths, err := store.EnsureLayout(cfg.Session.SessionID)
|
||||
env := opts.Env
|
||||
if env == nil {
|
||||
env = &Env{}
|
||||
}
|
||||
if env.Config == nil {
|
||||
env.Config = cfg
|
||||
}
|
||||
if env.ArtifactStore == nil {
|
||||
env.ArtifactStore = artifacts.NewLocalStore(cfg.Pipeline.Workspace.Root)
|
||||
}
|
||||
if env.ManifestStore == nil {
|
||||
env.ManifestStore = &manifest.LocalStore{}
|
||||
}
|
||||
if env.Logger == nil {
|
||||
env.Logger = logging.NewLogger(os.Stderr, slog.LevelInfo)
|
||||
}
|
||||
if env.WhisperX == nil {
|
||||
env.WhisperX = &whisperx.NoopClient{}
|
||||
}
|
||||
if env.Seriatim == nil {
|
||||
env.Seriatim = &seriatim.NoopRunner{}
|
||||
}
|
||||
if env.Audita == nil {
|
||||
env.Audita = &audita.NoopRunner{}
|
||||
}
|
||||
if env.Analyzer == nil {
|
||||
env.Analyzer = &analyzer.NoopRunner{}
|
||||
}
|
||||
if env.Storage == nil {
|
||||
env.Storage = &storage.NoopBackend{}
|
||||
}
|
||||
if env.Notifier == nil {
|
||||
env.Notifier = ¬ify.NoopSender{}
|
||||
}
|
||||
|
||||
artifactStore := env.ArtifactStore
|
||||
paths, err := artifactStore.EnsureLayout(cfg.Session.SessionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("prepare workdir: %w", err)
|
||||
}
|
||||
|
||||
lock, err := store.AcquireSessionLock(cfg.Session.SessionID)
|
||||
lock, err := artifactStore.AcquireSessionLock(cfg.Session.SessionID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("acquire session lock: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = store.ReleaseSessionLock(lock)
|
||||
_ = artifactStore.ReleaseSessionLock(lock)
|
||||
}()
|
||||
|
||||
manifestStore := &manifest.LocalStore{}
|
||||
manifestPath := paths.ManifestPath
|
||||
|
||||
m, err := loadOrCreateManifest(ctx, manifestStore, manifestPath, cfg.Session.SessionID)
|
||||
m, err := loadOrCreateManifest(ctx, env.ManifestStore, manifestPath, cfg.Session.SessionID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
env := &Env{
|
||||
Config: cfg,
|
||||
ArtifactStore: store,
|
||||
Logger: logging.NewLogger(os.Stderr, slog.LevelInfo),
|
||||
}
|
||||
stageEnv := toStageEnv(env)
|
||||
|
||||
_ = opts // TODO: use --force behavior in future skip/stale logic.
|
||||
_ = opts.Force // TODO: use --force behavior in future skip/stale logic.
|
||||
|
||||
runNames := make([]string, 0, len(stages))
|
||||
for _, s := range stages {
|
||||
@@ -62,14 +97,14 @@ func executeStages(ctx context.Context, cfg *config.Config, stages []stage.Stage
|
||||
|
||||
now := nowUTC()
|
||||
m.MarkStageRunning(s.Name(), now)
|
||||
if err := manifestStore.Save(ctx, manifestPath, m); err != nil {
|
||||
if err := env.ManifestStore.Save(ctx, manifestPath, m); err != nil {
|
||||
return nil, fmt.Errorf("save manifest before stage %q: %w", s.Name(), err)
|
||||
}
|
||||
|
||||
result, err := s.Run(ctx, stageEnv, m)
|
||||
if err != nil {
|
||||
m.MarkStageFailed(s.Name(), nowUTC(), err.Error())
|
||||
if saveErr := manifestStore.Save(ctx, manifestPath, m); saveErr != nil {
|
||||
if saveErr := env.ManifestStore.Save(ctx, manifestPath, m); saveErr != nil {
|
||||
return nil, fmt.Errorf("stage %q failed (%v) and manifest save failed (%v)", s.Name(), err, saveErr)
|
||||
}
|
||||
return nil, fmt.Errorf("stage %q failed: %w", s.Name(), err)
|
||||
@@ -79,7 +114,7 @@ func executeStages(ctx context.Context, cfg *config.Config, stages []stage.Stage
|
||||
m.MarkStageSucceeded(s.Name(), nowUTC(), outputs)
|
||||
applyStageResultToManifest(m, s.Name(), result)
|
||||
|
||||
if err := manifestStore.Save(ctx, manifestPath, m); err != nil {
|
||||
if err := env.ManifestStore.Save(ctx, manifestPath, m); err != nil {
|
||||
return nil, fmt.Errorf("save manifest after stage %q: %w", s.Name(), err)
|
||||
}
|
||||
}
|
||||
@@ -91,7 +126,7 @@ func executeStages(ctx context.Context, cfg *config.Config, stages []stage.Stage
|
||||
}, nil
|
||||
}
|
||||
|
||||
func loadOrCreateManifest(ctx context.Context, store *manifest.LocalStore, path, sessionID string) (*manifest.Manifest, error) {
|
||||
func loadOrCreateManifest(ctx context.Context, store manifest.Store, path, sessionID string) (*manifest.Manifest, error) {
|
||||
exists, err := fileExists(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("check manifest existence %q: %w", path, err)
|
||||
|
||||
Reference in New Issue
Block a user