Skip to content

Commit 1e1c747

Browse files
Merge pull request #117 from logic-building/SortSetDefault
Generating sort functions and set functions are default now. Sort and set options can override the default behavior
2 parents a8cae26 + 967bb36 commit 1e1c747

File tree

4 files changed

+1022
-99
lines changed

4 files changed

+1022
-99
lines changed

gofp/gofp.go

Lines changed: 240 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Note:
5353
package main
5454

5555
import (
56+
"bufio"
5657
"flag"
5758
"fmt"
5859
"log"
@@ -150,7 +151,7 @@ func main() {
150151
var setCode string
151152

152153
if *setStr != "" {
153-
setCode = generateSetMethods(*setStr)
154+
setCode = generateSetMethods(*setStr, nil)
154155
}
155156

156157
var sortingCode string
@@ -160,7 +161,27 @@ func main() {
160161
`import "sync" `,
161162
`import "sort"
162163
import "sync" `, -1)
163-
sortingCode = generateSortMethods(*sortStr)
164+
sortingCode = generateSortMethods(*sortStr, nil)
165+
}
166+
167+
// Generate set and sort functions for all the types of struct
168+
if *sortStr == "" || *setStr == "" {
169+
structToFieldsMap := findStructNamesAndFieldsGivenInGoGenerate()
170+
171+
// 2nd condition is ignoring auto generation of sort functions for `all fp in 1 place strategy"
172+
// Can be done in future : change the logic to find struct name(employee.Teacher) current logic is not checking .
173+
if *sortStr == "" && strings.Index(*types, ".") < 0 {
174+
generatedCode = strings.Replace(generatedCode,
175+
`import "sync" `,
176+
`import "sort"
177+
import "sync" `, -1)
178+
sortingCode = generateSortMethods(*sortStr, structToFieldsMap)
179+
180+
}
181+
182+
if *setStr == "" {
183+
setCode = generateSetMethods(*setStr, structToFieldsMap)
184+
}
164185
}
165186

166187
f.Write([]byte(generatedCode + "\n" + generatedCodeIO + "\n" + generatedCodeII + sortingCode + setCode))
@@ -172,7 +193,6 @@ import "sync" `, -1)
172193
if !isAlreadyRun {
173194
fmt.Println("Functional code generation is successful.")
174195
}
175-
176196
}
177197

178198
// When imports are passed, Remove 1st part of "." in <FOUTPUT_TYPE> and <FINPUT_TYPE>
@@ -807,8 +827,8 @@ func quoteForTheDay() string {
807827
"Love is the greatest power on earth",
808828
"When you wish good for others, good things come back to you. This is the Law of Nature",
809829
"If you can win over your mind, you can win over the whole world",
810-
"Darkness cannot drive out darkness, only light can do that. Hate cannot drive out hate. only love cna do that",
811-
"Silence says so mcuh. Just listen",
830+
"Darkness cannot drive out darkness, only light can do that. Hate cannot drive out hate. only love can do that",
831+
"Silence says so much. Just listen",
812832
"The greatest gift human can give to himself and others are tolerance and forgiveness",
813833
"The practice of devotion involves replacing desires for the world with the desires for God",
814834
"The wealth of divine love is the only true wealth. Every other form of wealth simply enhances one's pride",
@@ -819,7 +839,7 @@ func quoteForTheDay() string {
819839
"If you have to choose between being kind and being right choose being kind and you will always be right",
820840
"Silence & Smile are two powerful tools.Smile is the way to solve many problems & Silence is the way to avoid many problems",
821841
"Don't get upset with people and situations, because both are powerless without your reaction",
822-
"Most of the people are in lack of knowledge.Don't hate people.Love people and understand people are under influence of ignorance. Always do righteously.",
842+
"Most of the people are in lack of knowledge.Don't hate them.Love them and understand that they are under influence of ignorance. Always do righteously.",
823843
"Every way and means that leads our mind to God is Devotion",
824844
"The Only Purpose of Our Human Life is to Attain God",
825845
"Meditation. Because some questions can't be answered by Google!",
@@ -832,10 +852,23 @@ func quoteForTheDay() string {
832852
"If you can establish your relationship with God, that ultimate satisfaction that you have been searching for since innumerable lifetimes, will eventually be attained",
833853
"The Joy of the mind is the measure of its strength",
834854
"When you come to a point where you have no need to impress anybody, your freedom will begin",
835-
"Ritualistic worship, chanting and meditation are done with the body, voice and the mind: they excel each other in the ascending order",
855+
"Ritualistic worship, chanting and meditation are done with the body, voice and the mind: they excel each other in the ascending order - Ramana Maharshi",
836856
"Uttering the sacred word, either in a loud or low tone is preferable to chants in praise of the Supreme. Mental contemplation is superior to both",
837857
"When one learns to turn the mind away from material allurements and renounces the desires of the senses, such a person comes in touch with the inner bliss of the soul",
838858
"When we decide that God is ours and the whole world is His, then our consciousness transforms from seeking self-enjoyment to serving the Lord with everything that we have",
859+
"If you want to change the world, go home and love your family - Mother Teresa",
860+
"Every time you smile at someone, it is an action of love, a gift to that person, a beautiful thing. - Mother Teresa",
861+
"No color, no religion, no nationality should come between us, we are all children of God. - Mother Teresa",
862+
"In this life, we cannot always do great things. But we can do small things with great love. - Mother Teresa",
863+
`Lord, make an instrument of the peace,
864+
Where there is hatred, let me show love;
865+
Where there is injury, pardon;
866+
Where there is doubt, faith;
867+
Where there is despair, hope;
868+
Where there is darkness, light;
869+
Where there is sadness, Joy.
870+
`,
871+
"A generous heart, kind speech, and a life of service and compassion are the things which renew humanity, Buddha",
839872
}
840873

841874
s := rand.NewSource(time.Now().Unix())
@@ -881,69 +914,225 @@ func runWithin(duration time.Duration) bool {
881914
return runWithin("/tmp/functional-go.txt", duration)
882915
}
883916

884-
func generateSortMethods(sortStr string) string {
917+
func generateSortMethods(sortStr string, allFields map[string][]string) string {
918+
if allFields != nil {
919+
template := ""
920+
for structName, fieldsAndTypes := range allFields {
921+
if len(fieldsAndTypes) > 0 {
922+
for _, fieldType := range fieldsAndTypes {
923+
924+
fieldName := strings.Split(fieldType, " ")[0]
925+
926+
fStructName := strings.Title(structName)
927+
fFieldName := strings.Title(fieldName)
928+
929+
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName)
930+
template += template2.SortStruct()
931+
template = r.Replace(template)
932+
933+
}
934+
}
935+
}
936+
return template
937+
} else {
938+
if len(strings.TrimSpace(sortStr)) == 0 {
939+
fmt.Println("-sort: value is empty. ignoring sort methods")
940+
return ""
941+
}
942+
943+
template := ""
944+
sortedStrList := strings.Split(sortStr, ",")
945+
946+
for _, sortedStrItem := range sortedStrList {
947+
sortedStrItem = strings.TrimSpace(sortedStrItem)
948+
sortStrItemElements := strings.Split(sortedStrItem, ":")
949+
if len(sortStrItemElements) != 2 {
950+
fmt.Println("-sort: format is not valid. expected format for option -sort: <struct_name>:<field_name>. eg. -sort=\"Employee:Salary\"")
951+
fmt.Println("ignoring sort methods")
952+
return ""
953+
}
954+
955+
structName := strings.TrimSpace(sortStrItemElements[0])
956+
fieldName := strings.TrimSpace(sortStrItemElements[1])
957+
958+
fStructName := strings.Title(structName)
959+
fFieldName := strings.Title(fieldName)
885960

886-
if len(strings.TrimSpace(sortStr)) == 0 {
887-
fmt.Println("-sort: value is empty. ignoring sort methods")
888-
return ""
961+
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName)
962+
template += template2.SortStruct()
963+
template = r.Replace(template)
964+
}
965+
966+
return template
889967
}
968+
}
890969

891-
template := ""
892-
sortedStrList := strings.Split(sortStr, ",")
893-
894-
for _, sortedStrItem := range sortedStrList {
895-
sortedStrItem = strings.TrimSpace(sortedStrItem)
896-
sortStrItemElements := strings.Split(sortedStrItem, ":")
897-
if len(sortStrItemElements) != 2 {
898-
fmt.Println("-sort: format is not valid. expected format for option -sort: <struct_name>:<field_name>. eg. -sort=\"Employee:Salary\"")
899-
fmt.Println("ignoring sort methods")
970+
func generateSetMethods(setStr string, allFields map[string][]string) string {
971+
972+
if allFields != nil {
973+
template := ""
974+
for structName, fieldsAndTypes := range allFields {
975+
if len(fieldsAndTypes) > 0 {
976+
for _, fieldType := range fieldsAndTypes {
977+
978+
fieldName := strings.Split(fieldType, " ")[0]
979+
fieldType := strings.Split(fieldType, " ")[1]
980+
981+
fStructName := strings.Title(structName)
982+
fFieldName := strings.Title(fieldName)
983+
984+
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName, "<FIELD_TYPE>", fieldType)
985+
template += template2.SetStruct()
986+
template = r.Replace(template)
987+
988+
}
989+
}
990+
}
991+
return template
992+
993+
} else {
994+
if len(strings.TrimSpace(setStr)) == 0 {
995+
fmt.Println("-set: value is empty. ignoring set methods")
900996
return ""
901997
}
902998

903-
structName := strings.TrimSpace(sortStrItemElements[0])
904-
fieldName := strings.TrimSpace(sortStrItemElements[1])
999+
template := ""
1000+
sortedStrList := strings.Split(setStr, ",")
9051001

906-
fStructName := strings.Title(structName)
907-
fFieldName := strings.Title(fieldName)
1002+
for _, sortedStrItem := range sortedStrList {
1003+
sortedStrItem = strings.TrimSpace(sortedStrItem)
1004+
sortStrItemElements := strings.Split(sortedStrItem, ":")
1005+
if len(sortStrItemElements) != 3 {
1006+
fmt.Println("-set: format is not valid. expected format for option -sort: <struct_name>:<field_name>:<field_type>. eg. -set=\"Employee:Salary:float64\"")
1007+
fmt.Println("ignoring set methods")
1008+
return ""
1009+
}
9081010

909-
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName)
910-
template += template2.SortStruct()
911-
template = r.Replace(template)
1011+
structName := strings.TrimSpace(sortStrItemElements[0])
1012+
fieldName := strings.TrimSpace(sortStrItemElements[1])
1013+
fieldType := strings.TrimSpace(sortStrItemElements[2])
1014+
1015+
fStructName := strings.Title(structName)
1016+
fFieldName := strings.Title(fieldName)
1017+
1018+
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName, "<FIELD_TYPE>", fieldType)
1019+
template += template2.SetStruct()
1020+
template = r.Replace(template)
1021+
}
1022+
1023+
return template
9121024
}
1025+
}
1026+
1027+
func ListDir(dirName string) ([]string, error) {
1028+
var files []string
9131029

914-
return template
1030+
root := dirName
1031+
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
1032+
files = append(files, path)
1033+
return nil
1034+
})
1035+
if err != nil {
1036+
return nil, err
1037+
}
1038+
return files, nil
9151039
}
9161040

917-
func generateSetMethods(setStr string) string {
1041+
func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
1042+
allTypesInGoGenerate := strings.Split(*types, ",")
9181043

919-
if len(strings.TrimSpace(setStr)) == 0 {
920-
fmt.Println("-set: value is empty. ignoring set methods")
921-
return ""
1044+
isUserDefinedType := func(dataType string) bool {
1045+
switch strings.ToLower(strings.TrimSpace(dataType)) {
1046+
case "int", "int64", "int32", "int16", "int8", "uint", "uint64", "uint32", "uint16", "uint8", "float64", "float32", "string", "bool":
1047+
return false
1048+
}
1049+
return true
9221050
}
1051+
userDefinedTypesInGoGenerate := fp.MapStr(strings.TrimSpace, fp.FilterStr(isUserDefinedType, allTypesInGoGenerate))
9231052

924-
template := ""
925-
sortedStrList := strings.Split(setStr, ",")
926-
927-
for _, sortedStrItem := range sortedStrList {
928-
sortedStrItem = strings.TrimSpace(sortedStrItem)
929-
sortStrItemElements := strings.Split(sortedStrItem, ":")
930-
if len(sortStrItemElements) != 3 {
931-
fmt.Println("-set: format is not valid. expected format for option -sort: <struct_name>:<field_name>:<field_type>. eg. -set=\"Employee:Salary:float64\"")
932-
fmt.Println("ignoring set methods")
933-
return ""
1053+
structToFieldsMap := make(map[string][]string, len(userDefinedTypesInGoGenerate))
1054+
structToFieldsMapIndex := 0
1055+
1056+
path, err := os.Getwd()
1057+
if err != nil {
1058+
fmt.Println(err)
1059+
}
1060+
files, err := ListDir(path)
1061+
if err != nil {
1062+
fmt.Printf("\n error scanning current folder=%v, error=%v. sort and set methods will be skipped", path, err)
1063+
return nil
1064+
}
1065+
1066+
onlyGoFiles := fp.FilterStr(func(str string) bool {
1067+
return strings.Contains(str, ".go")
1068+
}, files)
1069+
1070+
totalStructCount := 0
1071+
for _, fileStr := range onlyGoFiles {
1072+
1073+
if totalStructCount == len(userDefinedTypesInGoGenerate) {
1074+
break
9341075
}
9351076

936-
structName := strings.TrimSpace(sortStrItemElements[0])
937-
fieldName := strings.TrimSpace(sortStrItemElements[1])
938-
fieldType := strings.TrimSpace(sortStrItemElements[2])
1077+
file, err := os.Open(fileStr)
1078+
if err != nil {
1079+
fmt.Printf("\n error reading file=%s to generate sort and set methods. skipping set and sort functions", fileStr)
1080+
return nil
1081+
}
1082+
defer file.Close()
9391083

940-
fStructName := strings.Title(structName)
941-
fFieldName := strings.Title(fieldName)
1084+
scanner := bufio.NewScanner(file)
1085+
packageFound := false
1086+
startCollectingStructInfo := false
1087+
var structFields []string
9421088

943-
r := strings.NewReplacer("<STRUCT_NAME>", structName, "<FIELD_NAME>", fieldName, "<FSTRUCT_NAME>", fStructName, "<FFIELD_NAME>", fFieldName, "<FIELD_TYPE>", fieldType)
944-
template += template2.SetStruct()
945-
template = r.Replace(template)
1089+
for scanner.Scan() {
1090+
txtLine := scanner.Text()
1091+
if len(txtLine) > 0 && strings.Contains(txtLine, *pkgName) {
1092+
packageFound = true
1093+
}
1094+
// reading lines of file of package mentioned in go:generate
1095+
if packageFound {
1096+
1097+
words := strings.Fields(txtLine)
1098+
1099+
// Found struct
1100+
if len(words) == 4 && strings.Contains(words[0], "type") && fp.ExistsStr(words[1], userDefinedTypesInGoGenerate) && strings.Contains(words[2], "struct") && strings.Contains(words[3], "{") {
1101+
startCollectingStructInfo = true
1102+
totalStructCount++
1103+
}
1104+
1105+
if startCollectingStructInfo && strings.TrimSpace(txtLine) == "}" {
1106+
startCollectingStructInfo = false
1107+
1108+
newStructFieldsArr := make([]string, len(structFields))
1109+
for i, v := range structFields {
1110+
newStructFieldsArr[i] = v
1111+
}
1112+
structToFieldsMap[userDefinedTypesInGoGenerate[structToFieldsMapIndex]] = newStructFieldsArr
1113+
structToFieldsMapIndex++
1114+
structFields = make([]string, 0)
1115+
}
1116+
1117+
if startCollectingStructInfo {
1118+
if len(words) >= 2 {
1119+
field := strings.TrimSpace(words[0])
1120+
dataType := strings.TrimSpace(words[1])
1121+
1122+
switch dataType {
1123+
case "int", "int64", "int32", "int16", "int8", "uint", "uint64", "uint32", "uint16", "uint8", "float64", "float32", "string", "time.Time":
1124+
structFields = append(structFields, field+" "+dataType)
1125+
}
1126+
}
1127+
}
1128+
}
1129+
}
1130+
1131+
if err := scanner.Err(); err != nil {
1132+
fmt.Printf("\n error scanning data from file %s. skipping generation of sort and set functions", fileStr)
1133+
return nil
1134+
}
9461135
}
9471136

948-
return template
1137+
return structToFieldsMap
9491138
}

0 commit comments

Comments
 (0)