<commit_before>// Package redialer provides a generic redialer for connection-like types in Go.
// It is useful when you need to access a connection from multiple goroutines.
// It helps to keep the reconnection logic in a single goroutine and provide protected access to the connection.
//
// See netredialer subpackage for usage example.
package redialer

import (
	"io"
	"log"
	"sync"
	"time"
)

// Redialer keeps connections connected.
type Redialer struct {
	dialer Dialer
	conn   io.Closer
	closed bool
	m      sync.Mutex
	cond   sync.Cond
}

type Dialer interface {
	Addr() string // used in logs
	Dial() (conn io.Closer, err error)
}

type Conn struct {
	redialer      *Redialer
	connectedConn io.Closer
}

// Get returns the connected connection.
// You have to convert the returned value to the type your Dial function returns.
func (c *Conn) Get() interface{} {
	return c.connectedConn
}

// SetClosed tells Redialer that the connection is closed.
// You have to call this function after your code detected the connection is disconnected.
func (c *Conn) SetClosed() {
	c.redialer.connClosed(c)
}

func New(d Dialer) *Redialer {
	r := &Redialer{
		dialer: d,
	}
	r.cond.L = &r.m
	return r
}

// Conn sends the connected connection on the returned channel.
// Only one Conn will be sent to the channel.
// If the Redialer is closed, the channel is closed.
func (r *Redialer) Conn() <-chan *Conn {
	ch := make(chan *Conn, 1)
	go r.notifyConn(ch)
	return ch
}

func (r *Redialer) notifyConn(ch chan<- *Conn) {
	r.m.Lock()
	defer r.m.Unlock()
	for r.conn == nil && !r.closed {
		r.cond.Wait()
	}
	if r.closed {
		close(ch)
		return
	}
	ch <- &Conn{
		redialer:      r,
		connectedConn: r.conn,
	}
}

// Close stops the Redialer and closes the connection if it is open.
func (r *Redialer) Close() error {
	r.m.Lock()
	defer r.m.Unlock()
	defer r.cond.Broadcast()
	r.closed = true
	if r.conn == nil {
		return nil
	}
	return r.conn.Close()
}

func (r *Redialer) Run() {
	for {
		r.m.Lock()
		for r.conn != nil && !r.closed {
			r.cond.Wait()
		}
		if r.closed {
			if r.conn != nil {
				r.conn.Close()
			}
			r.m.Unlock()
			break
		}
		r.m.Unlock()

		var conn io.Closer
		for {
			r.m.Lock()
			closed := r.closed
			r.m.Unlock()
			if closed {
				break
			}

			log.Println("connecting to", r.dialer.Addr())
			var err error
			conn, err = r.dialer.Dial()
			if err != nil {
				conn = nil // implementation may return non-nil value on error
				log.Println("cannot connect to", r.dialer.Addr(), "err:", err)
				time.Sleep(time.Second)
				continue
			}
			break
		}

		log.Println("connected to", r.dialer.Addr())
		r.m.Lock()
		r.conn = conn
		r.m.Unlock()
		r.cond.Broadcast()
	}
}

func (r *Redialer) connClosed(conn *Conn) {
	r.m.Lock()
	defer r.m.Unlock()
	if conn.connectedConn == r.conn {
		r.conn = nil
		log.Println("disconnected from", r.dialer.Addr())
		r.cond.Broadcast()
	}
}
<commit_msg>comment exported functions<commit_after>// Package redialer provides a generic redialer for connection-like types in Go.
// It is useful when you need to access a connection from multiple goroutines.
// It helps to keep the reconnection logic in a single goroutine and provide protected access to the connection.
//
// See netredialer subpackage for usage example.
package redialer

import (
	"io"
	"log"
	"sync"
	"time"
)

// Redialer keeps connections connected.
type Redialer struct {
	dialer Dialer
	conn   io.Closer
	closed bool
	m      sync.Mutex
	cond   sync.Cond
}

// Dialer is the interface passed to New function.
type Dialer interface {
	Addr() string // used in logs
	Dial() (conn io.Closer, err error)
}

// Conn is the type that is returned from Redialer.Conn method.
type Conn struct {
	redialer      *Redialer
	connectedConn io.Closer
}

// Get returns the connected connection.
// You have to convert the returned value to the type your Dial function returns.
func (c *Conn) Get() interface{} {
	return c.connectedConn
}

// SetClosed tells Redialer that the connection is closed.
// You have to call this function after your code detected the connection is disconnected.
func (c *Conn) SetClosed() {
	c.redialer.connClosed(c)
}

// New returns a new Redialer from Dialer.
func New(d Dialer) *Redialer {
	r := &Redialer{
		dialer: d,
	}
	r.cond.L = &r.m
	return r
}

// Conn sends the connected connection on the returned channel.
// Only one Conn will be sent to the channel.
// If the Redialer is closed, the channel is closed.
func (r *Redialer) Conn() <-chan *Conn {
	ch := make(chan *Conn, 1)
	go r.notifyConn(ch)
	return ch
}

func (r *Redialer) notifyConn(ch chan<- *Conn) {
	r.m.Lock()
	defer r.m.Unlock()
	for r.conn == nil && !r.closed {
		r.cond.Wait()
	}
	if r.closed {
		close(ch)
		return
	}
	ch <- &Conn{
		redialer:      r,
		connectedConn: r.conn,
	}
}

// Close stops the Redialer and closes the connection if it is open.
func (r *Redialer) Close() error {
	r.m.Lock()
	defer r.m.Unlock()
	defer r.cond.Broadcast()
	r.closed = true
	if r.conn == nil {
		return nil
	}
	return r.conn.Close()
}

// Run the reconnection loop. Call this with a go statement.
func (r *Redialer) Run() {
	for {
		r.m.Lock()
		for r.conn != nil && !r.closed {
			r.cond.Wait()
		}
		if r.closed {
			if r.conn != nil {
				r.conn.Close()
			}
			r.m.Unlock()
			break
		}
		r.m.Unlock()

		var conn io.Closer
		for {
			r.m.Lock()
			closed := r.closed
			r.m.Unlock()
			if closed {
				break
			}

			log.Println("connecting to", r.dialer.Addr())
			var err error
			conn, err = r.dialer.Dial()
			if err != nil {
				conn = nil // implementation may return non-nil value on error
				log.Println("cannot connect to", r.dialer.Addr(), "err:", err)
				time.Sleep(time.Second)
				continue
			}
			break
		}

		log.Println("connected to", r.dialer.Addr())
		r.m.Lock()
		r.conn = conn
		r.m.Unlock()
		r.cond.Broadcast()
	}
}

func (r *Redialer) connClosed(conn *Conn) {
	r.m.Lock()
	defer r.m.Unlock()
	if conn.connectedConn == r.conn {
		r.conn = nil
		log.Println("disconnected from", r.dialer.Addr())
		r.cond.Broadcast()
	}
}
<|endoftext|>


<commit_before>package cfnextract

import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"strconv"
	"strings"

	"github.com/NeowayLabs/clinit-cfn-tool/utils"
	"github.com/jteeuwen/go-pkg-optarg"
)

func getAwsResources(awsMap map[string]interface{}) (map[string]interface{}, error) {
	for k, v := range awsMap {
		if k == "Resources" {
			return v.(map[string]interface{}), nil
		}
	}

	return awsMap, errors.New("Resources not found...")
}

func getAwsUserData(awsMap map[string]interface{}) []map[string]interface{} {
	var tmp map[string]interface{}
	userDataArr := make([]map[string]interface{}, 0, 0)
	userDataArr2 := make([]map[string]interface{}, 0, 0)

	resources := awsMap["Resources"].(map[string]interface{})

	if resources == nil {
		fmt.Println("AWS CloudFormation Resources not found...")
		return userDataArr
	}

	for kk, vv := range resources {
		tmp = vv.(map[string]interface{})
		if tmp["Properties"] != nil {
			tmp := tmp["Properties"].(map[string]interface{})
			if tmp == nil {
				fmt.Printf("Resource '%s' doesn't have UserData\n", kk)
				continue
			}

			if tmp["UserData"] != nil {
				tmp = tmp["UserData"].(map[string]interface{})
				userDataArr2 = make([]map[string]interface{}, len(userDataArr)+1, len(userDataArr)+1)
				for i := range userDataArr {
					userDataArr2[i] = userDataArr[i]
				}

				userDataArr2[len(userDataArr)] = tmp
				userDataArr = userDataArr2
			}
		} else {
			fmt.Printf("Resource '%s' doesn't have Properties\n", kk)
		}
	}

	return userDataArr
}

func JoinCfnUserData(userData map[string]interface{}) (string, error) {
	var tmp map[string]interface{}

	if userData["Fn::Base64"] == nil {
		return "", errors.New("UserData doesn't have Fn::Base64 field")
	}

	tmp = userData["Fn::Base64"].(map[string]interface{})

	if tmp["Fn::Join"] == nil {
		return "", errors.New("UserData doesn-t have Fn::Join field")
	}

	tmpArr := tmp["Fn::Join"].([]interface{})

	// TODO: Review this assertion
	if len(tmpArr) <= 0 {
		return "", errors.New("Empty UserData string")
	}

	tmpArr2 := tmpArr[1].([]interface{})

	cloudInitData := make([]string, len(tmpArr2))

	for i, elem := range tmpArr2 {
		if elemStr, ok := elem.(string); ok {
			cloudInitData[i] = elemStr
		} else {
			specialAwsFunc, ok := elem.(map[string]interface{})

			if !ok {
				return "", fmt.Errorf("Unsupported value: ", specialAwsFunc)
			}

			if len(specialAwsFunc) != 1 {
				return "", fmt.Errorf("Unsupported special variable: %s", specialAwsFunc)
			}

			for f, awsValue := range specialAwsFunc {
				v := reflect.TypeOf(awsValue)

				switch v.Kind() {
				case reflect.Slice:
					funcArr := awsValue.([]interface{})
					funcArrStr := make([]string, len(funcArr))
					for ii := range funcArr {
						funcArrStr[ii] = funcArr[ii].(string)
					}

					cloudInitData[i] = "{{ ." + f + "." + strings.Join(funcArrStr, ".") + " }}"
				case reflect.String:
					cloudInitData[i] = "{{ ." + f + "." + awsValue.(string) + " }}"
				default:
					return "", fmt.Errorf("Unsupported special variable of type '%': %s: %s", v, f, awsValue)
				}
			}
		}
	}

	return strings.Join(cloudInitData, ""), nil
}

func handleUserData(userData map[string]interface{}) string {
	userDataStr, err := JoinCfnUserData(userData)

	if err != nil {
		utils.Check(err)
	}

	return userDataStr
}

func ExtractCloudinit(baseCloudinitPath string, awsFormationPath string) bool {
	awsFormationContentStr := utils.ReadFile(awsFormationPath)
	awsMapInt, err := utils.DecodeJson([]byte(awsFormationContentStr))

	if err != nil {
		fmt.Println(err)
		panic(err)
	}
	awsMap := awsMapInt.(map[string]interface{})

	if err != nil {
		fmt.Errorf("Failed to decode Json")
		return false
	}

	userData := getAwsUserData(awsMap)
	cloudInitDataArr := make([]string, len(userData), len(userData))

	for i := range userData {
		cloudInitDataArr[i] = handleUserData(userData[i])
	}

	for i := range cloudInitDataArr {
		outPath := baseCloudinitPath + strconv.Itoa(i+1) + ".yaml"
		fmt.Printf("Generating file '%s'\n", outPath)
		err := utils.SaveOutput(outPath, cloudInitDataArr[i])

		utils.Check(err)
	}

	return true
}

func Extract() {
	var baseCloudinitPath, awsFormationPath string
	var helpOpt, missingOpts bool

	optarg.Add("h", "help", "Displays this help", false)
	optarg.Add("o", "output-base-path", "Output base path name.", "")
	optarg.Add("i", "cloud-formation", "CloudFormation input file", "")

	for opt := range optarg.Parse() {
		switch opt.ShortName {
		case "o":
			baseCloudinitPath = opt.String()
		case "i":
			awsFormationPath = opt.String()
		case "h":
			helpOpt = opt.Bool()

		default:
			fmt.Println("Invalid flag: ", opt)
			optarg.Usage()
			os.Exit(1)
		}
	}

	if helpOpt {
		optarg.Usage()
		os.Exit(0)
	}

	if baseCloudinitPath == "" {
		fmt.Println("-o is required...")
		missingOpts = true
	}

	if awsFormationPath == "" {
		fmt.Println("-i is required...")
		missingOpts = true
	}

	if missingOpts {
		optarg.Usage()
		os.Exit(1)
	}

	if os.Getenv("DEBUG_OPTS") != "" {
		fmt.Println(baseCloudinitPath)
		fmt.Println(awsFormationPath)
	}

	ExtractCloudinit(baseCloudinitPath, awsFormationPath)
}
<commit_msg>[CHANGE] improve panic log<commit_after>package cfnextract

