Skip to content

Commit

Permalink
Allow specifying directory as input.
Browse files Browse the repository at this point in the history
Also ignore files that don't contain exported methods
of the source struct, to avoid problems with imports (see vburenin#9).

Fixes vburenin#3
  • Loading branch information
nkovacs committed Jul 5, 2017
1 parent 6f0f281 commit 6547b2a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 33 deletions.
29 changes: 28 additions & 1 deletion ifacemaker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/mkideal/cli"
Expand All @@ -12,7 +13,7 @@ import (

type cmdlineArgs struct {
cli.Helper
Files []string `cli:"*f,file" usage:"Go source file to read"`
Files []string `cli:"*f,file" usage:"Go source file or directory to read"`
StructType string `cli:"*s,struct" usage:"Generate an interface for this structure name"`
IfaceName string `cli:"*i,iface" usage:"Name of the generated interface"`
PkgName string `cli:"*p,pkg" usage:"Package name for the generated interface"`
Expand All @@ -25,7 +26,33 @@ func run(args *cmdlineArgs) {
StructName: args.StructType,
CopyDocs: args.CopyDocs,
}
allFiles := []string{}
for _, f := range args.Files {
fi, err := os.Stat(f)
if err != nil {
log.Fatal(err.Error())
}
if fi.IsDir() {
dir, err := os.Open(f)
if err != nil {
log.Fatal(err.Error())
}
dirFiles, err := dir.Readdir(-1)
dir.Close()
if err != nil {
log.Fatal(err.Error())
}
for _, fi := range dirFiles {
if !fi.IsDir() {
allFiles = append(allFiles, filepath.Join(f, fi.Name()))
}
}
} else {
allFiles = append(allFiles, f)
}
}

for _, f := range allFiles {
src, err := ioutil.ReadFile(f)
if err != nil {
log.Fatal(err.Error())
Expand Down
72 changes: 40 additions & 32 deletions maker/maker.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,46 @@ func (m *Maker) ParseSource(src []byte, filename string) error {
return errors.Wrap(err, "parsing file failed")
}

hasMethods := false
for _, d := range a.Decls {
if a, fd := m.getReceiverTypeName(d); a == m.StructName {
if !fd.Name.IsExported() {
continue
}
hasMethods = true
methodName := fd.Name.String()
if _, ok := m.methodNames[methodName]; ok {
continue
}

params, err := m.printParameters(fd.Type.Params)
if err != nil {
return errors.Wrap(err, "failed printing parameters")
}
ret, err := m.printParameters(fd.Type.Results)
if err != nil {
return errors.Wrap(err, "failed printing return values")
}
code := fmt.Sprintf("%s(%s) (%s)", methodName, params, ret)
var docs []string
if fd.Doc != nil && m.CopyDocs {
for _, d := range fd.Doc.List {
docs = append(docs, d.Text)
}
}
m.methodNames[methodName] = struct{}{}
m.methods = append(m.methods, &method{
Code: code,
Docs: docs,
})
}
}
// No point checking imports if there are no relevant methods in this file.
// This also avoids throwing unnecessary errors about imports in files that
// are not relevant.
if !hasMethods {
return nil
}
for _, i := range a.Imports {
alias := ""
if i.Name != nil {
Expand Down Expand Up @@ -104,38 +144,6 @@ func (m *Maker) ParseSource(src []byte, filename string) error {
m.imports = append(m.imports, imp)
}
}
for _, d := range a.Decls {
if a, fd := m.getReceiverTypeName(d); a == m.StructName {
if !fd.Name.IsExported() {
continue
}
methodName := fd.Name.String()
if _, ok := m.methodNames[methodName]; ok {
continue
}

params, err := m.printParameters(fd.Type.Params)
if err != nil {
return errors.Wrap(err, "failed printing parameters")
}
ret, err := m.printParameters(fd.Type.Results)
if err != nil {
return errors.Wrap(err, "failed printing return values")
}
code := fmt.Sprintf("%s(%s) (%s)", methodName, params, ret)
var docs []string
if fd.Doc != nil && m.CopyDocs {
for _, d := range fd.Doc.List {
docs = append(docs, d.Text)
}
}
m.methodNames[methodName] = struct{}{}
m.methods = append(m.methods, &method{
Code: code,
Docs: docs,
})
}
}

return nil
}
Expand Down

0 comments on commit 6547b2a

Please sign in to comment.