2026-05-02 10:37:38 -05:00
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2026-08-29 18:07:24 +00:00
|
|
|
"errors"
|
2026-05-02 10:43:45 -05:00
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
2026-05-02 10:37:38 -05:00
|
|
|
"io"
|
2026-05-02 10:43:45 -05:00
|
|
|
|
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
2026-05-02 10:37:38 -05:00
|
|
|
)
|
|
|
|
|
|
2026-05-06 21:36:30 +00:00
|
|
|
// Run executes the pipeline plan and persists manifest state.
|
2026-05-02 11:05:28 -05:00
|
|
|
func Run(ctx context.Context, args []string, out io.Writer) error {
|
2026-09-05 17:53:56 +00:00
|
|
|
return runWithDependencies(ctx, args, out, executePlan, commandDependencies{})
|
2026-09-04 01:21:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runWithPipelineExecutor(ctx context.Context, args []string, out io.Writer, executor pipelineExecutor) error {
|
2026-09-05 17:53:56 +00:00
|
|
|
return runWithDependencies(ctx, args, out, executor, commandDependencies{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func runWithDependencies(ctx context.Context, args []string, out io.Writer, executor pipelineExecutor, deps commandDependencies) error {
|
|
|
|
|
deps = normalizeCommandDependencies(deps)
|
2026-08-29 18:07:24 +00:00
|
|
|
request, err := parseBoundedRunRequest("run", args, out)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, flag.ErrHelp) {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2026-05-23 13:47:39 +00:00
|
|
|
return err
|
2026-05-02 10:43:45 -05:00
|
|
|
}
|
2026-08-29 18:07:24 +00:00
|
|
|
flags := request.Config
|
2026-09-07 04:13:58 +00:00
|
|
|
loaded, err := loadCommandConfigWithDependencies(ctx, flags.pipelinePath, flags.campaignPath, flags.campaignFilePath, flags.sessionPath, flags.sessionOptions(), flags.secretsDir.pointer(), deps)
|
2026-05-02 10:43:45 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("run: %w", err)
|
|
|
|
|
}
|
2026-08-10 21:41:00 +00:00
|
|
|
defer func() { _ = loaded.Close() }()
|
|
|
|
|
cfg := loaded.Config
|
2026-05-02 10:43:45 -05:00
|
|
|
if err := config.Validate(cfg); err != nil {
|
|
|
|
|
return fmt.Errorf("run: %w", err)
|
|
|
|
|
}
|
2026-08-30 14:27:42 +00:00
|
|
|
selectedArtifacts, err := normalizeArtifactSelection(cfg, request.SelectedArtifacts)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("run: %w", err)
|
|
|
|
|
}
|
|
|
|
|
effectiveArtifacts, err := resolveEffectiveArtifacts(cfg, selectedArtifacts)
|
2026-08-10 22:27:06 +00:00
|
|
|
if err != nil {
|
2026-05-19 18:36:30 -05:00
|
|
|
return fmt.Errorf("run: %w", err)
|
|
|
|
|
}
|
2026-09-04 01:21:37 +00:00
|
|
|
summary, err := executor(ctx, cfg, request.Plan, RunOptions{
|
2026-08-29 18:07:24 +00:00
|
|
|
Force: request.Force,
|
2026-08-30 14:27:42 +00:00
|
|
|
SelectedArtifacts: selectedArtifacts,
|
2026-08-10 22:27:06 +00:00
|
|
|
EffectiveArtifacts: effectiveArtifacts,
|
2026-05-19 18:36:30 -05:00
|
|
|
})
|
2026-05-02 11:05:28 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("run: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 11:38:42 -05:00
|
|
|
_, err = fmt.Fprintf(
|
|
|
|
|
out,
|
2026-08-30 13:41:26 +00:00
|
|
|
"narratio run: session %s; executed=%d skipped=%d; manifest=%s; %s\n",
|
2026-05-02 11:38:42 -05:00
|
|
|
summary.SessionID,
|
|
|
|
|
len(summary.Executed),
|
|
|
|
|
len(summary.Skipped),
|
|
|
|
|
summary.ManifestPath,
|
2026-08-30 13:41:26 +00:00
|
|
|
effectiveConfigSummary(cfg),
|
2026-05-02 11:38:42 -05:00
|
|
|
)
|
2026-05-02 10:43:45 -05:00
|
|
|
return err
|
2026-05-02 10:37:38 -05:00
|
|
|
}
|