import (
	"errors"
	"fmt"
	"os"
	"reflect"
	"strconv"
	"strings"

	"github.com/NeowayLabs/clinit-cfn-tool/utils"
	"github.com/jteeuwen/go-pkg-optarg"
)

func getAwsResources(awsMap map[string]interface{}) (map[string]interface{}, error) {
	for k, v := range awsMap {
		if k == "Resources" {
			return v.(map[string]interface{}), nil
		}
	}

	return awsMap, errors.New("Resources not found...")
}

func getAwsUserData(awsMap map[string]interface{}) []map[string]interface{} {
	var tmp map[string]interface{}
	userDataArr := make([]map[string]interface{}, 0, 0)
	userDataArr2 := make([]map[string]interface{}, 0, 0)

	resources := awsMap["Resources"].(map[string]interface{})

	if resources == nil {
		fmt.Println("AWS CloudFormation Resources not found...")
		return userDataArr
	}

	for kk, vv := range resources {
		tmp = vv.(map[string]interface{})
		if tmp["Properties"] != nil {
			tmp := tmp["Properties"].(map[string]interface{})
			if tmp == nil {
				fmt.Printf("Resource '%s' doesn't have UserData\n", kk)
				continue
			}

			if tmp["UserData"] != nil {
				tmp = tmp["UserData"].(map[string]interface{})
				userDataArr2 = make([]map[string]interface{}, len(userDataArr)+1, len(userDataArr)+1)
				for i := range userDataArr {
					userDataArr2[i] = userDataArr[i]
				}

				userDataArr2[len(userDataArr)] = tmp
				userDataArr = userDataArr2
			}
		} else {
			fmt.Printf("Resource '%s' doesn't have Properties\n", kk)
		}
	}

	return userDataArr
}

func JoinCfnUserData(userData map[string]interface{}) (string, error) {
	var tmp map[string]interface{}

	if userData["Fn::Base64"] == nil {
		return "", errors.New("UserData doesn't have Fn::Base64 field")
	}

	tmp = userData["Fn::Base64"].(map[string]interface{})

	if tmp["Fn::Join"] == nil {
		return "", errors.New("UserData doesn-t have Fn::Join field")
	}

	tmpArr := tmp["Fn::Join"].([]interface{})

	// TODO: Review this assertion
	if len(tmpArr) <= 0 {
		return "", errors.New("Empty UserData string")
	}

	tmpArr2 := tmpArr[1].([]interface{})

	cloudInitData := make([]string, len(tmpArr2))

	for i, elem := range tmpArr2 {
		if elemStr, ok := elem.(string); ok {
			cloudInitData[i] = elemStr
		} else {
			specialAwsFunc, ok := elem.(map[string]interface{})

			if !ok {
				return "", fmt.Errorf("Unsupported value: ", specialAwsFunc)
			}

			if len(specialAwsFunc) != 1 {
				return "", fmt.Errorf("Unsupported special variable: %s", specialAwsFunc)
			}

			for f, awsValue := range specialAwsFunc {
				v := reflect.TypeOf(awsValue)

				switch v.Kind() {
				case reflect.Slice:
					funcArr := awsValue.([]interface{})
					funcArrStr := make([]string, len(funcArr))
					for ii := range funcArr {
						funcArrStr[ii] = funcArr[ii].(string)
					}

					cloudInitData[i] = "{{ ." + f + "." + strings.Join(funcArrStr, ".") + " }}"
				case reflect.String:
					cloudInitData[i] = "{{ ." + f + "." + awsValue.(string) + " }}"
				default:
					return "", fmt.Errorf("Unsupported special variable of type '%': %s: %s", v, f, awsValue)
				}
			}
		}
	}

	return strings.Join(cloudInitData, ""), nil
}

func handleUserData(userData map[string]interface{}) string {
	userDataStr, err := JoinCfnUserData(userData)

	if err != nil {
		utils.Check(err)
	}

	return userDataStr
}

func ExtractCloudinit(baseCloudinitPath string, awsFormationPath string) bool {
	awsFormationContentStr := utils.ReadFile(awsFormationPath)
	awsMapInt, err := utils.DecodeJson([]byte(awsFormationContentStr))

	if err != nil {
		fmt.Println("Failed to decode JSON: %s", err.Error())
		panic(err)
	}
	awsMap := awsMapInt.(map[string]interface{})

	if err != nil {
		fmt.Errorf("Failed to decode Json")
		return false
	}

	userData := getAwsUserData(awsMap)
	cloudInitDataArr := make([]string, len(userData), len(userData))

	for i := range userData {
		cloudInitDataArr[i] = handleUserData(userData[i])
	}

	for i := range cloudInitDataArr {
		outPath := baseCloudinitPath + strconv.Itoa(i+1) + ".yaml"
		fmt.Printf("Generating file '%s'\n", outPath)
		err := utils.SaveOutput(outPath, cloudInitDataArr[i])

		utils.Check(err)
	}

	return true
}

func Extract() {
	var baseCloudinitPath, awsFormationPath string
	var helpOpt, missingOpts bool

	optarg.Add("h", "help", "Displays this help", false)
	optarg.Add("o", "output-base-path", "Output base path name.", "")
	optarg.Add("i", "cloud-formation", "CloudFormation input file", "")

	for opt := range optarg.Parse() {
		switch opt.ShortName {
		case "o":
			baseCloudinitPath = opt.String()
		case "i":
			awsFormationPath = opt.String()
		case "h":
			helpOpt = opt.Bool()

		default:
			fmt.Println("Invalid flag: ", opt)
			optarg.Usage()
			os.Exit(1)
		}
	}

	if helpOpt {
		optarg.Usage()
		os.Exit(0)
	}

	if baseCloudinitPath == "" {
		fmt.Println("-o is required...")
		missingOpts = true
	}

	if awsFormationPath == "" {
		fmt.Println("-i is required...")
		missingOpts = true
	}

	if missingOpts {
		optarg.Usage()
		os.Exit(1)
	}

	if os.Getenv("DEBUG_OPTS") != "" {
		fmt.Println(baseCloudinitPath)
		fmt.Println(awsFormationPath)
	}

	ExtractCloudinit(baseCloudinitPath, awsFormationPath)
}
<|endoftext|>


<commit_before>package dry

import (
	"fmt"
	"reflect"
	"sort"
	"unicode"
)

// ReflectTypeOfError returns the built-in error type
func ReflectTypeOfError() reflect.Type {
	return reflect.TypeOf((*error)(nil)).Elem()
}

// ReflectSetStructFieldsFromStringMap sets the fields of a struct
// with the field names and values taken from a map[string]string.
// If errOnMissingField is true, then all fields must exist.
func ReflectSetStructFieldsFromStringMap(structPtr interface{}, m map[string]string, errOnMissingField bool) error {
	v := reflect.ValueOf(structPtr)
	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("structPtr must be pointer to a struct, but is %T", structPtr)
	}
	v = v.Elem()

	for name, value := range m {
		if f := v.FieldByName(name); f.IsValid() {
			if f.Kind() == reflect.String {
				f.SetString(value)
			} else {
				_, err := fmt.Sscan(value, f.Addr().Interface())
				if err != nil {
					return err
				}
			}
		} else if errOnMissingField {
			return fmt.Errorf("%T has no struct field '%s'", v.Interface(), name)
		}
	}

	return nil
}

/*
ExportedStructFields returns a map from exported struct field names to values,
inlining anonymous sub-structs so that their field names are available
at the base level.
Example:
	type A struct {
		X int
	}
	type B Struct {
		A
		Y int
	}
	// Yields X and Y instead of A and Y:
	ReflectExportedStructFields(reflect.ValueOf(B{}))
*/
func ReflectExportedStructFields(v reflect.Value) map[string]reflect.Value {
	t := v.Type()
	if t.Kind() != reflect.Struct {
		panic(fmt.Errorf("Expected a struct, got %s", t))
	}
	result := make(map[string]reflect.Value)
	reflectExportedStructFields(v, t, result)
	return result
}

func reflectExportedStructFields(v reflect.Value, t reflect.Type, result map[string]reflect.Value) {
	for i := 0; i < t.NumField(); i++ {
		structField := t.Field(i)
		if ReflectStructFieldIsExported(structField) {
			if structField.Anonymous && structField.Type.Kind() == reflect.Struct {
				reflectExportedStructFields(v.Field(i), structField.Type, result)
			} else {
				result[structField.Name] = v.Field(i)
			}
		}
	}
}

func ReflectNameIsExported(name string) bool {
	return name != "" && unicode.IsUpper(rune(name[0]))
}

func ReflectStructFieldIsExported(structField reflect.StructField) bool {
	return structField.PkgPath == ""
}

// ReflectSort will sort slice according to compareFunc using reflection.
// slice can be a slice of any element type including interface{}.
// compareFunc must have two arguments that are assignable from
// the slice element type or pointers to such a type.
// The result of compareFunc must be a bool indicating
// if the first argument is less than the second.
// If the element type of slice is interface{}, then the type
// of the compareFunc arguments can be any type and dynamic
// casting from the interface value or its address will be attempted.
func ReflectSort(slice, compareFunc interface{}) {
	sortable, err := newReflectSortable(slice, compareFunc)
	if err != nil {
		panic(err)
	}
	sort.Sort(sortable)
}

func newReflectSortable(slice, compareFunc interface{}) (*reflectSortable, error) {
	t := reflect.TypeOf(compareFunc)
	if t.Kind() != reflect.Func {
		return nil, fmt.Errorf("compareFunc must be a function, got %T", compareFunc)
	}
	if t.NumIn() != 2 {
		return nil, fmt.Errorf("compareFunc must take two arguments, got %d", t.NumIn())
	}
	if t.In(0) != t.In(1) {
		return nil, fmt.Errorf("compareFunc's arguments must be identical, got %s and %s", t.In(0), t.In(1))
	}
	if t.NumOut() != 1 {
		return nil, fmt.Errorf("compareFunc must have one result, got %d", t.NumOut())
	}
	if t.Out(0).Kind() != reflect.Bool {
		return nil, fmt.Errorf("compareFunc result must be bool, got %s", t.Out(0))
	}

	argType := t.In(0)
	ptrArgs := argType.Kind() == reflect.Ptr
	if ptrArgs {
		argType = argType.Elem()
	}

	sliceV := reflect.ValueOf(slice)
	if sliceV.Kind() != reflect.Slice {
		return nil, fmt.Errorf("Need slice got %T", slice)
	}
	elemT := sliceV.Type().Elem()
	if elemT != argType && elemT.Kind() != reflect.Interface {
		return nil, fmt.Errorf("Slice element type must be interface{} or %s, got %s", argType, elemT)
	}

	return &reflectSortable{
		Slice:       sliceV,
		CompareFunc: reflect.ValueOf(compareFunc),
		ArgType:     argType,
		PtrArgs:     ptrArgs,
	}, nil
}

type reflectSortable struct {
	Slice       reflect.Value
	CompareFunc reflect.Value
	ArgType     reflect.Type
	PtrArgs     bool
}

func (self *reflectSortable) Len() int {
	return self.Slice.Len()
}

func (self *reflectSortable) Less(i, j int) bool {
	arg0 := self.Slice.Index(i)
	arg1 := self.Slice.Index(j)
	if self.Slice.Type().Elem().Kind() == reflect.Interface {
		arg0 = arg0.Elem()
		arg1 = arg1.Elem()
	}
	if (arg0.Kind() == reflect.Ptr) != self.PtrArgs {
		if self.PtrArgs {
			// Expects PtrArgs for reflectSortable, but Slice is value type
			arg0 = arg0.Addr()
		} else {
			// Expects value type for reflectSortable, but Slice is PtrArgs
			arg0 = arg0.Elem()
		}
	}
	if (arg1.Kind() == reflect.Ptr) != self.PtrArgs {
		if self.PtrArgs {
			// Expects PtrArgs for reflectSortable, but Slice is value type
			arg1 = arg1.Addr()
		} else {
			// Expects value type for reflectSortable, but Slice is PtrArgs
			arg1 = arg1.Elem()
		}
	}
	return self.CompareFunc.Call([]reflect.Value{arg0, arg1})[0].Bool()
}

func (self *reflectSortable) Swap(i, j int) {
	temp := self.Slice.Index(i).Interface()
	self.Slice.Index(i).Set(self.Slice.Index(j))
	self.Slice.Index(j).Set(reflect.ValueOf(temp))
}

// InterfaceSlice converts a slice of any type into a slice of interface{}.
func InterfaceSlice(slice interface{}) []interface{} {
	v := reflect.ValueOf(slice)
	if v.Kind() != reflect.Slice {
		panic(fmt.Errorf("InterfaceSlice: not a slice but %T", slice))
	}
	result := make([]interface{}, v.Len())
	for i := range result {
		result[i] = v.Index(i).Interface()
	}
	return result
}

