github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/cli/pflags/api/tag.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"strings"
     7  
     8  	"github.com/fatih/structtag"
     9  )
    10  
    11  const (
    12  	TagName     = "pflag"
    13  	JSONTagName = "json"
    14  )
    15  
    16  // Represents parsed PFlag Go-struct tag.
    17  // type Foo struct {
    18  //     StringValue      string            `json:"str" pflag:"\"hello world\",This is a string value"`
    19  // }
    20  // Name will be "str", Default value is "hello world" and Usage is "This is a string value"
    21  type Tag struct {
    22  	Name         string
    23  	DefaultValue string
    24  	Usage        string
    25  }
    26  
    27  // Parses tag. Name is computed from json tag, defaultvalue is the name of the pflag tag and usage is the concatenation
    28  // of all options for pflag tag.
    29  // e.g. `json:"name" pflag:"2,this is a useful param"`
    30  func ParseTag(tag string) (t Tag, err error) {
    31  	tags, err := structtag.Parse(tag)
    32  	if err != nil {
    33  		return Tag{}, err
    34  	}
    35  
    36  	t = Tag{}
    37  
    38  	jsonTag, err := tags.Get(JSONTagName)
    39  	if err == nil {
    40  		t.Name = jsonTag.Name
    41  	}
    42  
    43  	pflagTag, err := tags.Get(TagName)
    44  	if err == nil {
    45  		t.DefaultValue, err = url.QueryUnescape(pflagTag.Name)
    46  		if err != nil {
    47  			fmt.Printf("Failed to Query unescape tag name [%v], will use value as is. Error: %v", pflagTag.Name, err)
    48  			t.DefaultValue = pflagTag.Name
    49  		}
    50  
    51  		t.Usage = strings.Join(pflagTag.Options, ", ")
    52  		if len(t.Usage) == 0 {
    53  			t.Usage = `""`
    54  		}
    55  
    56  		if t.Usage[0] != '"' {
    57  			t.Usage = fmt.Sprintf(`"%v"`, t.Usage)
    58  		}
    59  	} else {
    60  		// We receive an error when the tag isn't present (or is malformed). Because there is no strongly-typed way to
    61  		// do that, we will just set Usage to empty string and move on.
    62  		t.Usage = `""`
    63  	}
    64  
    65  	return t, nil
    66  }