From b3bdeb18e2d24173dd8828677048a21e13725dfe Mon Sep 17 00:00:00 2001 From: andrewbaxter Date: Mon, 17 May 2021 20:31:07 +0900 Subject: [PATCH] Fixes #125: Support custom per-mapper placeholder text (#169) --- help.go | 5 +++++ mapper.go | 1 + mapper_test.go | 32 ++++++++++++++++++++++++++++++++ model.go | 4 ++++ 4 files changed, 42 insertions(+) diff --git a/help.go b/help.go index b0fc81d..2a9985f 100644 --- a/help.go +++ b/help.go @@ -65,6 +65,11 @@ type HelpProvider interface { Help() string } +// PlaceHolderProvider can be implemented by mappers to provide custom placeholder text. +type PlaceHolderProvider interface { + PlaceHolder(flag *Flag) string +} + // HelpIndenter is used to indent new layers in the help tree. type HelpIndenter func(prefix string) string diff --git a/mapper.go b/mapper.go index b8447ec..f5e1a3f 100644 --- a/mapper.go +++ b/mapper.go @@ -43,6 +43,7 @@ func (r *DecodeContext) WithScanner(scan *Scanner) *DecodeContext { } // MapperValue may be implemented by fields in order to provide custom mapping. +// Mappers may additionally implement PlaceHolderProvider to provide custom placeholder text. type MapperValue interface { Decode(ctx *DecodeContext) error } diff --git a/mapper_test.go b/mapper_test.go index 4f052f9..0a81f9c 100644 --- a/mapper_test.go +++ b/mapper_test.go @@ -420,3 +420,35 @@ func TestPathMapper(t *testing.T) { require.NoError(t, err) require.Equal(t, "-", cli.Path) } + +func TestMapperPlaceHolder(t *testing.T) { + var cli struct { + Flag string + } + b := bytes.NewBuffer(nil) + k := mustNew( + t, + &cli, + kong.Writers(b, b), + kong.ValueMapper(&cli.Flag, testMapperWithPlaceHolder{}), + kong.Exit(func(int) { panic("exit") }), + ) + // Ensure that --help + require.Panics(t, func() { + _, err := k.Parse([]string{"--help"}) + require.NoError(t, err) + }) + require.Contains(t, b.String(), "--flag=/a/b/c") +} + +type testMapperWithPlaceHolder struct { +} + +func (t testMapperWithPlaceHolder) Decode(ctx *kong.DecodeContext, target reflect.Value) error { + target.SetString("hi") + return nil +} + +func (t testMapperWithPlaceHolder) PlaceHolder(flag *kong.Flag) string { + return "/a/b/c" +} diff --git a/model.go b/model.go index f21dece..da64356 100644 --- a/model.go +++ b/model.go @@ -397,6 +397,10 @@ func (f *Flag) String() string { // FormatPlaceHolder formats the placeholder string for a Flag. func (f *Flag) FormatPlaceHolder() string { + placeholderHelper, ok := f.Value.Mapper.(PlaceHolderProvider) + if ok { + return placeholderHelper.PlaceHolder(f) + } tail := "" if f.Value.IsSlice() && f.Value.Tag.Sep != -1 { tail += string(f.Value.Tag.Sep) + "..."