func IsZero(value interface{}) bool {
	if value == nil {
		return true
	}

	v := reflect.ValueOf(value)
	// if IsFakeZero(v) {
	// 	return true
	// }

	switch v.Kind() {
	case reflect.String:
		return v.Len() == 0

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.Uint() == 0

	case reflect.Float32, reflect.Float64:
		return v.Float() == 0

	case reflect.Bool:
		return v.Bool() == false

	case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
		return v.IsNil()

	case reflect.Struct:
		return reflect.DeepEqual(value, reflect.Zero(v.Type()).Interface())
	}

	panic(fmt.Errorf("Unknown value kind %T", value))
}
<commit_msg>added ReflectSetStructFieldString<commit_after>package dry

import (
	"fmt"
	"reflect"
	"sort"
	"unicode"
)

// ReflectTypeOfError returns the built-in error type
func ReflectTypeOfError() reflect.Type {
	return reflect.TypeOf((*error)(nil)).Elem()
}

// ReflectSetStructFieldString sets the field with name to value.
func ReflectSetStructFieldString(structPtr interface{}, name, value string) error {
	v := reflect.ValueOf(structPtr)
	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("structPtr must be pointer to a struct, but is %T", structPtr)
	}
	v = v.Elem()

	if f := v.FieldByName(name); f.IsValid() {
		if f.Kind() == reflect.String {
			f.SetString(value)
		} else {
			_, err := fmt.Sscan(value, f.Addr().Interface())
			if err != nil {
				return err
			}
		}
	} else {
		return fmt.Errorf("%T has no struct field '%s'", v.Interface(), name)
	}

	return nil
}

// ReflectSetStructFieldsFromStringMap sets the fields of a struct
// with the field names and values taken from a map[string]string.
// If errOnMissingField is true, then all fields must exist.
func ReflectSetStructFieldsFromStringMap(structPtr interface{}, m map[string]string, errOnMissingField bool) error {
	v := reflect.ValueOf(structPtr)
	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("structPtr must be pointer to a struct, but is %T", structPtr)
	}
	v = v.Elem()

	for name, value := range m {
		if f := v.FieldByName(name); f.IsValid() {
			if f.Kind() == reflect.String {
				f.SetString(value)
			} else {
				_, err := fmt.Sscan(value, f.Addr().Interface())
				if err != nil {
					return err
				}
			}
		} else if errOnMissingField {
			return fmt.Errorf("%T has no struct field '%s'", v.Interface(), name)
		}
	}

	return nil
}

/*
ExportedStructFields returns a map from exported struct field names to values,
inlining anonymous sub-structs so that their field names are available
at the base level.
Example:
	type A struct {
		X int
	}
	type B Struct {
		A
		Y int
	}
	// Yields X and Y instead of A and Y:
	ReflectExportedStructFields(reflect.ValueOf(B{}))
*/
func ReflectExportedStructFields(v reflect.Value) map[string]reflect.Value {
	t := v.Type()
	if t.Kind() != reflect.Struct {
		panic(fmt.Errorf("Expected a struct, got %s", t))
	}
	result := make(map[string]reflect.Value)
	reflectExportedStructFields(v, t, result)
	return result
}

func reflectExportedStructFields(v reflect.Value, t reflect.Type, result map[string]reflect.Value) {
	for i := 0; i < t.NumField(); i++ {
		structField := t.Field(i)
		if ReflectStructFieldIsExported(structField) {
			if structField.Anonymous && structField.Type.Kind() == reflect.Struct {
				reflectExportedStructFields(v.Field(i), structField.Type, result)
			} else {
				result[structField.Name] = v.Field(i)
			}
		}
	}
}

func ReflectNameIsExported(name string) bool {
	return name != "" && unicode.IsUpper(rune(name[0]))
}

func ReflectStructFieldIsExported(structField reflect.StructField) bool {
	return structField.PkgPath == ""
}

// ReflectSort will sort slice according to compareFunc using reflection.
// slice can be a slice of any element type including interface{}.
// compareFunc must have two arguments that are assignable from
// the slice element type or pointers to such a type.
// The result of compareFunc must be a bool indicating
// if the first argument is less than the second.
// If the element type of slice is interface{}, then the type
// of the compareFunc arguments can be any type and dynamic
// casting from the interface value or its address will be attempted.
func ReflectSort(slice, compareFunc interface{}) {
	sortable, err := newReflectSortable(slice, compareFunc)
	if err != nil {
		panic(err)
	}
	sort.Sort(sortable)
}

func newReflectSortable(slice, compareFunc interface{}) (*reflectSortable, error) {
	t := reflect.TypeOf(compareFunc)
	if t.Kind() != reflect.Func {
		return nil, fmt.Errorf("compareFunc must be a function, got %T", compareFunc)
	}
	if t.NumIn() != 2 {
		return nil, fmt.Errorf("compareFunc must take two arguments, got %d", t.NumIn())
	}
	if t.In(0) != t.In(1) {
		return nil, fmt.Errorf("compareFunc's arguments must be identical, got %s and %s", t.In(0), t.In(1))
	}
	if t.NumOut() != 1 {
		return nil, fmt.Errorf("compareFunc must have one result, got %d", t.NumOut())
	}
	if t.Out(0).Kind() != reflect.Bool {
		return nil, fmt.Errorf("compareFunc result must be bool, got %s", t.Out(0))
	}

	argType := t.In(0)
	ptrArgs := argType.Kind() == reflect.Ptr
	if ptrArgs {
		argType = argType.Elem()
	}

	sliceV := reflect.ValueOf(slice)
	if sliceV.Kind() != reflect.Slice {
		return nil, fmt.Errorf("Need slice got %T", slice)
	}
	elemT := sliceV.Type().Elem()
	if elemT != argType && elemT.Kind() != reflect.Interface {
		return nil, fmt.Errorf("Slice element type must be interface{} or %s, got %s", argType, elemT)
	}

	return &reflectSortable{
		Slice:       sliceV,
		CompareFunc: reflect.ValueOf(compareFunc),
		ArgType:     argType,
		PtrArgs:     ptrArgs,
	}, nil
}

type reflectSortable struct {
	Slice       reflect.Value
	CompareFunc reflect.Value
	ArgType     reflect.Type
	PtrArgs     bool
}

func (self *reflectSortable) Len() int {
	return self.Slice.Len()
}

func (self *reflectSortable) Less(i, j int) bool {
	arg0 := self.Slice.Index(i)
	arg1 := self.Slice.Index(j)
	if self.Slice.Type().Elem().Kind() == reflect.Interface {
		arg0 = arg0.Elem()
		arg1 = arg1.Elem()
	}
	if (arg0.Kind() == reflect.Ptr) != self.PtrArgs {
		if self.PtrArgs {
			// Expects PtrArgs for reflectSortable, but Slice is value type
			arg0 = arg0.Addr()
		} else {
			// Expects value type for reflectSortable, but Slice is PtrArgs
			arg0 = arg0.Elem()
		}
	}
	if (arg1.Kind() == reflect.Ptr) != self.PtrArgs {
		if self.PtrArgs {
			// Expects PtrArgs for reflectSortable, but Slice is value type
			arg1 = arg1.Addr()
		} else {
			// Expects value type for reflectSortable, but Slice is PtrArgs
			arg1 = arg1.Elem()
		}
	}
	return self.CompareFunc.Call([]reflect.Value{arg0, arg1})[0].Bool()
}

func (self *reflectSortable) Swap(i, j int) {
	temp := self.Slice.Index(i).Interface()
	self.Slice.Index(i).Set(self.Slice.Index(j))
	self.Slice.Index(j).Set(reflect.ValueOf(temp))
}

// InterfaceSlice converts a slice of any type into a slice of interface{}.
func InterfaceSlice(slice interface{}) []interface{} {
	v := reflect.ValueOf(slice)
	if v.Kind() != reflect.Slice {
		panic(fmt.Errorf("InterfaceSlice: not a slice but %T", slice))
	}
	result := make([]interface{}, v.Len())
	for i := range result {
		result[i] = v.Index(i).Interface()
	}
	return result
}

func IsZero(value interface{}) bool {
	if value == nil {
		return true
	}

	v := reflect.ValueOf(value)
	// if IsFakeZero(v) {
	// 	return true
	// }

	switch v.Kind() {
	case reflect.String:
		return v.Len() == 0

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		return v.Uint() == 0

	case reflect.Float32, reflect.Float64:
		return v.Float() == 0

	case reflect.Bool:
		return v.Bool() == false

	case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Slice, reflect.Map:
		return v.IsNil()

	case reflect.Struct:
		return reflect.DeepEqual(value, reflect.Zero(v.Type()).Interface())
	}

	panic(fmt.Errorf("Unknown value kind %T", value))
}
<|endoftext|>


<commit_before>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package util

import (
	"io"
	"sort"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
)

// List does client.Glob("*") and returns a sorted slice of results or a
// VDL-compatible error.
func List(ctx *context.T, name string) ([]string, error) {
	client := v23.GetClient(ctx)
	// TODO(sadovsky): This is nuts. Why is Glob not a method on the stub, just
	// like every other streaming method?
	call, err := client.StartCall(ctx, name, rpc.GlobMethod, []interface{}{"*"})
	if err != nil {
		return nil, err
	}
	res := []string{}
	done := false
	for !done {
		var gr naming.GlobReply
		switch err := call.Recv(&gr); err {
		case nil:
			switch v := gr.(type) {
			case naming.GlobReplyEntry:
				res = append(res, v.Value.Name)
			case naming.GlobReplyError:
				return nil, v.Value.Error
			}
		case io.EOF:
			done = true
		default:
			return nil, err
		}
	}
	if err := call.Finish(); err != nil {
		return nil, err
	}
	sort.Strings(res)
	return res, nil
}
<commit_msg>syncbase/server: Implement GlobChildren__ instead of Glob__.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package util

import (
	"sort"
	"strings"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
)

// List does namespace.Glob("name/*") and returns a sorted slice of results or
// a VDL-compatible error.
func List(ctx *context.T, name string) ([]string, error) {
	ns := v23.GetNamespace(ctx)
	ch, err := ns.Glob(ctx, naming.Join(name, "*"))
	if err != nil {
		return nil, err
	}

	names := []string{}
	for globReply := range ch {
		switch v := globReply.(type) {
		case *naming.GlobReplyEntry:
			// NOTE(nlacasse): The names that come back from Glob are all
			// rooted.  We only want the last part of the name, so we must chop
			// off everything before the final '/'.  Since endpoints can
			// themselves contain slashes, we have to remove the endpoint from
			// the name first.
			_, name := naming.SplitAddressName(v.Value.Name)
			names = append(names, name[strings.LastIndex(name, "/")+1:])
		case *naming.GlobReplyError:
			return nil, v.Value.Error
		}
	}
	sort.Strings(names)
	return names, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Gauge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Gauge.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"errors"
	"fmt"
	"github.com/getgauge/common"
	"github.com/getgauge/gauge/config"
	"github.com/getgauge/gauge/gauge_messages"
	"github.com/golang/protobuf/proto"
	"path/filepath"
	"strings"
)

type rephraseRefactorer struct {
	oldStep   *step
	newStep   *step
	isConcept bool
}

type refactoringResult struct {
	success            bool
	specsChanged       []string
	conceptsChanged    []string
	runnerFilesChanged []string
	errors             []string
	warnings           []string
}

func performRephraseRefactoring(oldStep, newStep string) *refactoringResult {
	if newStep == oldStep {
		return rephraseFailure("Same old step name and new step name.")
	}
	agent, err := getRefactorAgent(oldStep, newStep)

	if err != nil {
		return rephraseFailure(err.Error())
	}

	projectRoot, err := common.GetProjectRoot()
	if err != nil {
		return rephraseFailure(err.Error())
	}

	result := &refactoringResult{success: true, errors: make([]string, 0), warnings: make([]string, 0)}
	specs, specParseResults := findSpecs(filepath.Join(projectRoot, common.SpecsDirectoryName), &conceptDictionary{})
	addErrorsAndWarningsToRefactoringResult(result, specParseResults...)
	if !result.success {
		return result
	}
	conceptDictionary, parseResult := createConceptsDictionary(false)

	addErrorsAndWarningsToRefactoringResult(result, parseResult)
	if !result.success {
		return result
	}

	refactorResult := agent.performRefactoringOn(specs, conceptDictionary)
	refactorResult.warnings = append(refactorResult.warnings, result.warnings...)
	return refactorResult
}

func rephraseFailure(errors ...string) *refactoringResult {
	return &refactoringResult{success: false, errors: errors}
}

func addErrorsAndWarningsToRefactoringResult(refactorResult *refactoringResult, parseResults ...*parseResult) {
	for _, parseResult := range parseResults {
		if !parseResult.ok {
			refactorResult.success = false
			refactorResult.errors = append(refactorResult.errors, parseResult.Error())
		}
		refactorResult.appendWarnings(parseResult.warnings)
	}
}

