(k *Kong, node *Node, typ NodeType, v reflect.Value, ft reflect.StructField, fv reflect.Value, tag *Tag, name string, seenFlags map[string]bool)
| 247 | } |
| 248 | |
| 249 | func buildChild(k *Kong, node *Node, typ NodeType, v reflect.Value, ft reflect.StructField, fv reflect.Value, tag *Tag, name string, seenFlags map[string]bool) error { |
| 250 | child, err := buildNode(k, fv, typ, newEmptyTag(), seenFlags) |
| 251 | if err != nil { |
| 252 | return err |
| 253 | } |
| 254 | child.Name = name |
| 255 | child.Tag = tag |
| 256 | child.Parent = node |
| 257 | child.Help = tag.Help |
| 258 | child.Hidden = tag.Hidden |
| 259 | child.Group = buildGroupForKey(k, tag.Group) |
| 260 | child.Aliases = tag.Aliases |
| 261 | |
| 262 | if provider, ok := fv.Addr().Interface().(HelpProvider); ok { |
| 263 | child.Detail = provider.Help() |
| 264 | } |
| 265 | |
| 266 | // A branching argument. This is a bit hairy, as we let buildNode() do the parsing, then check that |
| 267 | // a positional argument is provided to the child, and move it to the branching argument field. |
| 268 | if tag.Arg { |
| 269 | if len(child.Positional) == 0 { |
| 270 | return failField(v, ft, "positional branch must have at least one child positional argument named %q", name) |
| 271 | } |
| 272 | if child.Positional[0].Name != name { |
| 273 | return failField(v, ft, "first field in positional branch must have the same name as the parent field (%s).", child.Name) |
| 274 | } |
| 275 | |
| 276 | child.Argument = child.Positional[0] |
| 277 | child.Positional = child.Positional[1:] |
| 278 | if child.Help == "" { |
| 279 | child.Help = child.Argument.Help |
| 280 | } |
| 281 | } else { |
| 282 | if tag.HasDefault { |
| 283 | if node.DefaultCmd != nil { |
| 284 | return failField(v, ft, "can't have more than one default command under %s", node.Summary()) |
| 285 | } |
| 286 | if tag.Default != "withargs" && (len(child.Children) > 0 || len(child.Positional) > 0) { |
| 287 | return failField(v, ft, "default command %s must not have subcommands or arguments", child.Summary()) |
| 288 | } |
| 289 | node.DefaultCmd = child |
| 290 | } |
| 291 | if tag.Passthrough { |
| 292 | if len(child.Children) > 0 || len(child.Flags) > 0 { |
| 293 | return failField(v, ft, "passthrough command %s must not have subcommands or flags", child.Summary()) |
| 294 | } |
| 295 | if len(child.Positional) != 1 { |
| 296 | return failField(v, ft, "passthrough command %s must contain exactly one positional argument", child.Summary()) |
| 297 | } |
| 298 | if !checkPassthroughArg(child.Positional[0].Target) { |
| 299 | return failField(v, ft, "passthrough command %s must contain exactly one positional argument of []string type", child.Summary()) |
| 300 | } |
| 301 | child.Passthrough = true |
| 302 | } |
| 303 | } |
| 304 | node.Children = append(node.Children, child) |
| 305 | |
| 306 | if len(child.Positional) > 0 && len(child.Children) > 0 { |
no test coverage detected
searching dependent graphs…