diff --git a/chglog.go b/chglog.go
index f62e63e5..1be130f8 100644
--- a/chglog.go
+++ b/chglog.go
@@ -16,6 +16,7 @@ import (
// Options is an option used to process commits
type Options struct {
Processor Processor
+ NextTag string // Treat unreleased commits as specified tags (EXPERIMENTAL)
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`)
@@ -150,18 +151,30 @@ func (gen *Generator) Generate(w io.Writer, query string) error {
}
func (gen *Generator) readVersions(tags []*Tag, first string) ([]*Version, error) {
+ next := gen.config.Options.NextTag
versions := []*Version{}
for i, tag := range tags {
- var rev string
+ var (
+ isNext = next == tag.Name
+ rev string
+ )
- if i+1 < len(tags) {
- rev = tags[i+1].Name + ".." + tag.Name
- } else {
- if first != "" {
- rev = first + ".." + tag.Name
+ if isNext {
+ if tag.Previous != nil {
+ rev = tag.Previous.Name + "..HEAD"
} else {
- rev = tag.Name
+ rev = "HEAD"
+ }
+ } else {
+ if i+1 < len(tags) {
+ rev = tags[i+1].Name + ".." + tag.Name
+ } else {
+ if first != "" {
+ rev = first + ".." + tag.Name
+ } else {
+ rev = tag.Name
+ }
}
}
@@ -180,12 +193,21 @@ func (gen *Generator) readVersions(tags []*Tag, first string) ([]*Version, error
RevertCommits: revertCommits,
NoteGroups: noteGroups,
})
+
+ // Instead of `getTags()`, assign the date to the tag
+ if isNext {
+ tag.Date = commits[0].Author.Date
+ }
}
return versions, nil
}
func (gen *Generator) readUnreleased(tags []*Tag) (*Unreleased, error) {
+ if gen.config.Options.NextTag != "" {
+ return &Unreleased{}, nil
+ }
+
rev := "HEAD"
if len(tags) > 0 {
@@ -216,6 +238,33 @@ func (gen *Generator) getTags(query string) ([]*Tag, string, error) {
return nil, "", err
}
+ next := gen.config.Options.NextTag
+ if next != "" {
+ for _, tag := range tags {
+ if next == tag.Name {
+ return nil, "", fmt.Errorf("\"%s\" tag already exists", next)
+ }
+ }
+
+ var previous *RelateTag
+ if len(tags) > 0 {
+ previous = &RelateTag{
+ Name: tags[0].Name,
+ Subject: tags[0].Subject,
+ Date: tags[0].Date,
+ }
+ }
+
+ // Assign the date with `readVersions()`
+ tags = append([]*Tag{
+ &Tag{
+ Name: next,
+ Subject: next,
+ Previous: previous,
+ },
+ }, tags...)
+ }
+
if len(tags) == 0 {
return nil, "", errors.New("git-tag does not exist")
}
diff --git a/chglog_test.go b/chglog_test.go
index 6d329801..b233b45d 100644
--- a/chglog_test.go
+++ b/chglog_test.go
@@ -13,8 +13,9 @@ import (
)
var (
- cwd string
- testRepoRoot = ".tmp"
+ cwd string
+ testRepoRoot = ".tmp"
+ internalTimeFormat = "2006-01-02 15:04:05"
)
type commitFunc = func(date, subject, body string)
@@ -48,7 +49,7 @@ func setup(dir string, setupRepo func(commitFunc, tagFunc, gitcmd.Client)) {
if body != "" {
msg += "\n\n" + body
}
- t, _ := time.Parse("2006-01-02 15:04:05", date)
+ t, _ := time.Parse(internalTimeFormat, date)
d := t.Format("Mon Jan 2 15:04:05 2006 +0000")
git.Exec("commit", "--allow-empty", "--date", d, "-m", msg)
}
@@ -298,3 +299,95 @@ Online breaking change message.
[2.0.0-beta.0]: https://github.com/git-chglog/git-chglog/compare/1.1.0...2.0.0-beta.0
[1.1.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...1.1.0`, strings.TrimSpace(buf.String()))
}
+
+func TestGeneratorWithNextTag(t *testing.T) {
+ assert := assert.New(t)
+ testName := "type_scope_subject"
+
+ setup(testName, func(commit commitFunc, tag tagFunc, _ gitcmd.Client) {
+ commit("2018-01-01 00:00:00", "feat(core): version 1.0.0", "")
+ tag("1.0.0")
+
+ commit("2018-02-01 00:00:00", "feat(core): version 2.0.0", "")
+ tag("2.0.0")
+
+ commit("2018-03-01 00:00:00", "feat(core): version 3.0.0", "")
+ })
+
+ gen := NewGenerator(&Config{
+ Bin: "git",
+ WorkingDir: filepath.Join(testRepoRoot, testName),
+ Template: filepath.Join(cwd, "testdata", testName+".md"),
+ Info: &Info{
+ Title: "CHANGELOG Example",
+ RepositoryURL: "https://github.com/git-chglog/git-chglog",
+ },
+ Options: &Options{
+ NextTag: "3.0.0",
+ CommitFilters: map[string][]string{
+ "Type": []string{
+ "feat",
+ },
+ },
+ CommitSortBy: "Scope",
+ CommitGroupBy: "Type",
+ CommitGroupSortBy: "Title",
+ CommitGroupTitleMaps: map[string]string{
+ "feat": "Features",
+ },
+ HeaderPattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$",
+ HeaderPatternMaps: []string{
+ "Type",
+ "Scope",
+ "Subject",
+ },
+ },
+ })
+
+ buf := &bytes.Buffer{}
+ err := gen.Generate(buf, "")
+
+ assert.Nil(err)
+ assert.Equal(`
+## [Unreleased]
+
+
+
+## [3.0.0] - 2018-03-01
+### Features
+- **core:** version 3.0.0
+
+
+
+## [2.0.0] - 2018-02-01
+### Features
+- **core:** version 2.0.0
+
+
+
+## 1.0.0 - 2018-01-01
+### Features
+- **core:** version 1.0.0
+
+
+[Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD
+[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0
+[2.0.0]: https://github.com/git-chglog/git-chglog/compare/1.0.0...2.0.0`, strings.TrimSpace(buf.String()))
+
+ buf = &bytes.Buffer{}
+ err = gen.Generate(buf, "3.0.0")
+
+ assert.Nil(err)
+ assert.Equal(`
+## [Unreleased]
+
+
+
+## [3.0.0] - 2018-03-01
+### Features
+- **core:** version 3.0.0
+
+
+[Unreleased]: https://github.com/git-chglog/git-chglog/compare/3.0.0...HEAD
+[3.0.0]: https://github.com/git-chglog/git-chglog/compare/2.0.0...3.0.0`, strings.TrimSpace(buf.String()))
+}
diff --git a/cmd/git-chglog/config.go b/cmd/git-chglog/config.go
index a81340ee..cef822a2 100644
--- a/cmd/git-chglog/config.go
+++ b/cmd/git-chglog/config.go
@@ -257,6 +257,7 @@ func (config *Config) Convert(ctx *CLIContext) *chglog.Config {
RepositoryURL: info.RepositoryURL,
},
Options: &chglog.Options{
+ NextTag: ctx.NextTag,
CommitFilters: opts.Commits.Filters,
CommitSortBy: opts.Commits.SortBy,
CommitGroupBy: opts.CommitGroups.GroupBy,
diff --git a/cmd/git-chglog/context.go b/cmd/git-chglog/context.go
index c6a8740e..09c5cb59 100644
--- a/cmd/git-chglog/context.go
+++ b/cmd/git-chglog/context.go
@@ -15,6 +15,7 @@ type CLIContext struct {
NoColor bool
NoEmoji bool
Query string
+ NextTag string
}
// InitContext ...
diff --git a/cmd/git-chglog/main.go b/cmd/git-chglog/main.go
index fe435507..fcbbdc2c 100644
--- a/cmd/git-chglog/main.go
+++ b/cmd/git-chglog/main.go
@@ -89,6 +89,11 @@ func main() {
Usage: "output path and filename for the changelogs. If not specified, output to stdout",
},
+ cli.StringFlag{
+ Name: "next-tag",
+ Usage: "treat unreleased commits as specified tags (EXPERIMENTAL)",
+ },
+
// silent
cli.BoolFlag{
Name: "silent",
@@ -155,6 +160,7 @@ func main() {
NoColor: c.Bool("no-color"),
NoEmoji: c.Bool("no-emoji"),
Query: c.Args().First(),
+ NextTag: c.String("next-tag"),
},
fs,
NewConfigLoader(),