docs: Add godoc

This commit is contained in:
tsuyoshiwada 2018-02-18 01:54:44 +09:00
parent 4dd9b350e6
commit d55318c7a0
9 changed files with 154 additions and 84 deletions

View file

@ -1,3 +1,4 @@
// Package chglog implements main logic for the CHANGELOG generate.
package chglog
import (
@ -11,42 +12,42 @@ import (
gitcmd "github.com/tsuyoshiwada/go-gitcmd"
)
// Options ...
// Options is an option used to process commits
type Options struct {
Processor Processor
CommitFilters map[string][]string
CommitSortBy string
CommitGroupBy string
CommitGroupSortBy string
CommitGroupTitleMaps map[string]string
HeaderPattern string
HeaderPatternMaps []string
IssuePrefix []string
RefActions []string
MergePattern string
MergePatternMaps []string
RevertPattern string
RevertPatternMaps []string
NoteKeywords []string
CommitFilters map[string][]string // Filter by using `Commit` properties and values. Filtering is not done by specifying an empty value
CommitSortBy string // Property name to use for sorting `Commit` (e.g. `Scope`)
CommitGroupBy string // Property name of `Commit` to be grouped into `CommitGroup` (e.g. `Type`)
CommitGroupSortBy string // Property name to use for sorting `CommitGroup` (e.g. `Title`)
CommitGroupTitleMaps map[string]string // Map for `CommitGroup` title conversion
HeaderPattern string // A regular expression to use for parsing the commit header
HeaderPatternMaps []string // A rule for mapping the result of `HeaderPattern` to the property of` Commit`
IssuePrefix []string // Prefix used for issues (e.g. `#`, `gh-`)
RefActions []string // Word list of `Ref.Action`
MergePattern string // A regular expression to use for parsing the merge commit
MergePatternMaps []string // Similar to `HeaderPatternMaps`
RevertPattern string // A regular expression to use for parsing the revert commit
RevertPatternMaps []string // Similar to `HeaderPatternMaps`
NoteKeywords []string // Keyword list to find `Note`. A semicolon is a separator, like `<keyword>:` (e.g. `BREAKING CHANGE`)
}
// Info ...
// Info is metadata related to CHANGELOG
type Info struct {
Title string
RepositoryURL string
Title string // Title of CHANGELOG
RepositoryURL string // URL of git repository
}
// RenderData ...
// RenderData is the data passed to the template
type RenderData struct {
Info *Info
Versions []*Version
}
// Config ...
// Config for generating CHANGELOG
type Config struct {
Bin string
WorkingDir string
Template string
Bin string // Git execution command
WorkingDir string // Working directory
Template string // Path for template file. If a relative path is specified, it depends on the value of `WorkingDir`.
Info *Info
Options *Options
}
@ -78,7 +79,7 @@ func normalizeConfig(config *Config) {
config.Options = opts
}
// Generator ...
// Generator of CHANGELOG
type Generator struct {
client gitcmd.Client
config *Config
@ -88,7 +89,7 @@ type Generator struct {
commitExtractor *commitExtractor
}
// NewGenerator ...
// NewGenerator receives `Config` and create an new `Generator`
func NewGenerator(config *Config) *Generator {
client := gitcmd.New(&gitcmd.Config{
Bin: config.Bin,
@ -110,20 +111,25 @@ func NewGenerator(config *Config) *Generator {
}
}
// Generate ...
// Generate gets the commit based on the specified tag `query` and writes the result to `io.Writer`
//
// tag `query` can be specified with the following rule
// <old>..<new> - Commit contained in `<new>` tags from `<old>` (e.g. `1.0.0..2.0.0`)
// <tagname>.. - Commit from the `<tagname>` to the latest tag (e.g. `1.0.0..`)
// ..<tagname> - Commit from the oldest tag to `<tagname>` (e.g. `..1.0.0`)
// <tagname> - Commit contained in `<tagname>` (e.g. `1.0.0`)
func (gen *Generator) Generate(w io.Writer, query string) error {
back, err := gen.workdir()
if err != nil {
return err
}
defer back()
versions, err := gen.readVersions(query)
if err != nil {
return err
}
back()
return gen.render(w, versions)
}

View file

@ -55,7 +55,7 @@ func TestGeneratorNotFoundCommits(t *testing.T) {
gen := NewGenerator(&Config{
Bin: "git",
WorkingDir: filepath.Join(testRepoRoot, testName),
Template: filepath.Join("testdata", testName+".md"),
Template: filepath.Join(cwd, "testdata", testName+".md"),
Info: &Info{
RepositoryURL: "https://github.com/git-chglog/git-chglog",
},
@ -124,7 +124,7 @@ func TestGeneratorWithTypeScopeSubject(t *testing.T) {
gen := NewGenerator(&Config{
Bin: "git",
WorkingDir: filepath.Join(testRepoRoot, testName),
Template: filepath.Join("testdata", testName+".md"),
Template: filepath.Join(cwd, "testdata", testName+".md"),
Info: &Info{
Title: "CHANGELOG Example",
RepositoryURL: "https://github.com/git-chglog/git-chglog",

View file

@ -25,10 +25,13 @@ func main() {
{{range .Flags}}{{.}}
{{end}}
%s
{{.Name}} todo1
{{.Name}} todo2
{{.Name}} todo3
{{.Name}} todo4
{{.Name}}
{{.Name}} 1.0.0..5.0.0-rc.10
{{.Name}} 1.0.0..
{{.Name}} ..5.0.0-rc.10
{{.Name}} 1.0.0
{{.Name}} --output CHANGELOG.md
{{.Name}} --config dir/path/config.yml
`,
ttl("USAGE:"),
ttl("VERSION:"),

View file

@ -1 +1,8 @@
package chglog
import "errors"
var (
errNotFoundTag = errors.New("could not find the tag")
errFailedQueryParse = errors.New("failed to parse the query")
)

66
example_test.go Normal file
View file

@ -0,0 +1,66 @@
package chglog
import (
"bytes"
"fmt"
"log"
)
func Example() {
gen := NewGenerator(&Config{
Bin: "git",
WorkingDir: ".",
Template: "CHANGELOG.tpl.md",
Info: &Info{
Title: "CHANGELOG",
RepositoryURL: "https://github.com/git-chglog/git-chglog",
},
Options: &Options{
CommitFilters: map[string][]string{
"Type": []string{
"feat",
"fix",
},
},
CommitSortBy: "Scope",
CommitGroupBy: "Type",
CommitGroupSortBy: "Title",
CommitGroupTitleMaps: map[string]string{
"feat": "Features",
"fix": "Bug Fixes",
},
HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$",
HeaderPatternMaps: []string{
"Type",
"Scope",
"Subject",
},
IssuePrefix: []string{
"#",
"gh-",
},
RefActions: []string{},
MergePattern: "^Merge pull request #(\\d+) from (.*)$",
MergePatternMaps: []string{
"Ref",
"Source",
},
RevertPattern: "^Revert \"([\\s\\S]*)\"$",
RevertPatternMaps: []string{
"Header",
},
NoteKeywords: []string{
"BREAKING CHANGE",
},
},
})
buf := &bytes.Buffer{}
err := gen.Generate(buf, "")
if err != nil {
log.Fatalln(err)
}
fmt.Println(buf.String())
}

View file

@ -22,31 +22,31 @@ type Committer struct {
Date time.Time
}
// Merge ...
// Merge info for commit
type Merge struct {
Ref string
Source string
}
// Revert ...
// Revert info for commit
type Revert struct {
Header string
}
// Ref ...
// Ref is abstract data related to commit. (e.g. `Issues`, `Pull Request`)
type Ref struct {
Action string
Ref string
Source string
Action string // (e.g. `Closes`)
Ref string // (e.g. `123`)
Source string // (e.g. `owner/repository`)
}
// Note ...
// Note of commit
type Note struct {
Title string
Body string
Title string // (e.g. `BREAKING CHANGE`)
Body string // `Note` content body
}
// NoteGroup ...
// NoteGroup is a collection of `Note` grouped by titles
type NoteGroup struct {
Title string
Notes []*Note
@ -57,32 +57,34 @@ type Commit struct {
Hash *Hash
Author *Author
Committer *Committer
Merge *Merge
Revert *Revert
Merge *Merge // If it is not a merge commit, `nil` is assigned
Revert *Revert // If it is not a revert commit, `nil` is assigned
Refs []*Ref
Notes []*Note
Mentions []string
Header string
Type string
Scope string
Subject string
Mentions []string // Name of the user included in the commit header or body
Header string // (e.g. `feat(core): Add new feature`)
Type string // (e.g. `feat`)
Scope string // (e.g. `core`)
Subject string // (e.g. `Add new feature`)
Body string
}
// CommitGroup is group of commit
// CommitGroup is a collection of commits grouped according to the `CommitGroupBy` option
type CommitGroup struct {
RawTitle string
Title string
RawTitle string // Raw title before conversion (e.g. `build`)
Title string // Conversion by `CommitGroupTitleMaps` option, or title converted in title case (e.g. `Build`)
Commits []*Commit
}
// RelateTag ...
// RelateTag is sibling tag data of `Tag`.
// If you give `Tag`, the reference hierarchy will be deepened.
// This struct is used to minimize the hierarchy of references
type RelateTag struct {
Name string
Date time.Time
}
// Tag ...
// Tag is data of git-tag
type Tag struct {
Name string
Date time.Time
@ -90,7 +92,7 @@ type Tag struct {
Previous *RelateTag
}
// Version ...
// Version is a tag-separeted datset to be included in CHANGELOG
type Version struct {
Tag *Tag
CommitGroups []*CommitGroup

View file

@ -5,26 +5,19 @@ import (
"strings"
)
// Processor ...
// Processor hooks the internal processing of `Generator`, it is possible to adjust the contents
type Processor interface {
Bootstrap(*Config)
ProcessCommit(*Commit) *Commit
}
// PlainProcessor ...
type PlainProcessor struct{}
// Bootstrap ...
func (*PlainProcessor) Bootstrap(config *Config) {}
// ProcessCommit ...
func (*PlainProcessor) ProcessCommit(commit *Commit) *Commit {
return commit
}
// GitHubProcessor ...
// GitHubProcessor is optimized for CHANGELOG used in GitHub
//
// The following processing is performed
// - Mentions automatic link (@tsuyoshiwada -> [@tsuyoshiwada](https://github.com/tsuyoshiwada))
// - Automatic link to references (#123 -> [#123](https://github.com/owner/repo/issues/123))
type GitHubProcessor struct {
Host string
Host string // Host name used for link destination. Note: You must include the protocol (e.g. "https://github.com")
config *Config
reMention *regexp.Regexp
reIssue *regexp.Regexp

View file

@ -1,16 +1,9 @@
package chglog
import (
"errors"
"strings"
)
// TODO
var (
errNotFound = errors.New("todo: not found")
errParse = errors.New("todo: parse error")
)
type tagSelector struct{}
func newTagSelector() *tagSelector {
@ -36,7 +29,7 @@ func (s *tagSelector) Select(tags []*Tag, query string) ([]*Tag, string, error)
return s.selectRangeTags(tags, tokens[0], tokens[1])
}
return nil, "", errParse
return nil, "", errFailedQueryParse
}
func (s *tagSelector) selectSingleTag(tags []*Tag, token string) ([]*Tag, string, error) {
@ -76,7 +69,7 @@ func (*tagSelector) selectBeforeTags(tags []*Tag, token string) ([]*Tag, string,
}
if len(res) == 0 {
return res, "", errNotFound
return res, "", errNotFoundTag
}
return res, from, nil
@ -101,7 +94,7 @@ func (*tagSelector) selectAfterTags(tags []*Tag, token string) ([]*Tag, string,
}
if len(res) == 0 {
return res, "", errNotFound
return res, "", errNotFoundTag
}
return res, from, nil
@ -133,7 +126,7 @@ func (s *tagSelector) selectRangeTags(tags []*Tag, old string, new string) ([]*T
}
if len(res) == 0 {
return res, "", errNotFound
return res, "", errNotFoundTag
}
return res, from, nil

View file

@ -1,7 +1,7 @@
package chglog
import (
"errors"
"fmt"
"reflect"
"strings"
"time"
@ -51,7 +51,7 @@ func compare(a interface{}, operator string, b interface{}) (bool, error) {
at := reflect.TypeOf(a).String()
bt := reflect.TypeOf(a).String()
if at != bt {
return false, errors.New("todo: not match type")
return false, fmt.Errorf("\"%s\" and \"%s\" can not be compared", at, bt)
}
switch at {