Skip to content

Commit

Permalink
add option to extract api struct name
Browse files Browse the repository at this point in the history
part of #98
  • Loading branch information
Ivan Vlasic committed Dec 2, 2021
1 parent 0ec49f4 commit 6d15cc6
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 0 deletions.
50 changes: 50 additions & 0 deletions cli/controller/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package controller
import (
"errors"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -255,3 +258,50 @@ func saveFile(in []byte, path string) error {
}
return nil
}

func extractApiStructName(api, dir string) (string, error) {
pkgs, err := parser.ParseDir(token.NewFileSet(), dir, nil, parser.AllErrors)
if err != nil {
return "", log.Wrap(err)
}
pkg, ok := pkgs[api]
if !ok {
return "", log.Wrapf("package %s doesn't exist in folder %s", api, dir)
}
for _, v := range pkg.Files {
for _, o := range v.Scope.Objects {
if o.Name == "New" && o.Kind.String() == "func" {
decl, ok := o.Decl.(*ast.FuncDecl)
if !ok {
return "", log.Wrapf("could not find declaration of function New")
}
if len(decl.Type.Params.List) > 0 {
return "", log.Wrapf("function New should have no parameters")
}
rl := decl.Type.Results.List
if len(rl) > 1 {
return "", log.Wrapf("too many return values for New")
}
var idExpr ast.Expr
expr, ok := rl[0].Type.(*ast.StarExpr)
if ok {
idExpr = expr.X
} else {
idExpr = rl[0].Type
}
ident, ok := idExpr.(*ast.Ident)
if ok && ident.Obj != nil {
ft, ok := ident.Obj.Decl.(*ast.TypeSpec)
if ok {
_, ok := ft.Type.(*ast.StructType)
if ok {
return ident.Name, nil
}
}
}
return "", log.Wrapf("return value of New is not struct or pointer to struct")
}
}
}
return "", log.Wrapf("could not find function New for api %s", api)
}
51 changes: 51 additions & 0 deletions cli/controller/generate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package controller

import (
"fmt"
"testing"

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

func TestExtractApiStructNamePtr(t *testing.T) {
stc, err := extractApiStructName("ping", "testdata/generate/ping_ptr")
require.NoError(t, err)
assert.Equal(t, "Ping", stc)
}

func TestExtractApiStructNameStruct(t *testing.T) {
stc, err := extractApiStructName("ping", "testdata/generate/ping_struct")
require.NoError(t, err)
assert.Equal(t, "Ping", stc)
}

func TestExtractApiStructNameNoNew(t *testing.T) {
_, err := extractApiStructName("ping", "testdata/generate/no_new")
fmt.Println(err)
require.Error(t, err)
}

func TestExtractApiStructNameNewWithParameters(t *testing.T) {
_, err := extractApiStructName("ping", "testdata/generate/parameters")
fmt.Println(err)
require.Error(t, err)
}

func TestExtractApiStructNameTooManyValues(t *testing.T) {
_, err := extractApiStructName("ping", "testdata/generate/return_values")
fmt.Println(err)
require.Error(t, err)
}

func TestExtractApiStructNameWrongValue(t *testing.T) {
_, err := extractApiStructName("ping", "testdata/generate/return_value")
fmt.Println(err)
require.Error(t, err)
}

func TestExtractApiStructNameNewWrongType(t *testing.T) {
_, err := extractApiStructName("ping", "testdata/generate/new_wrong_type")
fmt.Println(err)
require.Error(t, err)
}
3 changes: 3 additions & 0 deletions cli/controller/testdata/generate/new_wrong_type/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ping

const New = "this should be a function"
3 changes: 3 additions & 0 deletions cli/controller/testdata/generate/no_new/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package ping

type Ping struct{}
7 changes: 7 additions & 0 deletions cli/controller/testdata/generate/parameters/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ping

type Ping struct{}

func New(par string) *Ping {
return Ping{}
}
7 changes: 7 additions & 0 deletions cli/controller/testdata/generate/ping_ptr/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ping

type Ping struct{}

func New() *Ping {
return &Ping{}
}
7 changes: 7 additions & 0 deletions cli/controller/testdata/generate/ping_struct/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ping

type Ping struct{}

func New() Ping {
return Ping{}
}
7 changes: 7 additions & 0 deletions cli/controller/testdata/generate/return_value/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ping

type Ping struct{}

func New() int {
return -1
}
7 changes: 7 additions & 0 deletions cli/controller/testdata/generate/return_values/ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ping

type Ping struct{}

func New() (*Ping, error) {
return Ping{}
}

0 comments on commit 6d15cc6

Please sign in to comment.