func (agent *rephraseRefactorer) performRefactoringOn(specs []*specification, conceptDictionary *conceptDictionary) *refactoringResult {
	specsRefactored, conceptFilesRefactored := agent.rephraseInSpecsAndConcepts(&specs, conceptDictionary)
	specFiles, conceptFiles := writeToConceptAndSpecFiles(specs, conceptDictionary, specsRefactored, conceptFilesRefactored)
	refactoringResult := &refactoringResult{specsChanged: specFiles, success: false, conceptsChanged: conceptFiles, errors: make([]string, 0)}

	runner, connErr := agent.startRunner()
	if connErr != nil {
		refactoringResult.errors = append(refactoringResult.errors, connErr.Error())
		return refactoringResult
	}
	defer runner.kill()
	stepName, err := agent.getStepNameFromRunner(runner)
	if err != nil {
		refactoringResult.errors = append(refactoringResult.errors, err.Error())
		return refactoringResult
	}
	runnerFilesChanged, err := agent.requestRunnerForRefactoring(runner, stepName)
	if err != nil {
		refactoringResult.errors = append(refactoringResult.errors, fmt.Sprintf("Only spec files and concepts refactored: %s", err))
		return refactoringResult
	}
	refactoringResult.success = true
	refactoringResult.runnerFilesChanged = runnerFilesChanged
	return refactoringResult
}

func (agent *rephraseRefactorer) rephraseInSpecsAndConcepts(specs *[]*specification, conceptDictionary *conceptDictionary) (map[*specification]bool, map[string]bool) {
	specsRefactored := make(map[*specification]bool, 0)
	conceptFilesRefactored := make(map[string]bool, 0)
	orderMap := agent.createOrderOfArgs()
	for _, spec := range *specs {
		specsRefactored[spec] = spec.renameSteps(*agent.oldStep, *agent.newStep, orderMap)
	}
	isConcept := false
	for _, concept := range conceptDictionary.conceptsMap {
		_, ok := conceptFilesRefactored[concept.fileName]
		conceptFilesRefactored[concept.fileName] = !ok && false || conceptFilesRefactored[concept.fileName]
		for _, item := range concept.conceptStep.items {
			isRefactored := conceptFilesRefactored[concept.fileName]
			conceptFilesRefactored[concept.fileName] = item.kind() == stepKind &&
				item.(*step).rename(*agent.oldStep, *agent.newStep, isRefactored, orderMap, &isConcept) ||
				isRefactored
		}
	}
	agent.isConcept = isConcept
	return specsRefactored, conceptFilesRefactored
}

func (agent *rephraseRefactorer) createOrderOfArgs() map[int]int {
	orderMap := make(map[int]int, len(agent.newStep.args))
	for i, arg := range agent.newStep.args {
		orderMap[i] = SliceIndex(len(agent.oldStep.args), func(i int) bool { return agent.oldStep.args[i].String() == arg.String() })
	}
	return orderMap
}

func SliceIndex(limit int, predicate func(i int) bool) int {
	for i := 0; i < limit; i++ {
		if predicate(i) {
			return i
		}
	}
	return -1
}

func getRefactorAgent(oldStepText, newStepText string) (*rephraseRefactorer, error) {
	parser := new(specParser)
	stepTokens, err := parser.generateTokens("* " + oldStepText + "\n" + "*" + newStepText)
	if err != nil {
		return nil, err
	}
	spec := &specification{}
	steps := make([]*step, 0)
	for _, stepToken := range stepTokens {
		step, parseDetails := spec.createStepUsingLookup(stepToken, nil)
		if parseDetails != nil && parseDetails.error != nil {
			return nil, parseDetails.error
		}
		steps = append(steps, step)
	}
	return &rephraseRefactorer{oldStep: steps[0], newStep: steps[1]}, nil
}

func (agent *rephraseRefactorer) requestRunnerForRefactoring(testRunner *testRunner, stepName string) ([]string, error) {
	refactorRequest, err := agent.createRefactorRequest(testRunner, stepName)
	if err != nil {
		return nil, err
	}
	refactorResponse := agent.sendRefactorRequest(testRunner, refactorRequest)
	var runnerError error
	if !refactorResponse.GetSuccess() {
		apiLog.Error("Refactoring error response from runner: %v", refactorResponse.GetError())
		runnerError = errors.New(refactorResponse.GetError())
	}
	return refactorResponse.GetFilesChanged(), runnerError
}

func (agent *rephraseRefactorer) startRunner() (*testRunner, error) {
	loadGaugeEnvironment()
	startAPIService(0)
	testRunner, err := startRunnerAndMakeConnection(getProjectManifest())
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Failed to connect to test runner: %s", err))
	}
	return testRunner, nil
}

func (agent *rephraseRefactorer) sendRefactorRequest(testRunner *testRunner, refactorRequest *gauge_messages.Message) *gauge_messages.RefactorResponse {
	response, err := getResponseForMessageWithTimeout(refactorRequest, testRunner.connection, config.RefactorTimeout())
	if err != nil {
		return &gauge_messages.RefactorResponse{Success: proto.Bool(false), Error: proto.String(err.Error())}
	}
	return response.GetRefactorResponse()
}

//Todo: Check for inline tables
func (agent *rephraseRefactorer) createRefactorRequest(runner *testRunner, stepName string) (*gauge_messages.Message, error) {
	oldStepValue, err := agent.getStepValueFor(agent.oldStep, stepName)
	if err != nil {
		return nil, err
	}
	orderMap := agent.createOrderOfArgs()
	newStepName := agent.generateNewStepName(oldStepValue.args, orderMap)
	newStepValue, err := extractStepValueAndParams(newStepName, false)
	if err != nil {
		return nil, err
	}
	oldProtoStepValue := convertToProtoStepValue(oldStepValue)
	newProtoStepValue := convertToProtoStepValue(newStepValue)
	return &gauge_messages.Message{MessageType: gauge_messages.Message_RefactorRequest.Enum(), RefactorRequest: &gauge_messages.RefactorRequest{OldStepValue: oldProtoStepValue, NewStepValue: newProtoStepValue, ParamPositions: agent.createParameterPositions(orderMap)}}, nil
}

func (agent *rephraseRefactorer) generateNewStepName(args []string, orderMap map[int]int) string {
	agent.newStep.populateFragments()
	paramIndex := 0
	for _, fragment := range agent.newStep.fragments {
		if fragment.GetFragmentType() == gauge_messages.Fragment_Parameter {
			if orderMap[paramIndex] != -1 {
				fragment.GetParameter().Value = proto.String(args[orderMap[paramIndex]])
			}
			paramIndex++
		}
	}
	return convertToStepText(agent.newStep.fragments)
}

func (agent *rephraseRefactorer) getStepNameFromRunner(runner *testRunner) (string, error) {
	stepNameMessage := &gauge_messages.Message{MessageType: gauge_messages.Message_StepNameRequest.Enum(), StepNameRequest: &gauge_messages.StepNameRequest{StepValue: proto.String(agent.oldStep.value)}}
	responseMessage, err := getResponseForMessageWithTimeout(stepNameMessage, runner.connection, config.RunnerRequestTimeout())
	if err != nil {
		return "", err
	}
	if !(responseMessage.GetStepNameResponse().GetIsStepPresent()) {
		return "", errors.New(fmt.Sprintf("Step implementation not found: %s", agent.oldStep.lineText))
	}
	if responseMessage.GetStepNameResponse().GetHasAlias() {
		return "", errors.New(fmt.Sprintf("steps with aliases : '%s' cannot be refactored.", strings.Join(responseMessage.GetStepNameResponse().GetStepName(), "', '")))
	}
	return responseMessage.GetStepNameResponse().GetStepName()[0], nil
}

func (agent *rephraseRefactorer) createParameterPositions(orderMap map[int]int) []*gauge_messages.ParameterPosition {
	paramPositions := make([]*gauge_messages.ParameterPosition, 0)
	for k, v := range orderMap {
		paramPositions = append(paramPositions, &gauge_messages.ParameterPosition{NewPosition: proto.Int(k), OldPosition: proto.Int(v)})
	}
	return paramPositions
}

func (agent *rephraseRefactorer) getStepValueFor(step *step, stepName string) (*stepValue, error) {
	return extractStepValueAndParams(stepName, false)
}

func writeToConceptAndSpecFiles(specs []*specification, conceptDictionary *conceptDictionary, specsRefactored map[*specification]bool, conceptFilesRefactored map[string]bool) ([]string, []string) {
	specFiles := make([]string, 0)
	conceptFiles := make([]string, 0)
	for _, spec := range specs {
		if specsRefactored[spec] {
			specFiles = append(specFiles, spec.fileName)
			formatted := formatSpecification(spec)
			saveFile(spec.fileName, formatted, true)
		}
	}
	conceptMap := formatConcepts(conceptDictionary)
	for fileName, concept := range conceptMap {
		if conceptFilesRefactored[fileName] {
			conceptFiles = append(conceptFiles, fileName)
			saveFile(fileName, concept, true)
		}
	}
	return specFiles, conceptFiles
}

func (refactoringResult *refactoringResult) appendWarnings(warnings []*warning) {
	if refactoringResult.warnings == nil {
		refactoringResult.warnings = make([]string, 0)
	}
	for _, warning := range warnings {
		refactoringResult.warnings = append(refactoringResult.warnings, warning.message)
	}
}

func (refactoringResult *refactoringResult) allFilesChanges() []string {
	filesChanged := make([]string, 0)
	filesChanged = append(filesChanged, refactoringResult.specsChanged...)
	filesChanged = append(filesChanged, refactoringResult.conceptsChanged...)
	filesChanged = append(filesChanged, refactoringResult.runnerFilesChanged...)
	return filesChanged

}
<commit_msg>not making request to runner if concept is being refactored.Fixes #93<commit_after>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Gauge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Gauge.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"errors"
	"fmt"
	"github.com/getgauge/common"
	"github.com/getgauge/gauge/config"
	"github.com/getgauge/gauge/gauge_messages"
	"github.com/golang/protobuf/proto"
	"path/filepath"
	"strings"
)

type rephraseRefactorer struct {
	oldStep   *step
	newStep   *step
	isConcept bool
}

type refactoringResult struct {
	success            bool
	specsChanged       []string
	conceptsChanged    []string
	runnerFilesChanged []string
	errors             []string
	warnings           []string
}

func performRephraseRefactoring(oldStep, newStep string) *refactoringResult {
	if newStep == oldStep {
		return rephraseFailure("Same old step name and new step name.")
	}
	agent, err := getRefactorAgent(oldStep, newStep)

	if err != nil {
		return rephraseFailure(err.Error())
	}

	projectRoot, err := common.GetProjectRoot()
	if err != nil {
		return rephraseFailure(err.Error())
	}

	result := &refactoringResult{success: true, errors: make([]string, 0), warnings: make([]string, 0)}
	specs, specParseResults := findSpecs(filepath.Join(projectRoot, common.SpecsDirectoryName), &conceptDictionary{})
	addErrorsAndWarningsToRefactoringResult(result, specParseResults...)
	if !result.success {
		return result
	}
	conceptDictionary, parseResult := createConceptsDictionary(false)

	addErrorsAndWarningsToRefactoringResult(result, parseResult)
	if !result.success {
		return result
	}

	refactorResult := agent.performRefactoringOn(specs, conceptDictionary)
	refactorResult.warnings = append(refactorResult.warnings, result.warnings...)
	return refactorResult
}

func rephraseFailure(errors ...string) *refactoringResult {
	return &refactoringResult{success: false, errors: errors}
}

func addErrorsAndWarningsToRefactoringResult(refactorResult *refactoringResult, parseResults ...*parseResult) {
	for _, parseResult := range parseResults {
		if !parseResult.ok {
			refactorResult.success = false
			refactorResult.errors = append(refactorResult.errors, parseResult.Error())
		}
		refactorResult.appendWarnings(parseResult.warnings)
	}
}

func (agent *rephraseRefactorer) performRefactoringOn(specs []*specification, conceptDictionary *conceptDictionary) *refactoringResult {
	specsRefactored, conceptFilesRefactored := agent.rephraseInSpecsAndConcepts(&specs, conceptDictionary)
	specFiles, conceptFiles := writeToConceptAndSpecFiles(specs, conceptDictionary, specsRefactored, conceptFilesRefactored)
	refactoringResult := &refactoringResult{specsChanged: specFiles, success: false, conceptsChanged: conceptFiles, errors: make([]string, 0)}
	if !agent.isConcept {
		runner, connErr := agent.startRunner()
		if connErr != nil {
			refactoringResult.errors = append(refactoringResult.errors, connErr.Error())
			return refactoringResult
		}
		defer runner.kill()
		stepName, err := agent.getStepNameFromRunner(runner)
		if err != nil {
			refactoringResult.errors = append(refactoringResult.errors, err.Error())
			return refactoringResult
		}
		runnerFilesChanged, err := agent.requestRunnerForRefactoring(runner, stepName)
		if err != nil {
			refactoringResult.errors = append(refactoringResult.errors, fmt.Sprintf("Only spec files and concepts refactored: %s", err))
			return refactoringResult
		}
		refactoringResult.runnerFilesChanged = runnerFilesChanged
	}
	refactoringResult.success = true
	return refactoringResult
}

