-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
556d8c1
commit 0b95d09
Showing
3 changed files
with
173 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io/fs" | ||
"os" | ||
"path" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
"gitub.com/strangelove-ventures/spawn/spawn" | ||
) | ||
|
||
func ProtoServiceGenerate() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
// TODO: this name is ew | ||
// TODO: Put this in the make file on proto-gen? (after) | ||
Use: "service-generate [module]", | ||
Short: "Auto generate the MsgService stubs from proto -> Cosmos-SDK", | ||
Example: `spawn service-generate mymodule`, | ||
Args: cobra.MaximumNArgs(1), | ||
Aliases: []string{"sg"}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
fmt.Println("service-generate called") | ||
|
||
cwd, err := os.Getwd() | ||
if err != nil { | ||
fmt.Println("Error: ", err) | ||
} | ||
|
||
protoPath := path.Join(cwd, "proto") | ||
|
||
dirs, err := os.ReadDir(protoPath) | ||
if err != nil { | ||
fmt.Println("Error: ", err) | ||
} | ||
|
||
absDirs := make([]string, 0) | ||
for _, dir := range dirs { | ||
if !dir.IsDir() { | ||
continue | ||
} | ||
|
||
if len(args) > 0 && dir.Name() != args[0] { | ||
continue | ||
} | ||
|
||
absDirs = append(absDirs, path.Join(protoPath, dir.Name())) | ||
} | ||
|
||
fmt.Println("Found dirs: ", absDirs) | ||
|
||
// walk it | ||
|
||
modules := make(map[string]map[spawn.FileType][]spawn.ProtoService) | ||
|
||
fs.WalkDir(os.DirFS(protoPath), ".", func(relPath string, d fs.DirEntry, e error) error { | ||
if !strings.HasSuffix(relPath, ".proto") { | ||
return nil | ||
} | ||
|
||
// read file content | ||
content, err := os.ReadFile(path.Join(protoPath, relPath)) | ||
if err != nil { | ||
fmt.Println("Error: ", err) | ||
} | ||
|
||
fileType := spawn.SortContentToFileType(content) | ||
|
||
parent := path.Dir(relPath) | ||
parent = strings.Split(parent, "/")[0] | ||
|
||
// add/append to modules | ||
if _, ok := modules[parent]; !ok { | ||
modules[parent] = make(map[spawn.FileType][]spawn.ProtoService) | ||
} | ||
|
||
fmt.Println("debugging... : ", parent, relPath, fileType) | ||
|
||
switch fileType { | ||
case spawn.Tx: | ||
fmt.Println("File is a transaction") | ||
tx := spawn.ProtoServiceParser(content) | ||
modules[parent][spawn.Tx] = append(modules[parent][spawn.Tx], tx...) | ||
|
||
case spawn.Query: | ||
fmt.Println("File is a query") | ||
query := spawn.ProtoServiceParser(content) | ||
modules[parent][spawn.Query] = append(modules[parent][spawn.Query], query...) | ||
case spawn.None: | ||
fmt.Println("File is neither a transaction nor a query") | ||
} | ||
|
||
return nil | ||
}) | ||
|
||
fmt.Printf("Modules: %+v\n", modules) | ||
|
||
}, | ||
} | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package spawn | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// The Name, RequestMsg, and ResponseMsg fields of rpc services | ||
type ProtoService struct { | ||
Name string | ||
Req string | ||
Res string | ||
} | ||
|
||
// ProtoServiceParser parses out a proto file and returns all the services within it. | ||
func ProtoServiceParser(content []byte) []ProtoService { | ||
qss := make([]ProtoService, 0) | ||
c := strings.Split(string(content), "\n") | ||
|
||
for idx, line := range c { | ||
if strings.Contains(line, "rpc ") { | ||
fmt.Println("Found rpc line: ", strings.Trim(line, " ")) | ||
|
||
// if line does not end with {, we also need to load the next line | ||
if !strings.HasSuffix(line, "{") { | ||
line = line + c[idx+1] | ||
} | ||
|
||
line = strings.Trim(line, " ") | ||
|
||
line = strings.NewReplacer("rpc", "", "returns", "", "(", " ", ")", " ", "{", "", "}", "").Replace(line) | ||
|
||
words := strings.Fields(line) | ||
qss = append(qss, ProtoService{ | ||
Name: words[0], | ||
Req: words[1], | ||
Res: words[2], | ||
}) | ||
} | ||
} | ||
|
||
return qss | ||
} | ||
|
||
// FileType tells the application which type of proto file is it so we can sort Txs from Queries | ||
type FileType string | ||
|
||
const ( | ||
Tx FileType = "tx" | ||
Query FileType = "query" | ||
None FileType = "none" | ||
) | ||
|
||
// returns "tx" or "query" depending on the content of the file | ||
func SortContentToFileType(bz []byte) FileType { | ||
res := string(bz) | ||
|
||
// if `service Query` or `message Query` found in the file, it's a query | ||
if strings.Contains(res, "service Query") || strings.Contains(res, "message Query") { | ||
return Query | ||
} | ||
|
||
// if `service Msg` or `service Tx` or `message Msg` | ||
if strings.Contains(res, "service Msg") || strings.Contains(res, "service Tx") || strings.Contains(res, "message Msg") { | ||
return Tx | ||
} | ||
|
||
return None | ||
} |