add: message only from this file

This commit is contained in:
Gyu-Ho Lee 2016-04-21 16:36:58 -07:00
parent adad2168d1
commit fd023d24d8
5 changed files with 71 additions and 51 deletions

22
main.go
View File

@ -15,13 +15,17 @@
// protodoc generates Protocol Buffer documentation. // protodoc generates Protocol Buffer documentation.
// //
// Usage: // Usage:
// protodoc [flags] // protodoc [flags]
// //
// Flags: // Flags:
// -h, --help help for protodoc // --directories value comma separated map of target directory to parse options (e.g. 'dirA=message,dirB=message_service')
// -o, --languages value language options in field descriptions (default [Go,C++,Java,Python]) // -d, --directory string target directory where Protocol Buffer files are.
// -p, --target-path string file path to save the documentation // -h, --help help for protodoc
// -t, --title string title of documentation // -l, --languages value language options in field descriptions (Go, C++, Java, Python, Ruby, C#) (default [])
// --message-only-from-this-file string if specified, it parses only the messages in this file within the directory
// -o, --output string output file path to save documentation
// -p, --parse value Protocol Buffer types to parse (message, service) (default [service,message])
// -t, --title string title of documentation
// //
package main package main
@ -48,7 +52,8 @@ var (
title string title string
outputPath string outputPath string
targetDirectories mapString targetDirectories mapString
messageOnlyFromThisFile string
) )
type mapString map[string][]parse.ParseOption type mapString map[string][]parse.ParseOption
@ -94,13 +99,14 @@ func init() {
rootCommand.PersistentFlags().StringVarP(&outputPath, "output", "o", "", "output file path to save documentation") rootCommand.PersistentFlags().StringVarP(&outputPath, "output", "o", "", "output file path to save documentation")
rootCommand.PersistentFlags().Var(&targetDirectories, "directories", "comma separated map of target directory to parse options (e.g. 'dirA=message,dirB=message_service')") rootCommand.PersistentFlags().Var(&targetDirectories, "directories", "comma separated map of target directory to parse options (e.g. 'dirA=message,dirB=message_service')")
rootCommand.PersistentFlags().StringVar(&messageOnlyFromThisFile, "message-only-from-this-file", "", "if specified, it parses only the messages in this file within the directory")
} }
func CommandFunc(cmd *cobra.Command, args []string) error { func CommandFunc(cmd *cobra.Command, args []string) error {
var rs string var rs string
if len(targetDirectories) == 0 { if len(targetDirectories) == 0 {
log.Println("opening", targetDirectory) log.Println("opening", targetDirectory)
proto, err := parse.ReadDir(targetDirectory) proto, err := parse.ReadDir(targetDirectory, "")
if err != nil { if err != nil {
return err return err
} }
@ -121,7 +127,7 @@ func CommandFunc(cmd *cobra.Command, args []string) error {
} else { } else {
for k, opts := range targetDirectories { for k, opts := range targetDirectories {
log.Println("opening", k) log.Println("opening", k)
proto, err := parse.ReadDir(k) proto, err := parse.ReadDir(k, messageOnlyFromThisFile)
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,7 +17,7 @@ package parse
import "testing" import "testing"
func TestMarkdown(t *testing.T) { func TestMarkdown(t *testing.T) {
proto, err := ReadDir("testdata") proto, err := ReadDir("testdata", "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -62,33 +62,47 @@ const (
parsingRPC parsingRPC
) )
func ReadDir(targetDir string) (*Proto, error) { func ReadDir(targetDir, messageOnlyFromThisFile string) (*Proto, error) {
rm, err := walkDirExt(targetDir, ".proto") rm, err := walkDirExt(targetDir, ".proto")
if err != nil { if err != nil {
return nil, err return nil, err
} }
var lines []string pr := &Proto{
for _, fpath := range rm { Services: []ProtoService{},
f, err := os.OpenFile(fpath, os.O_RDONLY, 0444) Messages: []ProtoMessage{},
if err != nil {
return nil, err
}
ls, err := readLines(f)
if err != nil {
f.Close()
return nil, err
}
lines = append(lines, ls...)
f.Close()
} }
for _, fpath := range rm {
p, err := ReadFile(fpath)
if err != nil {
return nil, err
}
pr.Services = append(pr.Services, p.Services...)
if messageOnlyFromThisFile == "" ||
(messageOnlyFromThisFile != "" && strings.HasSuffix(fpath, messageOnlyFromThisFile)) {
pr.Messages = append(pr.Messages, p.Messages...)
}
}
return pr, nil
}
func ReadFile(fpath string) (*Proto, error) {
f, err := os.OpenFile(fpath, os.O_RDONLY, 0444)
if err != nil {
return nil, err
}
lines, err := readLines(f)
if err != nil {
f.Close()
return nil, err
}
f.Close()
var ( var (
rp = Proto{ rp = Proto{
Messages: []ProtoMessage{},
Services: []ProtoService{}, Services: []ProtoService{},
Messages: []ProtoMessage{},
} }
mode = reading mode = reading

View File

@ -17,7 +17,7 @@ package parse
import "testing" import "testing"
func TestReadDir(t *testing.T) { func TestReadDir(t *testing.T) {
proto, err := ReadDir("testdata") proto, err := ReadDir("testdata", "")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -18,25 +18,41 @@ import "sort"
// Proto represents sets of 'ProtoMessage' and 'ProtoService'. // Proto represents sets of 'ProtoMessage' and 'ProtoService'.
type Proto struct { type Proto struct {
Messages []ProtoMessage
Services []ProtoService Services []ProtoService
Messages []ProtoMessage
} }
type messages []ProtoMessage
func (s messages) Len() int { return len(s) }
func (s messages) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s messages) Less(i, j int) bool { return s[i].Name < s[j].Name }
type services []ProtoService type services []ProtoService
func (s services) Len() int { return len(s) } func (s services) Len() int { return len(s) }
func (s services) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s services) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s services) Less(i, j int) bool { return s[i].Name < s[j].Name } func (s services) Less(i, j int) bool { return s[i].Name < s[j].Name }
type messages []ProtoMessage
func (s messages) Len() int { return len(s) }
func (s messages) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s messages) Less(i, j int) bool { return s[i].Name < s[j].Name }
func (p *Proto) Sort() { func (p *Proto) Sort() {
sort.Sort(messages(p.Messages))
sort.Sort(services(p.Services)) sort.Sort(services(p.Services))
sort.Sort(messages(p.Messages))
}
// ProtoService represents the 'service' type in Protocol Buffer.
// (https://developers.google.com/protocol-buffers/docs/proto3#services)
type ProtoService struct {
Name string
Description string
Methods []ProtoMethod
}
// ProtoMethod represents methods in ProtoService.
type ProtoMethod struct {
Name string
Description string
RequestType string
ResponseType string
} }
// ProtoMessage represents the 'message' type in Protocol Buffer. // ProtoMessage represents the 'message' type in Protocol Buffer.
@ -55,19 +71,3 @@ type ProtoField struct {
ProtoType ProtoType ProtoType ProtoType
UserDefinedProtoType string UserDefinedProtoType string
} }
// ProtoService represents the 'service' type in Protocol Buffer.
// (https://developers.google.com/protocol-buffers/docs/proto3#services)
type ProtoService struct {
Name string
Description string
Methods []ProtoMethod
}
// ProtoMethod represents methods in ProtoService.
type ProtoMethod struct {
Name string
Description string
RequestType string
ResponseType string
}