func (agent *rephraseRefactorer) rephraseInSpecsAndConcepts(specs *[]*specification, conceptDictionary *conceptDictionary) (map[*specification]bool, map[string]bool) {
	specsRefactored := make(map[*specification]bool, 0)
	conceptFilesRefactored := make(map[string]bool, 0)
	orderMap := agent.createOrderOfArgs()
	for _, spec := range *specs {
		specsRefactored[spec] = spec.renameSteps(*agent.oldStep, *agent.newStep, orderMap)
	}
	isConcept := false
	for _, concept := range conceptDictionary.conceptsMap {
		_, ok := conceptFilesRefactored[concept.fileName]
		conceptFilesRefactored[concept.fileName] = !ok && false || conceptFilesRefactored[concept.fileName]
		for _, item := range concept.conceptStep.items {
			isRefactored := conceptFilesRefactored[concept.fileName]
			conceptFilesRefactored[concept.fileName] = item.kind() == stepKind &&
				item.(*step).rename(*agent.oldStep, *agent.newStep, isRefactored, orderMap, &isConcept) ||
				isRefactored
		}
	}
	agent.isConcept = isConcept
	return specsRefactored, conceptFilesRefactored
}

func (agent *rephraseRefactorer) createOrderOfArgs() map[int]int {
	orderMap := make(map[int]int, len(agent.newStep.args))
	for i, arg := range agent.newStep.args {
		orderMap[i] = SliceIndex(len(agent.oldStep.args), func(i int) bool { return agent.oldStep.args[i].String() == arg.String() })
	}
	return orderMap
}

func SliceIndex(limit int, predicate func(i int) bool) int {
	for i := 0; i < limit; i++ {
		if predicate(i) {
			return i
		}
	}
	return -1
}

func getRefactorAgent(oldStepText, newStepText string) (*rephraseRefactorer, error) {
	parser := new(specParser)
	stepTokens, err := parser.generateTokens("* " + oldStepText + "\n" + "*" + newStepText)
	if err != nil {
		return nil, err
	}
	spec := &specification{}
	steps := make([]*step, 0)
	for _, stepToken := range stepTokens {
		step, parseDetails := spec.createStepUsingLookup(stepToken, nil)
		if parseDetails != nil && parseDetails.error != nil {
			return nil, parseDetails.error
		}
		steps = append(steps, step)
	}
	return &rephraseRefactorer{oldStep: steps[0], newStep: steps[1]}, nil
}

func (agent *rephraseRefactorer) requestRunnerForRefactoring(testRunner *testRunner, stepName string) ([]string, error) {
	refactorRequest, err := agent.createRefactorRequest(testRunner, stepName)
	if err != nil {
		return nil, err
	}
	refactorResponse := agent.sendRefactorRequest(testRunner, refactorRequest)
	var runnerError error
	if !refactorResponse.GetSuccess() {
		apiLog.Error("Refactoring error response from runner: %v", refactorResponse.GetError())
		runnerError = errors.New(refactorResponse.GetError())
	}
	return refactorResponse.GetFilesChanged(), runnerError
}

func (agent *rephraseRefactorer) startRunner() (*testRunner, error) {
	loadGaugeEnvironment()
	startAPIService(0)
	testRunner, err := startRunnerAndMakeConnection(getProjectManifest())
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Failed to connect to test runner: %s", err))
	}
	return testRunner, nil
}

func (agent *rephraseRefactorer) sendRefactorRequest(testRunner *testRunner, refactorRequest *gauge_messages.Message) *gauge_messages.RefactorResponse {
	response, err := getResponseForMessageWithTimeout(refactorRequest, testRunner.connection, config.RefactorTimeout())
	if err != nil {
		return &gauge_messages.RefactorResponse{Success: proto.Bool(false), Error: proto.String(err.Error())}
	}
	return response.GetRefactorResponse()
}

//Todo: Check for inline tables
func (agent *rephraseRefactorer) createRefactorRequest(runner *testRunner, stepName string) (*gauge_messages.Message, error) {
	oldStepValue, err := agent.getStepValueFor(agent.oldStep, stepName)
	if err != nil {
		return nil, err
	}
	orderMap := agent.createOrderOfArgs()
	newStepName := agent.generateNewStepName(oldStepValue.args, orderMap)
	newStepValue, err := extractStepValueAndParams(newStepName, false)
	if err != nil {
		return nil, err
	}
	oldProtoStepValue := convertToProtoStepValue(oldStepValue)
	newProtoStepValue := convertToProtoStepValue(newStepValue)
	return &gauge_messages.Message{MessageType: gauge_messages.Message_RefactorRequest.Enum(), RefactorRequest: &gauge_messages.RefactorRequest{OldStepValue: oldProtoStepValue, NewStepValue: newProtoStepValue, ParamPositions: agent.createParameterPositions(orderMap)}}, nil
}

func (agent *rephraseRefactorer) generateNewStepName(args []string, orderMap map[int]int) string {
	agent.newStep.populateFragments()
	paramIndex := 0
	for _, fragment := range agent.newStep.fragments {
		if fragment.GetFragmentType() == gauge_messages.Fragment_Parameter {
			if orderMap[paramIndex] != -1 {
				fragment.GetParameter().Value = proto.String(args[orderMap[paramIndex]])
			}
			paramIndex++
		}
	}
	return convertToStepText(agent.newStep.fragments)
}

func (agent *rephraseRefactorer) getStepNameFromRunner(runner *testRunner) (string, error) {
	stepNameMessage := &gauge_messages.Message{MessageType: gauge_messages.Message_StepNameRequest.Enum(), StepNameRequest: &gauge_messages.StepNameRequest{StepValue: proto.String(agent.oldStep.value)}}
	responseMessage, err := getResponseForMessageWithTimeout(stepNameMessage, runner.connection, config.RunnerRequestTimeout())
	if err != nil {
		return "", err
	}
	if !(responseMessage.GetStepNameResponse().GetIsStepPresent()) {
		return "", errors.New(fmt.Sprintf("Step implementation not found: %s", agent.oldStep.lineText))
	}
	if responseMessage.GetStepNameResponse().GetHasAlias() {
		return "", errors.New(fmt.Sprintf("steps with aliases : '%s' cannot be refactored.", strings.Join(responseMessage.GetStepNameResponse().GetStepName(), "', '")))
	}
	return responseMessage.GetStepNameResponse().GetStepName()[0], nil
}

func (agent *rephraseRefactorer) createParameterPositions(orderMap map[int]int) []*gauge_messages.ParameterPosition {
	paramPositions := make([]*gauge_messages.ParameterPosition, 0)
	for k, v := range orderMap {
		paramPositions = append(paramPositions, &gauge_messages.ParameterPosition{NewPosition: proto.Int(k), OldPosition: proto.Int(v)})
	}
	return paramPositions
}

func (agent *rephraseRefactorer) getStepValueFor(step *step, stepName string) (*stepValue, error) {
	return extractStepValueAndParams(stepName, false)
}

func writeToConceptAndSpecFiles(specs []*specification, conceptDictionary *conceptDictionary, specsRefactored map[*specification]bool, conceptFilesRefactored map[string]bool) ([]string, []string) {
	specFiles := make([]string, 0)
	conceptFiles := make([]string, 0)
	for _, spec := range specs {
		if specsRefactored[spec] {
			specFiles = append(specFiles, spec.fileName)
			formatted := formatSpecification(spec)
			saveFile(spec.fileName, formatted, true)
		}
	}
	conceptMap := formatConcepts(conceptDictionary)
	for fileName, concept := range conceptMap {
		if conceptFilesRefactored[fileName] {
			conceptFiles = append(conceptFiles, fileName)
			saveFile(fileName, concept, true)
		}
	}
	return specFiles, conceptFiles
}

func (refactoringResult *refactoringResult) appendWarnings(warnings []*warning) {
	if refactoringResult.warnings == nil {
		refactoringResult.warnings = make([]string, 0)
	}
	for _, warning := range warnings {
		refactoringResult.warnings = append(refactoringResult.warnings, warning.message)
	}
}

func (refactoringResult *refactoringResult) allFilesChanges() []string {
	filesChanged := make([]string, 0)
	filesChanged = append(filesChanged, refactoringResult.specsChanged...)
	filesChanged = append(filesChanged, refactoringResult.conceptsChanged...)
	filesChanged = append(filesChanged, refactoringResult.runnerFilesChanged...)
	return filesChanged

}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/golang/protobuf/proto"
	"os"
)

type rephraseRefactorer struct {
	oldStep   *step
	newStep   *step
	isConcept bool
}

func (agent *rephraseRefactorer) refactor(specs *[]*specification, conceptDictionary *conceptDictionary) (map[*specification]bool, map[string]bool) {
	specsRefactored := make(map[*specification]bool, 0)
	conceptFilesRefactored := make(map[string]bool, 0)
	orderMap := agent.createOrderOfArgs()
	for _, spec := range *specs {
		specsRefactored[spec] = spec.renameSteps(*agent.oldStep, *agent.newStep, orderMap)
	}
	isConcept := false
	for _, concept := range conceptDictionary.conceptsMap {
		_, ok := conceptFilesRefactored[concept.fileName]
		conceptFilesRefactored[concept.fileName] = !ok && false || conceptFilesRefactored[concept.fileName]
		for _, item := range concept.conceptStep.items {
			isRefactored := conceptFilesRefactored[concept.fileName]
			conceptFilesRefactored[concept.fileName] = item.kind() == stepKind &&
				item.(*step).rename(*agent.oldStep, *agent.newStep, isRefactored, orderMap, &isConcept) ||
				isRefactored
		}
	}
	agent.isConcept = isConcept
	return specsRefactored, conceptFilesRefactored
}

func (agent *rephraseRefactorer) createOrderOfArgs() map[int]int {
	orderMap := make(map[int]int, len(agent.newStep.args))
	for i, arg := range agent.newStep.args {
		orderMap[i] = SliceIndex(len(agent.oldStep.args), func(i int) bool { return agent.oldStep.args[i].String() == arg.String() })
	}
	return orderMap
}

func SliceIndex(limit int, predicate func(i int) bool) int {
	for i := 0; i < limit; i++ {
		if predicate(i) {
			return i
		}
	}
	return -1
}

func getRefactorAgent(oldStepText, newStepText string) (*rephraseRefactorer, error) {
	parser := new(specParser)
	stepTokens, err := parser.generateTokens("* " + oldStepText + "\n" + "*" + newStepText)
	if err != nil {
		return nil, err
	}
	spec := &specification{}
	steps := make([]*step, 0)
	for _, stepToken := range stepTokens {
		step, err := spec.createStepUsingLookup(stepToken, nil)
		if err != nil {
			return nil, err
		}
		steps = append(steps, step)
	}
	return &rephraseRefactorer{oldStep: steps[0], newStep: steps[1]}, nil
}

func (agent *rephraseRefactorer) requestRunnerForRefactoring() {
	if agent.isConcept {
		return
	}
	loadGaugeEnvironment()
	startAPIService(0)
	testRunner, err := startRunnerAndMakeConnection(getProjectManifest())
	if err != nil {
		fmt.Printf("Failed to connect to test runner: %s", err)
		os.Exit(1)
	}
	refactorRequest, err := agent.createRefactorRequest(testRunner)
	if err != nil {
		fmt.Printf("Failed to create refactoring request: %s", err)
		testRunner.kill()
		os.Exit(1)
	}
	agent.sendRefactorRequest(testRunner, refactorRequest)
	testRunner.kill()
}

func (agent *rephraseRefactorer) sendRefactorRequest(testRunner *testRunner, refactorRequest *Message) {
	response, err := getResponseForGaugeMessage(refactorRequest, testRunner.connection)
	if err != nil {
		testRunner.kill()
		fmt.Printf("Failed to perform refactoring in code: %s", err)
		os.Exit(1)
	} else if !response.GetRefactorResponse().GetSuccess() {
		fmt.Printf("Failed to perform refactoring in code: %s", response.GetRefactorResponse().GetError())
		testRunner.kill()
		os.Exit(1)
	}
}

//Todo: Check for inline tables
func (agent *rephraseRefactorer) createRefactorRequest(runner *testRunner) (*Message, error) {
	isStepPresent, stepName := agent.getStepNameFromRunner(runner)
	if !isStepPresent {
		return nil, errors.New(fmt.Sprintf("Step implementation not found: %s", agent.oldStep.lineText))
	}
	oldStepValue, err := agent.getStepValueFor(agent.oldStep, stepName)
	if err != nil {
		return nil, err
	}
	orderMap := agent.createOrderOfArgs()
	newStepName := agent.generateNewStepName(oldStepValue.args, orderMap)
	newStepValue, err := extractStepValueAndParams(newStepName, false)
	if err != nil {
		return nil, err
	}
	oldProtoStepValue := convertToProtoStepValue(oldStepValue)
	newProtoStepValue := convertToProtoStepValue(newStepValue)
	return &Message{MessageType: Message_RefactorRequest.Enum(), RefactorRequest: &RefactorRequest{OldStepValue: oldProtoStepValue, NewStepValue: newProtoStepValue, ParamPositions: agent.createParameterPositions(orderMap)}}, nil
}

