diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-22 08:42:56 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-22 08:42:56 +0300 |
| commit | f9baad3a11e48a6d438d3e614e1ca1ee45c1547d (patch) | |
| tree | 72db85faa6307b7b586d0ed982da977ad12c6e46 /cmd | |
| parent | 15639ba3508ab92599bd1884ba07139c73b2dac0 (diff) | |
Fix manual prompt mode flags
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/comicforge/cli.go | 17 | ||||
| -rw-r--r-- | cmd/comicforge/cli_test.go | 50 |
2 files changed, 62 insertions, 5 deletions
diff --git a/cmd/comicforge/cli.go b/cmd/comicforge/cli.go index 1a7f1ec..47ec2df 100644 --- a/cmd/comicforge/cli.go +++ b/cmd/comicforge/cli.go @@ -83,6 +83,9 @@ func newRootCommandWithDeps(deps commandDeps) *cobra.Command { _, _ = fmt.Fprintln(cmd.OutOrStdout(), version.Version) return nil } + if err := validateUltraRealisticFlags(flags); err != nil { + return err + } if cmd.Flags().Changed("prompt") && strings.TrimSpace(flags.prompt) == "" { return fmt.Errorf("--prompt is required when set") } @@ -105,8 +108,8 @@ func newRootCommandWithDeps(deps commandDeps) *cobra.Command { cmd.Flags().StringVar(&flags.configPath, "config", "", "config file (default: search ~/.config/comicforge, $HOME, and .)") cmd.Flags().StringVar(&flags.promptsDir, "prompts-dir", "", "directory containing prompt templates") cmd.Flags().StringVar(&flags.outputDir, "output", ".", "root output directory for generated comic data") - cmd.Flags().StringVar(&flags.style, "style", "", "comic art style override") - cmd.Flags().StringVar(&flags.theme, "theme", "", "story theme override") + cmd.Flags().StringVar(&flags.style, "style", "", "comic art style override for story and prompt mode") + cmd.Flags().StringVar(&flags.theme, "theme", "", "story theme override; used as prompt context in manual prompt mode") cmd.Flags().BoolVar(&flags.ultraRealistic, "ultra-realistic", false, "force photorealistic rendering") cmd.Flags().BoolVar(&flags.noUltraRealistic, "no-ultra-realistic", false, "disable photorealistic rendering") cmd.Flags().BoolVar(&flags.narrateEnabled, "narrate", false, "generate narration after the comic") @@ -127,9 +130,6 @@ func runCommand(ctx context.Context, cmd *cobra.Command, deps commandDeps, flags if ctx == nil { ctx = context.Background() } - if flags.noUltraRealistic && flags.ultraRealistic { - return fmt.Errorf("only one of --ultra-realistic and --no-ultra-realistic may be set") - } cfg, err := deps.loadConfig(flags.configPath) if err != nil { @@ -224,6 +224,13 @@ func runPromptCommand(ctx context.Context, cmd *cobra.Command, deps commandDeps, return runner.RunPrompt(ctx, flags.prompt) } +func validateUltraRealisticFlags(flags cliFlags) error { + if flags.noUltraRealistic && flags.ultraRealistic { + return fmt.Errorf("only one of --ultra-realistic and --no-ultra-realistic may be set") + } + return nil +} + func applyConfigOverrides(cmd *cobra.Command, cfg *config.Config, flags cliFlags) { if cfg == nil { return diff --git a/cmd/comicforge/cli_test.go b/cmd/comicforge/cli_test.go index 048d22e..54c5ea8 100644 --- a/cmd/comicforge/cli_test.go +++ b/cmd/comicforge/cli_test.go @@ -300,6 +300,44 @@ func TestRootCommandRejectsConflictingUltraFlags(t *testing.T) { } } +func TestRootCommandRejectsConflictingUltraFlagsInPromptMode(t *testing.T) { + cmd := newRootCommandWithDeps(commandDeps{ + loadConfig: func(string) (*config.Config, error) { + t.Fatal("loadConfig should not be called when ultra-realistic flags conflict") + return nil, nil + }, + newTextProvider: func(*config.Config) (provider.TextProvider, error) { + t.Fatal("newTextProvider should not be called when ultra-realistic flags conflict") + return noopProvider{}, nil + }, + newImageProvider: func(*config.Config) (provider.ImageProvider, error) { + t.Fatal("newImageProvider should not be called when ultra-realistic flags conflict") + return noopProvider{}, nil + }, + newTTSProvider: func(*config.Config, string) (provider.TTSProvider, error) { + t.Fatal("newTTSProvider should not be called when ultra-realistic flags conflict") + return noopProvider{}, nil + }, + newRunner: func(*comic.RunnerConfig) comic.StoryRunner { + t.Fatal("newRunner should not be called when ultra-realistic flags conflict") + return &recordingRunner{} + }, + }) + cmd.SetArgs([]string{ + "--prompt", "draw a robot", + "--ultra-realistic", + "--no-ultra-realistic", + }) + + err := cmd.ExecuteContext(context.Background()) + if err == nil { + t.Fatal("ExecuteContext() error = nil, want conflict error") + } + if !strings.Contains(err.Error(), "only one of --ultra-realistic and --no-ultra-realistic may be set") { + t.Fatalf("ExecuteContext() error = %v, want conflict error", err) + } +} + func TestRootCommandProviderFlagsDefaultToGemini(t *testing.T) { cmd := newRootCommand() for _, flagName := range []string{"text-provider", "image-provider", "tts-provider"} { @@ -399,6 +437,9 @@ func TestRootCommandPromptModeSkipsVocabFlow(t *testing.T) { "--prompt", "a robot reading a newspaper", "--output", filepath.Join(tmpDir, "out"), "--slug", "manual-robot", + "--style", "noir", + "--theme", "mystery", + "--ultra-realistic", }) if err := cmd.ExecuteContext(context.Background()); err != nil { @@ -425,6 +466,15 @@ func TestRootCommandPromptModeSkipsVocabFlow(t *testing.T) { if got, want := gotRunnerCfg.Slug, "manual-robot"; got != want { t.Fatalf("slug = %q, want %q", got, want) } + if got, want := gotRunnerCfg.Style, "noir"; got != want { + t.Fatalf("style = %q, want %q", got, want) + } + if got, want := gotRunnerCfg.Theme, "mystery"; got != want { + t.Fatalf("theme = %q, want %q", got, want) + } + if gotRunnerCfg.UltraRealistic == nil || !*gotRunnerCfg.UltraRealistic { + t.Fatalf("ultra realistic = %#v, want true", gotRunnerCfg.UltraRealistic) + } } func TestRootCommandRejectsPromptAndVocabTogether(t *testing.T) { |
