func doPrompt()

in hgctl/pkg/plugin/install/asker.go [532:667]


func doPrompt(fieldName string, parent, schema *types.JSONSchemaProps, oriScope, selScope types.Scope, printer *utils.YesOrNoPrinter) (interface{}, error) {
	if schema.Title == "" {
		schema.Title = fieldName
	}
	if schema.Description == "" {
		schema.Description = fieldName
	}
	required := true
	if parent != nil {
		required = isRequired(fieldName, parent.Required)
	}
	msg, help := fieldTips(fieldName, parent, schema, required, printer)

	switch types.JsonType(schema.Type) {
	case types.JsonTypeObject:
		printer.Println(iconIdent + msg)
		obj := make(map[string]interface{})
		m := schema.GetPropertiesOrderMap()
		for _, name := range m.Keys() {
			propI, _ := m.Get(name)
			prop := propI.(types.JSONSchemaProps)

			if parent == nil { // keep topmost scope
				if prop.Scope == types.ScopeGlobal {
					oriScope = types.ScopeGlobal
				} else if prop.Scope == types.ScopeInstance || prop.Scope == "" {
					oriScope = types.ScopeInstance
				}
			}

			if !matchesScope(oriScope, selScope, prop.Scope) {
				continue
			}

			printer.IncIdentRepeat()
			v, err := doPrompt(name, schema, &prop, oriScope, selScope, printer)
			printer.DecIndentRepeat()
			if err != nil {
				return nil, err
			}
			if v != nil {
				obj[name] = v
			}
		}

		if len(obj) == 0 {
			return nil, nil
		}
		return obj, nil

	case types.JsonTypeArray:
		printer.Println(iconIdent + msg)
		continueA := newContinueAsker(printer)
		arr := make([]interface{}, 0)
		for {
			printer.IncIdentRepeat()
			v, err := doPrompt("item", schema, schema.Items.Schema, oriScope, selScope, printer)
			if err != nil {
				printer.DecIndentRepeat()
				return nil, err
			}
			if v != nil {
				arr = append(arr, v)
			}

			err = continueA.Ask()
			printer.DecIndentRepeat()
			if err != nil {
				return nil, err
			}

			if !continueA.resp {
				break
			}
		}

		if len(arr) == 0 {
			return nil, nil
		}
		return arr, nil

	case types.JsonTypeInteger, types.JsonTypeNumber, types.JsonTypeBoolean, types.JsonTypeString:
		for {
			var inp string
			if err := utils.AskOne(&survey.Input{
				Message: msg,
				Help:    help,
			}, &inp); err != nil {
				return nil, err
			}
			if inp == "" && !required {
				return nil, nil
			}

			switch types.JsonType(schema.Type) {
			case types.JsonTypeInteger:
				v, err := strconv.ParseInt(inp, 10, 64)
				if err != nil {
					if errors.Is(err, strconv.ErrSyntax) {
						printer.Nof("%s %q type is invalid.\n", invalidSyntax, inp)
						continue
					}
					return nil, err
				}
				return v, nil
			case types.JsonTypeNumber:
				v, err := strconv.ParseFloat(inp, 64)
				if err != nil {
					if errors.Is(err, strconv.ErrSyntax) {
						printer.Nof("%s %q type is invalid.\n", invalidSyntax, inp)
						continue
					}
					return nil, err
				}
				return v, nil
			case types.JsonTypeBoolean:
				v, err := strconv.ParseBool(inp)
				if err != nil {
					if errors.Is(err, strconv.ErrSyntax) {
						printer.Nof("%s %q type is invalid.\n", invalidSyntax, inp)
						continue
					}
					return nil, err
				}
				return v, nil
			case types.JsonTypeString:
				return inp, nil
			default:
				return inp, nil
			}
		}

	default:
		return nil, fmt.Errorf("unsupported type: %s", schema.Type)
	}
}