func (agent *rephraseRefactorer) generateNewStepName(args []string, orderMap map[int]int) string {
	agent.newStep.populateFragments()
	paramIndex := 0
	for _, fragment := range agent.newStep.fragments {
		if fragment.GetFragmentType() == Fragment_Parameter {
			if orderMap[paramIndex] != -1 {
				fragment.GetParameter().Value = proto.String(args[orderMap[paramIndex]])
			}
			paramIndex++
		}
	}
	return convertToStepText(agent.newStep.fragments)
}

func (agent *rephraseRefactorer) getStepNameFromRunner(runner *testRunner) (bool, string) {
	stepNameMessage := &Message{MessageType: Message_StepNameRequest.Enum(), StepNameRequest: &GetStepNameRequest{StepValue: proto.String(agent.oldStep.value)}}
	responseMessage, err := getResponseForGaugeMessage(stepNameMessage, runner.connection)
	if err != nil || responseMessage.GetMessageType() != Message_StepNameResponse {
		return false, ""
	}
	return responseMessage.GetStepNameResponse().GetIsStepPresent(), responseMessage.GetStepNameResponse().GetStepName()
}

func (agent *rephraseRefactorer) createParameterPositions(orderMap map[int]int) []*ParameterPosition {
	paramPositions := make([]*ParameterPosition, 0)
	for k, v := range orderMap {
		paramPositions = append(paramPositions, &ParameterPosition{NewPosition: proto.Int(k), OldPosition: proto.Int(v)})
	}
	return paramPositions
}

func (agent *rephraseRefactorer) getStepValueFor(step *step, stepName string) (*stepValue, error) {
	return extractStepValueAndParams(stepName, false)
}
<commit_msg>changing error messages<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/golang/protobuf/proto"
	"os"
)

type rephraseRefactorer struct {
	oldStep   *step
	newStep   *step
	isConcept bool
}

func (agent *rephraseRefactorer) refactor(specs *[]*specification, conceptDictionary *conceptDictionary) (map[*specification]bool, map[string]bool) {
	specsRefactored := make(map[*specification]bool, 0)
	conceptFilesRefactored := make(map[string]bool, 0)
	orderMap := agent.createOrderOfArgs()
	for _, spec := range *specs {
		specsRefactored[spec] = spec.renameSteps(*agent.oldStep, *agent.newStep, orderMap)
	}
	isConcept := false
	for _, concept := range conceptDictionary.conceptsMap {
		_, ok := conceptFilesRefactored[concept.fileName]
		conceptFilesRefactored[concept.fileName] = !ok && false || conceptFilesRefactored[concept.fileName]
		for _, item := range concept.conceptStep.items {
			isRefactored := conceptFilesRefactored[concept.fileName]
			conceptFilesRefactored[concept.fileName] = item.kind() == stepKind &&
				item.(*step).rename(*agent.oldStep, *agent.newStep, isRefactored, orderMap, &isConcept) ||
				isRefactored
		}
	}
	agent.isConcept = isConcept
	return specsRefactored, conceptFilesRefactored
}

func (agent *rephraseRefactorer) createOrderOfArgs() map[int]int {
	orderMap := make(map[int]int, len(agent.newStep.args))
	for i, arg := range agent.newStep.args {
		orderMap[i] = SliceIndex(len(agent.oldStep.args), func(i int) bool { return agent.oldStep.args[i].String() == arg.String() })
	}
	return orderMap
}

func SliceIndex(limit int, predicate func(i int) bool) int {
	for i := 0; i < limit; i++ {
		if predicate(i) {
			return i
		}
	}
	return -1
}

func getRefactorAgent(oldStepText, newStepText string) (*rephraseRefactorer, error) {
	parser := new(specParser)
	stepTokens, err := parser.generateTokens("* " + oldStepText + "\n" + "*" + newStepText)
	if err != nil {
		return nil, err
	}
	spec := &specification{}
	steps := make([]*step, 0)
	for _, stepToken := range stepTokens {
		step, err := spec.createStepUsingLookup(stepToken, nil)
		if err != nil {
			return nil, err
		}
		steps = append(steps, step)
	}
	return &rephraseRefactorer{oldStep: steps[0], newStep: steps[1]}, nil
}

func (agent *rephraseRefactorer) requestRunnerForRefactoring() {
	if agent.isConcept {
		return
	}
	loadGaugeEnvironment()
	startAPIService(0)
	testRunner, err := startRunnerAndMakeConnection(getProjectManifest())
	if err != nil {
		fmt.Printf("Failed to connect to test runner: %s", err)
		os.Exit(1)
	}
	refactorRequest, err := agent.createRefactorRequest(testRunner)
	if err != nil {
		fmt.Printf("%s", err)
		testRunner.kill()
		os.Exit(1)
	}
	agent.sendRefactorRequest(testRunner, refactorRequest)
	testRunner.kill()
}

func (agent *rephraseRefactorer) sendRefactorRequest(testRunner *testRunner, refactorRequest *Message) {
	response, err := getResponseForGaugeMessage(refactorRequest, testRunner.connection)
	if err != nil {
		testRunner.kill()
		fmt.Printf("Failed to perform refactoring in code: %s", err)
		os.Exit(1)
	} else if !response.GetRefactorResponse().GetSuccess() {
		fmt.Printf("Failed to perform refactoring in code: %s", response.GetRefactorResponse().GetError())
		testRunner.kill()
		os.Exit(1)
	}
}

//Todo: Check for inline tables
func (agent *rephraseRefactorer) createRefactorRequest(runner *testRunner) (*Message, error) {
	isStepPresent, stepName := agent.getStepNameFromRunner(runner)
	if !isStepPresent {
		return nil, errors.New(fmt.Sprintf("Changes only in spec and concept files.Step implementation not found: %s", agent.oldStep.lineText))
	}
	oldStepValue, err := agent.getStepValueFor(agent.oldStep, stepName)
	if err != nil {
		return nil, err
	}
	orderMap := agent.createOrderOfArgs()
	newStepName := agent.generateNewStepName(oldStepValue.args, orderMap)
	newStepValue, err := extractStepValueAndParams(newStepName, false)
	if err != nil {
		return nil, err
	}
	oldProtoStepValue := convertToProtoStepValue(oldStepValue)
	newProtoStepValue := convertToProtoStepValue(newStepValue)
	return &Message{MessageType: Message_RefactorRequest.Enum(), RefactorRequest: &RefactorRequest{OldStepValue: oldProtoStepValue, NewStepValue: newProtoStepValue, ParamPositions: agent.createParameterPositions(orderMap)}}, nil
}

func (agent *rephraseRefactorer) generateNewStepName(args []string, orderMap map[int]int) string {
	agent.newStep.populateFragments()
	paramIndex := 0
	for _, fragment := range agent.newStep.fragments {
		if fragment.GetFragmentType() == Fragment_Parameter {
			if orderMap[paramIndex] != -1 {
				fragment.GetParameter().Value = proto.String(args[orderMap[paramIndex]])
			}
			paramIndex++
		}
	}
	return convertToStepText(agent.newStep.fragments)
}

func (agent *rephraseRefactorer) getStepNameFromRunner(runner *testRunner) (bool, string) {
	stepNameMessage := &Message{MessageType: Message_StepNameRequest.Enum(), StepNameRequest: &GetStepNameRequest{StepValue: proto.String(agent.oldStep.value)}}
	responseMessage, err := getResponseForGaugeMessage(stepNameMessage, runner.connection)
	if err != nil || responseMessage.GetMessageType() != Message_StepNameResponse {
		return false, ""
	}
	return responseMessage.GetStepNameResponse().GetIsStepPresent(), responseMessage.GetStepNameResponse().GetStepName()
}

func (agent *rephraseRefactorer) createParameterPositions(orderMap map[int]int) []*ParameterPosition {
	paramPositions := make([]*ParameterPosition, 0)
	for k, v := range orderMap {
		paramPositions = append(paramPositions, &ParameterPosition{NewPosition: proto.Int(k), OldPosition: proto.Int(v)})
	}
	return paramPositions
}

func (agent *rephraseRefactorer) getStepValueFor(step *step, stepName string) (*stepValue, error) {
	return extractStepValueAndParams(stepName, false)
}
<|endoftext|>


<commit_before>package github

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

var (
	RequestRepositoriesUri  = "https://api.github.com/repos/"
	RequestAuthorizationUri = "https://api.github.com/authorizations"
)

//Repo contains repo information
type Repo struct {
	DefaultBranch string `json:"default_branch"`
}

func DefaultBranch() string {
	str, _ := GetDefaultBranch(RequestRepositoriesUri)
	return str
}

func GetDefaultBranch(RequestRepositoriesUri string) (string, error) {

	res, err := http.Get(RequestRepositoriesUri)

	if err != nil {
		return "", err
	}

	if res.StatusCode != http.StatusOK {
		return "", fmt.Errorf("request did not respond 200 OK: %s", res.Status)
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return "", err
	}

	re := Repo{}
	err = json.Unmarshal(body, &re)

	if err != nil {
		return "", err
	}

	return re.DefaultBranch, nil
}

//type Plugin interface {
//	DefaultBranch() string
//	ListIssues() map[int]string
//	SetAssignee(string)
//	SetLabelsOnIssue(...string)
//	InitializeRepo()
//}

