package app import ( "context" "flag" "fmt" "io" "gitea.maximumdirect.net/eric/narratio/internal/config" ) // Run executes the pipeline plan and persists manifest state. func Run(ctx context.Context, args []string, out io.Writer) error { fs := flag.NewFlagSet("run", flag.ContinueOnError) fs.SetOutput(io.Discard) var pipelinePath string var sessionPath string var sessionID string var force bool var selectedArtifacts artifactSelectionFlag fs.StringVar(&pipelinePath, "config", "", "path to pipeline.yml (optional; defaults searched)") fs.StringVar(&sessionPath, "session", "", "path to session.yml") fs.StringVar(&sessionID, "session-id", "", "session identifier for session.yml templates") fs.BoolVar(&force, "force", false, "force stage execution (reserved for future behavior)") fs.Var(&selectedArtifacts, "artifacts", "artifact names to execute during analyze (comma-separated or repeatable)") if err := fs.Parse(args); err != nil { return fmt.Errorf("run: invalid flags: %w", err) } if fs.NArg() != 0 { return fmt.Errorf("run: unexpected positional arguments") } resolvedPipelinePath, err := resolvePipelineConfigPath(pipelinePath) if err != nil { return fmt.Errorf("run: %w", err) } resolvedSessionPath, err := resolveSessionConfigPath(sessionPath) if err != nil { return fmt.Errorf("run: %w", err) } cfg, err := config.LoadWithSessionOptions(resolvedPipelinePath, resolvedSessionPath, config.SessionLoadOptions{ SessionID: sessionID, }) if err != nil { return fmt.Errorf("run: %w", err) } if err := config.Validate(cfg); err != nil { return fmt.Errorf("run: %w", err) } normalizedArtifacts, err := selectedArtifacts.Normalize() if err != nil { return fmt.Errorf("run: invalid --artifacts: %w", err) } if err := validateSelectedAnalyzeArtifacts(cfg, normalizedArtifacts); err != nil { return fmt.Errorf("run: %w", err) } stages := BuildFullPlan() summary, err := executeStages(ctx, cfg, stages, RunOptions{ Force: force, SelectedArtifacts: normalizedArtifacts, }) if err != nil { return fmt.Errorf("run: %w", err) } _, err = fmt.Fprintf( out, "narratio run: session %s; executed=%d skipped=%d; manifest=%s\n", summary.SessionID, len(summary.Executed), len(summary.Skipped), summary.ManifestPath, ) return err }