diff --git a/cmd/goreadme/main.go b/cmd/goreadme/main.go index 9451af7..0af1800 100644 --- a/cmd/goreadme/main.go +++ b/cmd/goreadme/main.go @@ -42,6 +42,7 @@ func init() { flag.StringVar(&cfg.Title, "title", "", "Override readme title. Default is package name.") flag.BoolVar(&cfg.RecursiveSubPackages, "recursive", false, "Load docs recursively.") flag.BoolVar(&cfg.Functions, "functions", false, "Write functions section.") + flag.BoolVar(&cfg.Types, "types", false, "Write types section.") flag.BoolVar(&cfg.SkipExamples, "skip-examples", false, "Skip the examples section.") flag.BoolVar(&cfg.SkipSubPackages, "skip-sub-packages", false, "Skip the sub packages section.") flag.BoolVar(&cfg.Badges.TravisCI, "badge-travisci", false, "Show TravisCI badge.") diff --git a/goreadme.go b/goreadme.go index b3ce52c..1ec482e 100644 --- a/goreadme.go +++ b/goreadme.go @@ -131,6 +131,8 @@ type Config struct { ImportPath string `json:"import_path"` // Functions will make functions documentation to be added to the README. Functions bool `json:"functions"` + // Types will make types documentation to be added to the README. + Types bool `json:"types"` // SkipExamples will omit the examples section from the README. SkipExamples bool `json:"skip_examples"` // SkipSubPackages will omit the sub packages section from the README. @@ -208,6 +210,22 @@ func (r *GoReadme) get(ctx context.Context, name string) (*pkg, error) { } } + // If types were not requested to be added to the readme, add their + // examples to the main readme. + if !r.config.Types { + for _, f := range p.Types { + for _, e := range f.Examples { + if e.Name == "" { + e.Name = f.Name + } + if e.Doc == "" { + e.Doc = f.Doc + } + p.Examples = append(p.Examples, e) + } + } + } + if p.IsCmd { // TODO: make this better p.Name = filepath.Base(name) diff --git a/internal/template/template.go b/internal/template/template.go index 9b28ef0..815ab93 100644 --- a/internal/template/template.go +++ b/internal/template/template.go @@ -3,6 +3,7 @@ package template import ( "bytes" "io" + "regexp" "strings" "text/template" @@ -29,6 +30,11 @@ var base = template.New("base").Funcs( "inlineCode": func(s string) string { return "`" + s + "`" }, + "inlineCodeEllipsis": func(s string) string { + r := regexp.MustCompile(`\{[^[]*\}`) + s = r.ReplaceAllString(s, "{ ... }") + return "`" + s + "`" + }, "importPath": func(p *doc.Package) string { return p.ImportPath }, @@ -73,6 +79,10 @@ var main = template.Must(base.Parse(`# {{.Package.Name}} {{ template "functions" .Package }} {{ end }} +{{ if .Config.Types }} +{{ template "types" .Package }} +{{ end }} + {{ if (not .Config.SkipSubPackages) }} {{ template "subpackages" . }} {{ end }} @@ -107,6 +117,27 @@ var functions = template.Must(base.Parse(` {{ end }} `)) +var types = template.Must(base.Parse(` +{{ define "types" }} +{{ if .Types }} + +## Types + +{{ range .Types }} + +### type [{{ .Name }}]({{ urlOrName (index $.Files .Pos.File) }}#L{{ .Pos.Line }}) + +{{ inlineCodeEllipsis .Decl.Text }} + +{{ doc .Doc }} + +{{ template "examplesNoHeading" .Examples }} +{{ end }} + +{{ end }} +{{ end }} +`)) + var examples = template.Must(base.Parse(` {{ define "examples" }} {{ if . }} diff --git a/testdata/pkg1/README.md b/testdata/pkg1/README.md index 0692eb6..b8df20c 100644 --- a/testdata/pkg1/README.md +++ b/testdata/pkg1/README.md @@ -134,3 +134,14 @@ Func() ``` hello ``` + +### Assignment + +ExampleExampleType tests using the type ExampleType + +```golang + +example := new(ExampleType) +example.val = 1 + +``` diff --git a/testdata/pkg1/pkg1.go b/testdata/pkg1/pkg1.go index 5b01e92..ad64b85 100644 --- a/testdata/pkg1/pkg1.go +++ b/testdata/pkg1/pkg1.go @@ -67,3 +67,8 @@ import "fmt" func Func() { fmt.Println("hello") } + +type ExampleType struct { + val int + ExampleInterface interface{} +} diff --git a/testdata/pkg1/pkg1_test.go b/testdata/pkg1/pkg1_test.go index 04087f6..e8fdd9b 100644 --- a/testdata/pkg1/pkg1_test.go +++ b/testdata/pkg1/pkg1_test.go @@ -24,3 +24,9 @@ func ExampleFunc_withName() { Func() // Output: hello } + +// ExampleExampleType tests using the type ExampleType +func ExampleExampleType_assignment() { + example := new(ExampleType) + example.val = 1 +} diff --git a/testdata/pkg8_types/README.md b/testdata/pkg8_types/README.md new file mode 100644 index 0000000..1342719 --- /dev/null +++ b/testdata/pkg8_types/README.md @@ -0,0 +1,22 @@ +# pkg1 + +Package pkg1 is a testing package. + +## Types + +### type [ExampleType](/pkg.go#L5) + +`type ExampleType struct { ... }` + +ExampleType is a type + +### Assignment + +ExampleExampleType tests using the type ExampleType + +```golang + +example := new(ExampleType) +example.val = 1 + +``` diff --git a/testdata/pkg8_types/go.mod b/testdata/pkg8_types/go.mod new file mode 100644 index 0000000..7722379 --- /dev/null +++ b/testdata/pkg8_types/go.mod @@ -0,0 +1,3 @@ +module pkg6 + +go 1.15 diff --git a/testdata/pkg8_types/goreadme.json b/testdata/pkg8_types/goreadme.json new file mode 100644 index 0000000..660f458 --- /dev/null +++ b/testdata/pkg8_types/goreadme.json @@ -0,0 +1,3 @@ +{ + "types": true +} \ No newline at end of file diff --git a/testdata/pkg8_types/pkg.go b/testdata/pkg8_types/pkg.go new file mode 100644 index 0000000..fd79164 --- /dev/null +++ b/testdata/pkg8_types/pkg.go @@ -0,0 +1,8 @@ +// Package pkg1 is a testing package. +package pkg1 + +// ExampleType is a type +type ExampleType struct { + val int + ExampleInterface interface{} +} diff --git a/testdata/pkg8_types/pkg_test.go b/testdata/pkg8_types/pkg_test.go new file mode 100644 index 0000000..11e216b --- /dev/null +++ b/testdata/pkg8_types/pkg_test.go @@ -0,0 +1,7 @@ +package pkg1 + +// ExampleExampleType tests using the type ExampleType +func ExampleExampleType_assignment() { + example := new(ExampleType) + example.val = 1 +}