//GetRepoInfo ...  gets repo info from name
func GetRepoInfo(repoName string) (out Repo) {

	res, err := http.Get("https://api.github.com/repos/" + repoName)
	if err != nil {
		panic(err.Error())
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	re := Repo{}
	err = json.Unmarshal(body, &re)
	if err != nil {
		panic(err)
	}

	fmt.Println(re.DefaultBranch)

	return re
}

func GetRepoAndUser(remote string) (user, repo string) {

	var repoInfo []string

	tmp := strings.Split(remote, ":")[1]
	tmp = strings.Split(tmp, ".")[0]

	repoInfo = strings.Split(tmp, "/")

	repo = repoInfo[0]
	user = repoInfo[1]
	return

}
<commit_msg>close #44 workon Add GitHub plugin<commit_after>package github

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

var (
	RequestRepositoriesUri  = "https://api.github.com/repos/"
	RequestAuthorizationUri = "https://api.github.com/authorizations"
)

//Repo contains repo information
type Repo struct {
	DefaultBranch string `json:"default_branch"`
}

func DefaultBranch() string {
	str, _ := GetDefaultBranch(RequestRepositoriesUri)
	return str
}

func GetDefaultBranch(RequestRepositoriesUri string) (string, error) {

	res, err := http.Get(RequestRepositoriesUri)

	if err != nil {
		return "", err
	}

	if res.StatusCode != http.StatusOK {
		return "", fmt.Errorf("request did not respond 200 OK: %s", res.Status)
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	if err != nil {
		return "", err
	}

	re := Repo{}
	err = json.Unmarshal(body, &re)

	if err != nil {
		return "", err
	}

	return re.DefaultBranch, nil
}

//type Plugin interface {
//	DefaultBranch() string
//	ListIssues() map[int]string
//	SetAssignee(string)
//	SetLabelsOnIssue(...string)
//	InitializeRepo()
//}

//GetRepoInfo ...  gets repo info from name
func GetRepoInfo(repoName string) (out Repo) {

	res, err := http.Get("https://api.github.com/repos/" + repoName)
	if err != nil {
		panic(err.Error())
	}

	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)

	re := Repo{}
	err = json.Unmarshal(body, &re)
	if err != nil {
		panic(err)
	}

	fmt.Println(re.DefaultBranch)

	return re
}

//GetRepoAndUser ...
func GetRepoAndUser(remote string) (user, repo string) {

	var repoInfo []string

	tmp := strings.Split(remote, ":")[1]
	tmp = strings.Split(tmp, ".")[0]

	repoInfo = strings.Split(tmp, "/")

	repo = repoInfo[0]
	user = repoInfo[1]
	return

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"github.com/grafadruid/go-druid"
	"log"
	"time"

	"github.com/grafadruid/go-druid/builder/intervals"

	"github.com/grafadruid/go-druid/builder"
	"github.com/grafadruid/go-druid/builder/aggregation"
	"github.com/grafadruid/go-druid/builder/datasource"
	"github.com/grafadruid/go-druid/builder/filter"
	"github.com/grafadruid/go-druid/builder/granularity"
	"github.com/grafadruid/go-druid/builder/query"
)

// Copied from https://github.com/grafadruid/go-druid/blob/master/examples/main.go

func main() {
	var druidOpts []druid.ClientOption
	druidOpts = append(druidOpts, druid.WithSkipTLSVerify())

	d, err := druid.NewClient("http://localhost:8082", druidOpts...)
	if err != nil {
		log.Fatal(err)
	}
	status, _, err := d.Common().Status()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("{\"version\": \"" + status.Version + "\"}")

	t := datasource.NewTable().SetName("wikipedia")

	i := intervals.NewInterval()
	i.SetInterval(time.Unix(0, 0), time.Now())
	i2 := intervals.NewInterval()
	i2.SetIntervalWithString("2021-01-21T14:59:05.000Z", "P1D")
	is := intervals.NewIntervals().SetIntervals([]*intervals.Interval{i, i2})

	c := aggregation.NewCount().SetName("count")
	aa := []builder.Aggregator{c}
	s1 := filter.NewSelector().SetDimension("countryName").SetValue("France")
	s2 := filter.NewSelector().SetDimension("cityName").SetValue("Paris")
	n := filter.NewNot().SetField(s2)
	a := filter.NewAnd().SetFields([]builder.Filter{s1, n})
	m := granularity.NewSimple().SetGranularity(granularity.All)
	ts := query.NewTimeseries().SetDataSource(t).SetIntervals(is).SetAggregations(aa).SetGranularity(m).SetFilter(a).SetLimit(10)
	var results interface{}
	_, err = d.Query().Execute(ts, &results)
	if err != nil {
		log.Fatalf("Execute failed, %s", err)
	}

	spew.Dump(results)
}
<commit_msg>Add code comments and running results for the example of go-druid<commit_after>package main

import (
	"fmt"
	"github.com/davecgh/go-spew/spew"
	"github.com/grafadruid/go-druid"
	"log"
	"time"

	"github.com/grafadruid/go-druid/builder/intervals"

	"github.com/grafadruid/go-druid/builder"
	"github.com/grafadruid/go-druid/builder/aggregation"
	"github.com/grafadruid/go-druid/builder/datasource"
	"github.com/grafadruid/go-druid/builder/filter"
	"github.com/grafadruid/go-druid/builder/granularity"
	"github.com/grafadruid/go-druid/builder/query"
)

// Copied from https://github.com/grafadruid/go-druid/blob/master/examples/main.go

func main() {

	// Connection
	var druidOpts []druid.ClientOption
	druidOpts = append(druidOpts, druid.WithSkipTLSVerify())
	d, err := druid.NewClient("http://localhost:8082", druidOpts...)
	if err != nil {
		log.Fatal(err)
	}

	// Version
	status, _, err := d.Common().Status()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("{\"version\": \"" + status.Version + "\"}") // {"version": "0.22.0"}

	// DataSource
	t := datasource.NewTable().SetName("wikipedia")

	// Time range
	i := intervals.NewInterval()
	i.SetInterval(time.Unix(0, 0), time.Now())
	i2 := intervals.NewInterval()
	i2.SetIntervalWithString("2021-01-21T14:59:05.000Z", "P1D")
	is := intervals.NewIntervals().SetIntervals([]*intervals.Interval{i, i2})

	// Aggregation
	c := aggregation.NewCount().SetName("count")
	aa := []builder.Aggregator{c}

	// Columns
	s1 := filter.NewSelector().SetDimension("countryName").SetValue("France")
	s2 := filter.NewSelector().SetDimension("cityName").SetValue("Paris")
	n := filter.NewNot().SetField(s2)
	a := filter.NewAnd().SetFields([]builder.Filter{s1, n})
	m := granularity.NewSimple().SetGranularity(granularity.All)
	ts := query.NewTimeseries().SetDataSource(t).SetIntervals(is).SetAggregations(aa).SetGranularity(m).SetFilter(a).SetLimit(10)
	var results interface{}

	// Execute
	_, err = d.Query().Execute(ts, &results)
	if err != nil {
		log.Fatalf("Execute failed, %s", err)
	}

	// Result
	/**
	([]interface {}) (len=1 cap=1) {
	 (map[string]interface {}) (len=2) {
	  (string) (len=9) "timestamp": (string) (len=24) "2016-06-27T00:00:11.080Z",
	  (string) (len=6) "result": (map[string]interface {}) (len=1) {
	   (string) (len=5) "count": (float64) 79
	  }
	 }
	}
	*/
	spew.Dump(results)
}
<|endoftext|>


<commit_before>package mph

import (
	"bufio"
	"bytes"
	"io"
	"os"
	"testing"

	"github.com/stretchrcom/testify/assert"
)

var (
	sampleData = map[string]string{
		"one":   "1",
		"two":   "2",
		"three": "3",
		"four":  "4",
		"five":  "5",
		"six":   "6",
		"seven": "7",
	}
)

var (
	words [][]byte
)

func init() {
	f, err := os.Open("/usr/share/dict/words")
	if err != nil {
		panic(err)
	}
	r := bufio.NewReader(f)
	for {
		line, err := r.ReadBytes('\n')
		if err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
		words = append(words, line)
	}
}

func TestCHDBuilder(t *testing.T) {
	b := Builder()
	for k, v := range sampleData {
		b.Add([]byte(k), []byte(v))
	}
	c, err := b.Build()
	assert.NoError(t, err)
	assert.Equal(t, 7, len(c.keys))
	for k, v := range sampleData {
		assert.Equal(t, []byte(v), c.Get([]byte(k)))
	}
	assert.Nil(t, c.Get([]byte("monkey")))
}

func TestCHDSerialization(t *testing.T) {
	cb := Builder()
	for _, v := range words {
		cb.Add([]byte(v), []byte(v))
	}
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
	for _, v := range words {
		assert.Equal(t, []byte(v), n.Get([]byte(v)))
	}
}

func TestCHDSerialization_empty(t *testing.T) {
	cb := Builder()
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
}

func TestCHDSerialization_one(t *testing.T) {
	cb := Builder()
	cb.Add([]byte("k"), []byte("v"))
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
}

func BenchmarkBuiltinMap(b *testing.B) {
	keys := []string{}
	d := map[string]string{}
	for _, bk := range words {
		k := string(bk)
		d[k] = k
		keys = append(keys, k)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = d[keys[i%len(keys)]]
	}
}

func BenchmarkCHD(b *testing.B) {
	keys := [][]byte{}
	mph := Builder()
	for _, k := range words {
		keys = append(keys, k)
		mph.Add(k, k)
	}
	h, _ := mph.Build()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Get(keys[i%len(keys)])
	}
}
<commit_msg>update github.com/stretchr<commit_after>package mph

import (
	"bufio"
	"bytes"
	"io"
	"os"
	"testing"

	"github.com/stretchr/testify/assert"
)

var (
	sampleData = map[string]string{
		"one":   "1",
		"two":   "2",
		"three": "3",
		"four":  "4",
		"five":  "5",
		"six":   "6",
		"seven": "7",
	}
)

var (
	words [][]byte
)

func init() {
	f, err := os.Open("/usr/share/dict/words")
	if err != nil {
		panic(err)
	}
	r := bufio.NewReader(f)
	for {
		line, err := r.ReadBytes('\n')
		if err == io.EOF {
			break
		} else if err != nil {
			panic(err)
		}
		words = append(words, line)
	}
}

func TestCHDBuilder(t *testing.T) {
	b := Builder()
	for k, v := range sampleData {
		b.Add([]byte(k), []byte(v))
	}
	c, err := b.Build()
	assert.NoError(t, err)
	assert.Equal(t, 7, len(c.keys))
	for k, v := range sampleData {
		assert.Equal(t, []byte(v), c.Get([]byte(k)))
	}
	assert.Nil(t, c.Get([]byte("monkey")))
}

func TestCHDSerialization(t *testing.T) {
	cb := Builder()
	for _, v := range words {
		cb.Add([]byte(v), []byte(v))
	}
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
	for _, v := range words {
		assert.Equal(t, []byte(v), n.Get([]byte(v)))
	}
}

func TestCHDSerialization_empty(t *testing.T) {
	cb := Builder()
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
}

func TestCHDSerialization_one(t *testing.T) {
	cb := Builder()
	cb.Add([]byte("k"), []byte("v"))
	m, err := cb.Build()
	assert.NoError(t, err)
	w := &bytes.Buffer{}
	err = m.Write(w)
	assert.NoError(t, err)

	n, err := Mmap(w.Bytes())
	assert.NoError(t, err)
	assert.Equal(t, n.r, m.r)
	assert.Equal(t, n.indices, m.indices)
	assert.Equal(t, n.keys, m.keys)
	assert.Equal(t, n.values, m.values)
}

func BenchmarkBuiltinMap(b *testing.B) {
	keys := []string{}
	d := map[string]string{}
	for _, bk := range words {
		k := string(bk)
		d[k] = k
		keys = append(keys, k)
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = d[keys[i%len(keys)]]
	}
}

func BenchmarkCHD(b *testing.B) {
	keys := [][]byte{}
	mph := Builder()
	for _, k := range words {
		keys = append(keys, k)
		mph.Add(k, k)
	}
	h, _ := mph.Build()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		h.Get(keys[i%len(keys)])
	}
}
<|endoftext|>


<commit_before>// Copyright © 2016 Thomas Rabaix <thomas.rabaix@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/mitchellh/cli"
	"github.com/rande/gitlab-ci-helper/commands"
	"github.com/rande/gitlab-ci-helper/integrations/flowdock"
	"github.com/rande/gitlab-ci-helper/integrations/hipchat"
	"os"
)

var (
	Version = "0.0.3-Dev"
	RefLog  = "master"
)

func main() {
	ui := &cli.BasicUi{Writer: os.Stdout}

	c := cli.NewCLI("gitlab-ci-helper", "0.0.1-DEV")
	c.Args = os.Args[1:]

	c.Commands = map[string]cli.CommandFactory{
		"project:list": func() (cli.Command, error) {
			return &commands.ProjectsListCommand{
				Ui: ui,
			}, nil
		},
		"project:builds": func() (cli.Command, error) {
			return &commands.ProjectBuildsListCommand{
				Ui: ui,
			}, nil
		},
		"project:builds:artifacts": func() (cli.Command, error) {
			return &commands.ProjectBuildArtifactCommand{
				Ui: ui,
			}, nil
		},
		"ci:meta": func() (cli.Command, error) {
			return &commands.CiDumpMetaCommand{
				Ui: ui,
			}, nil
		},
		"ci:revision": func() (cli.Command, error) {
			return &commands.CiDumpRevisionCommand{
				Ui: ui,
			}, nil
		},
		"hipchat:message": func() (cli.Command, error) {
			return &hipchat.CiNotificationHipchatCommand{
				Ui: ui,
			}, nil
		},
		"flowdock:message": func() (cli.Command, error) {
			return &flowdock.CiFlowdockMessageCommand{
				Ui: ui,
			}, nil
		},
		"flowdock:status": func() (cli.Command, error) {
			return &flowdock.CiFlowdockStatusCommand{
				Ui: ui,
			}, nil
		},
		"dump:readme": func() (cli.Command, error) {
			return &commands.DumpReadmeCommand{
				Ui:       ui,
				Commands: c.Commands,
			}, nil
		},
		"version": func() (cli.Command, error) {
			return &commands.VersionCommand{
				Ui:      ui,
				Version: Version,
				RefLog:  RefLog,
			}, nil
		},
		"s3:archive": func() (cli.Command, error) {
			return &commands.S3ArchiveCommand{
				Ui: ui,
			}, nil
		},
		"s3:extract": func() (cli.Command, error) {
			return &commands.S3ExtractCommand{
				Ui: ui,
			}, nil
		},
	}

	exitStatus, _ := c.Run()

	os.Exit(exitStatus)
}
<commit_msg>Use Version variable for --version default cli<commit_after>// Copyright © 2016 Thomas Rabaix <thomas.rabaix@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/mitchellh/cli"
	"github.com/rande/gitlab-ci-helper/commands"
	"github.com/rande/gitlab-ci-helper/integrations/flowdock"
	"github.com/rande/gitlab-ci-helper/integrations/hipchat"
	"os"
)

var (
	Version = "0.0.3-Dev"
	RefLog  = "master"
)

func main() {
	ui := &cli.BasicUi{Writer: os.Stdout}

	c := cli.NewCLI("gitlab-ci-helper", Version)
	c.Args = os.Args[1:]

	c.Commands = map[string]cli.CommandFactory{
		"project:list": func() (cli.Command, error) {
			return &commands.ProjectsListCommand{
				Ui: ui,
			}, nil
		},
		"project:builds": func() (cli.Command, error) {
			return &commands.ProjectBuildsListCommand{
				Ui: ui,
			}, nil
		},
		"project:builds:artifacts": func() (cli.Command, error) {
			return &commands.ProjectBuildArtifactCommand{
				Ui: ui,
			}, nil
		},
		"ci:meta": func() (cli.Command, error) {
			return &commands.CiDumpMetaCommand{
				Ui: ui,
			}, nil
		},
		"ci:revision": func() (cli.Command, error) {
			return &commands.CiDumpRevisionCommand{
				Ui: ui,
			}, nil
		},
		"hipchat:message": func() (cli.Command, error) {
			return &hipchat.CiNotificationHipchatCommand{
				Ui: ui,
			}, nil
		},
		"flowdock:message": func() (cli.Command, error) {
			return &flowdock.CiFlowdockMessageCommand{
				Ui: ui,
			}, nil
		},
		"flowdock:status": func() (cli.Command, error) {
			return &flowdock.CiFlowdockStatusCommand{
				Ui: ui,
			}, nil
		},
		"dump:readme": func() (cli.Command, error) {
			return &commands.DumpReadmeCommand{
				Ui:       ui,
				Commands: c.Commands,
			}, nil
		},
		"version": func() (cli.Command, error) {
			return &commands.VersionCommand{
				Ui:      ui,
				Version: Version,
				RefLog:  RefLog,
			}, nil
		},
		"s3:archive": func() (cli.Command, error) {
			return &commands.S3ArchiveCommand{
				Ui: ui,
			}, nil
		},
		"s3:extract": func() (cli.Command, error) {
			return &commands.S3ExtractCommand{
				Ui: ui,
			}, nil
		},
	}

	exitStatus, _ := c.Run()

	os.Exit(exitStatus)
}
<|endoftext|>


