diff --git a/main.go b/main.go index 1cac8a5..1179c31 100644 --- a/main.go +++ b/main.go @@ -15,13 +15,17 @@ // protodoc generates Protocol Buffer documentation. // // Usage: -// protodoc [flags] +// protodoc [flags] // // Flags: -// -h, --help help for protodoc -// -o, --languages value language options in field descriptions (default [Go,C++,Java,Python]) -// -p, --target-path string file path to save the documentation -// -t, --title string title of documentation +// --directories value comma separated map of target directory to parse options (e.g. 'dirA=message,dirB=message_service') +// -d, --directory string target directory where Protocol Buffer files are. +// -h, --help help for protodoc +// -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 @@ -48,7 +52,8 @@ var ( title string outputPath string - targetDirectories mapString + targetDirectories mapString + messageOnlyFromThisFile string ) 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().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 { var rs string if len(targetDirectories) == 0 { log.Println("opening", targetDirectory) - proto, err := parse.ReadDir(targetDirectory) + proto, err := parse.ReadDir(targetDirectory, "") if err != nil { return err } @@ -121,7 +127,7 @@ func CommandFunc(cmd *cobra.Command, args []string) error { } else { for k, opts := range targetDirectories { log.Println("opening", k) - proto, err := parse.ReadDir(k) + proto, err := parse.ReadDir(k, messageOnlyFromThisFile) if err != nil { return err } diff --git a/parse/markdown_test.go b/parse/markdown_test.go index f54516b..d4d3f07 100644 --- a/parse/markdown_test.go +++ b/parse/markdown_test.go @@ -17,7 +17,7 @@ package parse import "testing" func TestMarkdown(t *testing.T) { - proto, err := ReadDir("testdata") + proto, err := ReadDir("testdata", "") if err != nil { t.Fatal(err) } diff --git a/parse/parse.go b/parse/parse.go index 39046b5..2e4651e 100644 --- a/parse/parse.go +++ b/parse/parse.go @@ -62,33 +62,47 @@ const ( parsingRPC ) -func ReadDir(targetDir string) (*Proto, error) { +func ReadDir(targetDir, messageOnlyFromThisFile string) (*Proto, error) { rm, err := walkDirExt(targetDir, ".proto") if err != nil { return nil, err } - var lines []string - for _, fpath := range rm { - f, err := os.OpenFile(fpath, os.O_RDONLY, 0444) - if err != nil { - return nil, err - } - - ls, err := readLines(f) - if err != nil { - f.Close() - return nil, err - } - lines = append(lines, ls...) - - f.Close() + pr := &Proto{ + Services: []ProtoService{}, + Messages: []ProtoMessage{}, } + 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 ( rp = Proto{ - Messages: []ProtoMessage{}, Services: []ProtoService{}, + Messages: []ProtoMessage{}, } mode = reading diff --git a/parse/parse_test.go b/parse/parse_test.go index e17ef0c..c468f20 100644 --- a/parse/parse_test.go +++ b/parse/parse_test.go @@ -17,7 +17,7 @@ package parse import "testing" func TestReadDir(t *testing.T) { - proto, err := ReadDir("testdata") + proto, err := ReadDir("testdata", "") if err != nil { t.Fatal(err) } diff --git a/parse/proto.go b/parse/proto.go index 3cd3c25..87d21e6 100644 --- a/parse/proto.go +++ b/parse/proto.go @@ -18,25 +18,41 @@ import "sort" // Proto represents sets of 'ProtoMessage' and 'ProtoService'. type Proto struct { - Messages []ProtoMessage 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 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) 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() { - sort.Sort(messages(p.Messages)) 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. @@ -55,19 +71,3 @@ type ProtoField struct { ProtoType ProtoType 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 -}