(block *configBlock, cfg any, flags map[uintptr]*flag.Flag, addedRootBlocks map[string]struct{})
| 74 | } |
| 75 | |
| 76 | func parseConfig(block *configBlock, cfg any, flags map[uintptr]*flag.Flag, addedRootBlocks map[string]struct{}) ([]*configBlock, error) { |
| 77 | blocks := []*configBlock{} |
| 78 | |
| 79 | // If the input block is nil it means we're generating the doc for the top-level block |
| 80 | if block == nil { |
| 81 | block = &configBlock{} |
| 82 | blocks = append(blocks, block) |
| 83 | } |
| 84 | |
| 85 | // The input config is expected to be addressable. |
| 86 | if reflect.TypeOf(cfg).Kind() != reflect.Ptr { |
| 87 | t := reflect.TypeOf(cfg) |
| 88 | return nil, fmt.Errorf("%s is a %s while a %s is expected", t, t.Kind(), reflect.Ptr) |
| 89 | } |
| 90 | |
| 91 | // The input config is expected to be a pointer to struct. |
| 92 | v := reflect.ValueOf(cfg).Elem() |
| 93 | t := v.Type() |
| 94 | |
| 95 | if v.Kind() != reflect.Struct { |
| 96 | return nil, fmt.Errorf("%s is a %s while a %s is expected", v, v.Kind(), reflect.Struct) |
| 97 | } |
| 98 | |
| 99 | for i := 0; i < t.NumField(); i++ { |
| 100 | field := t.Field(i) |
| 101 | fieldValue := v.FieldByIndex(field.Index) |
| 102 | |
| 103 | // Skip fields explicitly marked as "hidden" in the doc |
| 104 | if isFieldHidden(field) { |
| 105 | continue |
| 106 | } |
| 107 | |
| 108 | // Skip fields not exported via yaml (unless they're inline) |
| 109 | fieldName := getFieldName(field) |
| 110 | if fieldName == "" && !isFieldInline(field) { |
| 111 | continue |
| 112 | } |
| 113 | |
| 114 | // Skip field types which are non configurable |
| 115 | if field.Type.Kind() == reflect.Func || field.Type.Kind() == reflect.Pointer { |
| 116 | continue |
| 117 | } |
| 118 | |
| 119 | // Skip deprecated fields we're still keeping for backward compatibility |
| 120 | // reasons (by convention we prefix them by UnusedFlag) |
| 121 | if strings.HasPrefix(field.Name, "UnusedFlag") { |
| 122 | continue |
| 123 | } |
| 124 | |
| 125 | // Handle custom fields in vendored libs upon which we have no control. |
| 126 | fieldEntry, err := getCustomFieldEntry(t, field, fieldValue, flags) |
| 127 | if err != nil { |
| 128 | return nil, err |
| 129 | } |
| 130 | if fieldEntry != nil { |
| 131 | block.Add(fieldEntry) |
| 132 | continue |
| 133 | } |
no test coverage detected