<commit_before>package xql

import (
    "reflect"
    "strings"
    "errors"
    "time"
)

type Column struct {
    PropertySet
    FieldName  string
    ElemName   string
    Jtag       string
    Type       reflect.Type
    TypeDefine string
    Indexed    bool // Indexed or not, on field
    Nullable   bool // Nullable constraint on field
    Unique     bool // Unique constraint on field
    PrimaryKey bool //Primary Key constraint on field
    Default    interface{}
    Constraints []*Constraint
    Indexes     []*Index
    table      interface{}
}

type Declarable interface {
    Declare(props PropertySet) string
}

func DefaultDeclare(f reflect.StructField, props PropertySet) (string, error) {
    if t, ok := props.GetString("type"); ok {
        t = strings.ToLower(t)
        switch t {
        case "varchar", "string":
            return Varchar("").Declare(props), nil
        case "char":
            return Char("").Declare(props), nil
        case "text":
            return Text("").Declare(props), nil
        case "int", "integer":
            return Integer(0).Declare(props), nil
        case "smallint","smallinteger":
            return SmallInteger(0).Declare(props), nil
        case "bigint","biginteger":
            return BigInteger(0).Declare(props), nil
        case "serial":
            return Serial(0).Declare(props), nil
        case "bigserial":
            return BigSerial(0).Declare(props), nil
        case "real", "float":
            return Real(0.0).Declare(props), nil
        case "double":
            return Double(0.0).Declare(props), nil
        case "bool", "boolean":
            return Boolean(false).Declare(props), nil
        case "date":
            return Date(time.Time{}).Declare(props), nil
        case "time":
            return Time(time.Time{}).Declare(props), nil
        case "datetime", "timestamp":
            return TimeStamp(time.Time{}).Declare(props), nil
        case "decimal","numeric":
            return Decimal("").Declare(props), nil
        case "uuid":
            return UUID("").Declare(props), nil
        default:
            return t, nil
        }
    }
    switch f.Type.Kind() {
    case reflect.String:
        //size, _ := props.GetUInt("size", 32)
        //return fmt.Sprintf("VARCHAR(%d)", size), nil
        return Varchar("").Declare(props), nil
    case reflect.Int16, reflect.Uint16:
        //return "SMALLINT", nil
        return SmallInteger(0).Declare(props), nil
    case reflect.Int, reflect.Int32, reflect.Uint, reflect.Uint32:
        //return "INTEGER", nil
        return Integer(0).Declare(props), nil
    case reflect.Int64, reflect.Uint64:
        //return "BIGINT", nil
        return BigInteger(0).Declare(props), nil
    case reflect.Bool:
        return Boolean(false).Declare(props), nil
        //return "BOOLEAN", nil
    case reflect.Float32:
        //return "FLOAT", nil
        return Real(0.0).Declare(props), nil
    case reflect.Float64:
        return Double(0.0).Declare(props), nil
    }
    return "", errors.New("Unknow Type of:>" + f.Name)

}

// makeColumn
// Make a &Column{} object according to given field.
func makeColumn(t *Table, f reflect.StructField, v reflect.Value) *Column {
    props, e := ParseProperties(f.Tag.Get("xql"))
    if nil != e {
        panic(e)
    }
    field := &Column{
        FieldName: Camel2Underscore(f.Name),
        ElemName:f.Name,
        Type: f.Type,
        PropertySet: props,
    }
    jtag := f.Tag.Get("json")
    if jtag != "" {
        field.Jtag = jtag
    }else{
        field.Jtag = f.Name
    }
    if fn, ok := props.PopString("name"); ok {
        field.FieldName = fn
    }
    field.Indexed, _ = props.PopBool("index", false)
    if field.Indexed {
        field.Indexes = append(field.Indexes,
            makeIndexes(INDEX_B_TREE, t.BaseTableName()+"_"+field.FieldName, field)...)
    }
    field.Nullable, _ = props.PopBool("nullable", false)
    if field.Nullable == false {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_NOT_NULL, field)...)
    }
    field.Unique, _ = props.PopBool("unique", false)
    if field.Unique {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_UNIQUE, field)...)
    }
    field.PrimaryKey, _ = props.PopBool("primarykey", false)
    if ! field.PrimaryKey {
        field.PrimaryKey, _ = props.PopBool("pk", false)
    }
    if field.PrimaryKey {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_PRIMARYKEY, field)...)
    }
    if fk, ok := props.GetString("foreignkey", ); ok && fk != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_FOREIGNKEY, field)...)
    }else if fk, ok := props.GetString("fk", ); ok && fk != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_FOREIGNKEY, field)...)
    }
    if check, ok := props.GetString("check"); ok && check != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_CHECK, field)...)
    }
    if exclude, ok := props.GetString("exclude"); ok && exclude != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_EXCLUDE, field)...)
    }
    if df, ok := props.PopString("default"); ok {
        field.Default = df
    }
    //field.PropertySet = props
    if p, ok := v.Interface().(Declarable); ok {
        field.TypeDefine = p.Declare(props)
    }else{
        if d, e := DefaultDeclare(f, props); nil == e {
            field.TypeDefine = d
        }else{
            panic(e)
        }
    }
    return field
}

// makeColumns
// Make a list of &Column{} objects according to a given struct pointer.
func makeColumns(t *Table, p interface{}, recursive bool, skips ...string) []*Column {
    if nil == p {
        panic("Can not use nil pointer ")
    }
    et := reflect.TypeOf(p)
    ev := reflect.ValueOf(p)
    fields := []*Column{}
    for i := 0; i < et.Elem().NumField(); i++ {
        f := et.Elem().Field(i)
        v := ev.Elem().Field(i)
        if inSlice(f.Name, skips) {
            continue
        }
        x_tags := strings.Split(f.Tag.Get("xql"), ",")
        if x_tags[0] == "-" {
            continue
        }
        if f.Anonymous {
            if x_tags[0] != "-" {
                sks := getSkips(x_tags)
                for _, c := range makeColumns(t, ev.Elem().Field(i).Addr().Interface(), true, sks...) {
                    fields = append(fields, c)
                }
            } else {
                continue
            }
            continue
        }
        field := makeColumn(t, f, v)
        fields = append(fields, field)
    }
    return fields
}

<commit_msg>Updated: fixed getting jtag.<commit_after>package xql

import (
    "errors"
    "reflect"
    "strings"
    "time"
)

type Column struct {
    PropertySet
    FieldName   string
    ElemName    string
    Jtag        string
    Type        reflect.Type
    TypeDefine  string
    Indexed     bool // Indexed or not, on field
    Nullable    bool // Nullable constraint on field
    Unique      bool // Unique constraint on field
    PrimaryKey  bool //Primary Key constraint on field
    Default     interface{}
    Constraints []*Constraint
    Indexes     []*Index
    table       interface{}
}

type Declarable interface {
    Declare(props PropertySet) string
}

func DefaultDeclare(f reflect.StructField, props PropertySet) (string, error) {
    if t, ok := props.GetString("type"); ok {
        t = strings.ToLower(t)
        switch t {
        case "varchar", "string":
            return Varchar("").Declare(props), nil
        case "char":
            return Char("").Declare(props), nil
        case "text":
            return Text("").Declare(props), nil
        case "int", "integer":
            return Integer(0).Declare(props), nil
        case "smallint", "smallinteger":
            return SmallInteger(0).Declare(props), nil
        case "bigint", "biginteger":
            return BigInteger(0).Declare(props), nil
        case "serial":
            return Serial(0).Declare(props), nil
        case "bigserial":
            return BigSerial(0).Declare(props), nil
        case "real", "float":
            return Real(0.0).Declare(props), nil
        case "double":
            return Double(0.0).Declare(props), nil
        case "bool", "boolean":
            return Boolean(false).Declare(props), nil
        case "date":
            return Date(time.Time{}).Declare(props), nil
        case "time":
            return Time(time.Time{}).Declare(props), nil
        case "datetime", "timestamp":
            return TimeStamp(time.Time{}).Declare(props), nil
        case "decimal", "numeric":
            return Decimal("").Declare(props), nil
        case "uuid":
            return UUID("").Declare(props), nil
        default:
            return t, nil
        }
    }
    switch f.Type.Kind() {
    case reflect.String:
        //size, _ := props.GetUInt("size", 32)
        //return fmt.Sprintf("VARCHAR(%d)", size), nil
        return Varchar("").Declare(props), nil
    case reflect.Int16, reflect.Uint16:
        //return "SMALLINT", nil
        return SmallInteger(0).Declare(props), nil
    case reflect.Int, reflect.Int32, reflect.Uint, reflect.Uint32:
        //return "INTEGER", nil
        return Integer(0).Declare(props), nil
    case reflect.Int64, reflect.Uint64:
        //return "BIGINT", nil
        return BigInteger(0).Declare(props), nil
    case reflect.Bool:
        return Boolean(false).Declare(props), nil
        //return "BOOLEAN", nil
    case reflect.Float32:
        //return "FLOAT", nil
        return Real(0.0).Declare(props), nil
    case reflect.Float64:
        return Double(0.0).Declare(props), nil
    }
    return "", errors.New("Unknow Type of:>" + f.Name)

}

// makeColumn
// Make a &Column{} object according to given field.
func makeColumn(t *Table, f reflect.StructField, v reflect.Value) *Column {
    props, e := ParseProperties(f.Tag.Get("xql"))
    if nil != e {
        panic(e)
    }
    field := &Column{
        FieldName:   Camel2Underscore(f.Name),
        ElemName:    f.Name,
        Type:        f.Type,
        PropertySet: props,
    }
    jtag := f.Tag.Get("json")
    if jtag != "" {
        field.Jtag = strings.Split(jtag, ",")[0]
    } else {
        field.Jtag = f.Name
    }
    if fn, ok := props.PopString("name"); ok {
        field.FieldName = fn
    }
    field.Indexed, _ = props.PopBool("index", false)
    if field.Indexed {
        field.Indexes = append(field.Indexes,
            makeIndexes(INDEX_B_TREE, t.BaseTableName()+"_"+field.FieldName, field)...)
    }
    field.Nullable, _ = props.PopBool("nullable", false)
    if field.Nullable == false {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_NOT_NULL, field)...)
    }
    field.Unique, _ = props.PopBool("unique", false)
    if field.Unique {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_UNIQUE, field)...)
    }
    field.PrimaryKey, _ = props.PopBool("primarykey", false)
    if ! field.PrimaryKey {
        field.PrimaryKey, _ = props.PopBool("pk", false)
    }
    if field.PrimaryKey {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_PRIMARYKEY, field)...)
    }
    if fk, ok := props.GetString("foreignkey", ); ok && fk != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_FOREIGNKEY, field)...)
    } else if fk, ok := props.GetString("fk", ); ok && fk != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_FOREIGNKEY, field)...)
    }
    if check, ok := props.GetString("check"); ok && check != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_CHECK, field)...)
    }
    if exclude, ok := props.GetString("exclude"); ok && exclude != "" {
        field.Constraints = append(field.Constraints,
            makeConstraints(CONSTRAINT_EXCLUDE, field)...)
    }
    if df, ok := props.PopString("default"); ok {
        field.Default = df
    }
    //field.PropertySet = props
    if p, ok := v.Interface().(Declarable); ok {
        field.TypeDefine = p.Declare(props)
    } else {
        if d, e := DefaultDeclare(f, props); nil == e {
            field.TypeDefine = d
        } else {
            panic(e)
        }
    }
    return field
}

// makeColumns
// Make a list of &Column{} objects according to a given struct pointer.
func makeColumns(t *Table, p interface{}, recursive bool, skips ...string) []*Column {
    if nil == p {
        panic("Can not use nil pointer ")
    }
    et := reflect.TypeOf(p)
    ev := reflect.ValueOf(p)
    fields := []*Column{}
    for i := 0; i < et.Elem().NumField(); i++ {
        f := et.Elem().Field(i)
        v := ev.Elem().Field(i)
        if inSlice(f.Name, skips) {
            continue
        }
        x_tags := strings.Split(f.Tag.Get("xql"), ",")
        if x_tags[0] == "-" {
            continue
        }
        if f.Anonymous {
            if x_tags[0] != "-" {
                sks := getSkips(x_tags)
                for _, c := range makeColumns(t, ev.Elem().Field(i).Addr().Interface(), true, sks...) {
                    fields = append(fields, c)
                }
            } else {
                continue
            }
            continue
        }
        field := makeColumn(t, f, v)
        fields = append(fields, field)
    }
    return fields
}
<|endoftext|>