cli icon indicating copy to clipboard operation
cli copied to clipboard

Expected `cli.Generic` but actual is `string`

Open prestonvanloon opened this issue 5 years ago • 4 comments

my urfave/cli version is

v2

Checklist

  • [x] Are you running the latest v2 release? The list of releases is here.
  • [x] Did you check the manual for your release? The v2 manual is here
  • [x] Did you perform a search about this problem? Here's the Github guide about searching.

Dependency Management

  • Bazel

Describe the bug

Trying to specify a generic flag to load from yaml.

To reproduce

Create a generic flag and provide a string value in yaml.

Observed behavior

Expected 'cli.Generic' but actual is 'string'

Expected behavior

It works

Additional context

Add any other context about the problem here.

If the issue relates to a specific open source Github repo, please link that repo here.

If you can reproduce this issue with a public CI system, please link a failing build here.

Want to fix this yourself?

We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it.

Run go version and paste its output here

go version go1.13.1 linux/amd64

Run go env and paste its output here

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/preston/.cache/go-build"
GOENV="/home/preston/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/preston/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build299372313=/tmp/go-build -gno-record-gcc-switches"

prestonvanloon avatar Feb 16 '20 21:02 prestonvanloon

@prestonvanloon I need to see some code in your reproduction, your description of the reproduction doesn't have enough detail for me to look into it effectively.

coilysiren avatar Feb 17 '20 12:02 coilysiren

This issue or PR has been automatically marked as stale because it has not had recent activity. Please add a comment bumping this if you're still interested in it's resolution! Thanks for your help, please let us know if you need anything else.

stale[bot] avatar May 17 '20 13:05 stale[bot]

Closing this as it has become stale.

stale[bot] avatar Jun 16 '20 14:06 stale[bot]

I think I have a reprex 🤔

package main

import (
        "fmt"
        "log"
        "os"

        "github.com/urfave/cli/v2"
        "github.com/urfave/cli/v2/altsrc"
)

type Pants struct {
        v string
}

func (p *Pants) Set(value string) error {
        p.v = value
        return nil
}

func (p *Pants) String() string {
        return p.v
}

func main() {
        pantsPtr := &Pants{}

        flags := []cli.Flag{
                altsrc.NewGenericFlag(&cli.GenericFlag{Name: "pants", Value: pantsPtr}),
                &cli.StringFlag{Name: "load"},
        }

        app := &cli.App{
                Action: func(cCtx *cli.Context) error {
                        pants := cCtx.Generic("pants")
                        fmt.Printf("pants (%T): %+#v\n", pants, pants)
                        return nil
                },
                Before: altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load")),
                Flags:  flags,
        }

        if err := app.Run(os.Args); err != nil {
                log.Fatal(err)
        }
}
pants: eleven
$ go run 1072.go --load 1072.yml
2022/05/05 21:52:38 Mismatched type for flag 'pants'. Expected 'cli.Generic' but actual is 'string'
exit status 1

meatballhat avatar May 06 '22 01:05 meatballhat

@meatballhat This is actually expected behaviour. The normal yaml load can only load vanilla data types, int, float, string, intslice etc . For other complex types like Generic the default yaml loader doesnt know that it needs to deserialize, for example the pants: eleven to a &Pants{v:"eleven"}. It is the responsibility of the user to write a custom input source context(backed by map input source) which can handle the deserialization.

dearchap avatar Sep 13 '22 00:09 dearchap

@dearchap I'm glad you know how this is supposed to work! :joy: :shrug: Is it obvious that I don't use altsrc?

meatballhat avatar Sep 13 '22 03:09 meatballhat

Works as designed.

dearchap avatar Sep 20 '22 08:09 dearchap

@meatballhat This is actually expected behaviour. The normal yaml load can only load vanilla data types, int, float, string, intslice etc . For other complex types like Generic the default yaml loader doesnt know that it needs to deserialize, for example the pants: eleven to a &Pants{v:"eleven"}. It is the responsibility of the user to write a custom input source context(backed by map input source) which can handle the deserialization.

@dearchap I'm running into a similar issue. Do you have an example on how to extend the yaml loader to support deserializing to custom types?

richard-ramos avatar Jan 11 '23 15:01 richard-ramos

@richard-ramos You have to create a new yaml loader and pass in your custom struct here https://github.com/urfave/cli/blob/v2-maint/altsrc/yaml_file_loader.go#L25

That way the correct types are unmarshalled here

https://github.com/urfave/cli/blob/v2-maint/altsrc/yaml_file_loader.go#L49

Perhaps we could allow the user to pass in a custom unmarshal function. I have to think about it.

dearchap avatar Jan 14 '23 21:01 dearchap