diff --git a/main.go b/main.go index ac06d2f..5967b6c 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,6 @@ import ( "github.com/urfave/cli/v3" ) - var ( version = "dev" commit = "none" @@ -30,6 +29,7 @@ func main() { Flags: util.Flags, EnableShellCompletion: true, HideHelpCommand: true, + Before: util.CheckMutuallyExclusiveTitleFlags, Action: util.RunMark, } diff --git a/util/cli_test.go b/util/cli_test.go new file mode 100644 index 0000000..2f2ea9f --- /dev/null +++ b/util/cli_test.go @@ -0,0 +1,52 @@ +package util + +import ( + "context" + "testing" + + "github.com/urfave/cli/v3" +) + +func runWithArgs(args []string) error { + cmd := &cli.Command{ + Flags: []cli.Flag{ + &cli.BoolFlag{Name: "title-from-h1"}, + &cli.BoolFlag{Name: "title-from-filename"}, + }, + Before: CheckMutuallyExclusiveTitleFlags, + Action: func(ctx context.Context, cmd *cli.Command) error { + return nil + }, + } + return cmd.Run(context.Background(), args) +} + +func TestCheckMutuallyExclusiveTitleFlags(t *testing.T) { + t.Run("neither flag set", func(t *testing.T) { + err := runWithArgs([]string{"cmd"}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + }) + + t.Run("only title-from-h1 set", func(t *testing.T) { + err := runWithArgs([]string{"cmd", "--title-from-h1"}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + }) + + t.Run("only title-from-filename set", func(t *testing.T) { + err := runWithArgs([]string{"cmd", "--title-from-filename"}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + }) + + t.Run("both flags set", func(t *testing.T) { + err := runWithArgs([]string{"cmd", "--title-from-h1", "--title-from-filename"}) + if err == nil { + t.Errorf("expected error, got nil") + } + }) +} diff --git a/util/flags.go b/util/flags.go index e9f01e7..e4807df 100644 --- a/util/flags.go +++ b/util/flags.go @@ -1,6 +1,9 @@ package util import ( + "context" + "errors" + altsrc "github.com/urfave/cli-altsrc/v3" altsrctoml "github.com/urfave/cli-altsrc/v3/toml" "github.com/urfave/cli/v3" @@ -58,13 +61,13 @@ var Flags = []cli.Flag{ &cli.BoolFlag{ Name: "title-from-h1", Value: false, - Usage: "extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata.", + Usage: "extract page title from a leading H1 heading. If no H1 heading on a page exists, then title must be set in the page metadata. Mutually exclusive with --title-from-filename.", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_H1"), altsrctoml.TOML("title-from-h1", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ Name: "title-from-filename", Value: false, - Usage: "use the filename (without extension) as the Confluence page title if no explicit 'Title' header or H1 heading is found.", + Usage: "use the filename (without extension) as the Confluence page title if no explicit page title is set in the metadata. Mutually exclusive with --title-from-h1.", Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_TITLE_FROM_FILENAME"), altsrctoml.TOML("title-from-filename", altsrc.NewStringPtrSourcer(&filename))), }, &cli.BoolFlag{ @@ -194,3 +197,11 @@ var Flags = []cli.Flag{ Sources: cli.NewValueSourceChain(cli.EnvVar("MARK_FEATURES"), altsrctoml.TOML("features", altsrc.NewStringPtrSourcer(&filename))), }, } + +// CheckMutuallyExclusiveTitleFlags checks if both title-from-h1 and title-from-filename are set +func CheckMutuallyExclusiveTitleFlags(context context.Context, command *cli.Command) (context.Context, error) { + if command.Bool("title-from-h1") && command.Bool("title-from-filename") { + return context, errors.New("flags --title-from-h1 and --title-from-filename are mutually exclusive. Please specify only one") + } + return context, nil +}