Skip to content

Commit

Permalink
improve behavior when no arguments are provided
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Goodman <[email protected]>
  • Loading branch information
wagoodman committed Nov 13, 2021
1 parent 5aadcad commit b79ebf3
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 20 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@
A fast changelog generator that sources changes from GitHub PRs and issues, organized by labels.

```bash
# create a changelog from the last GitHib release until the current git HEAD tag/commit
# for the git repo in the current directory
chronicle

# create a changelog with all changes from v0.16.0 until current git HEAD tag/commit
# for the git repo in the current directory
chronicle --since-tag v0.16.0
chronicle --since-tag v0.16.0 --until-tag v0.18.0

# create a changelog between two specific tags for a repo at the given path
chronicle --since-tag v0.16.0 --until-tag v0.18.0 ./path/to/git/repo
```

## Installation
Expand Down
43 changes: 28 additions & 15 deletions cmd/create_github_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,14 @@ func createChangelogFromGithub() (*release.Description, error) {
}
log.Infof("since ref=%q date=%q", lastRelease.Version, lastRelease.Date)

releaseVersion := appConfig.UntilTag
releaseDisplayVersion := releaseVersion
if releaseVersion == "" {
releaseVersion = "(Unreleased)"
releaseDisplayVersion = releaseVersion
// check if the current commit is tagged, then use that
releaseTag, err := git.HeadTagOrCommit(appConfig.CliOptions.RepoPath)
if err != nil {
return nil, fmt.Errorf("problem while attempting to find head tag: %w", err)
}
if releaseTag != "" {
releaseVersion = releaseTag
}
releaseVersion, releaseDisplayVersion, err := getCurrentReleaseInfo(appConfig.UntilTag, appConfig.CliOptions.RepoPath)
if err != nil {
return nil, err
}

log.Infof("until ref=%q", releaseVersion)

changes, err := summer.Changes(lastRelease.Version, appConfig.UntilTag)
changes, err := summer.Changes(lastRelease.Version, releaseVersion)
if err != nil {
return nil, fmt.Errorf("unable to summarize changes: %w", err)
}
Expand All @@ -70,9 +60,32 @@ func createChangelogFromGithub() (*release.Description, error) {
Date: time.Now(),
},
VCSTagURL: summer.TagURL(lastRelease.Version),
VCSChangesURL: summer.ChangesURL(lastRelease.Version, appConfig.UntilTag),
VCSChangesURL: summer.ChangesURL(lastRelease.Version, releaseVersion),
Changes: changes,
SupportedChanges: supportedChanges,
Notice: "", // TODO...
}, nil
}

func getCurrentReleaseInfo(explicitReleaseVersion, repoPath string) (string, string, error) {
if explicitReleaseVersion != "" {
return explicitReleaseVersion, explicitReleaseVersion, nil
}

// check if the current commit is tagged, then use that
releaseTag, err := git.HeadTag(repoPath)
if err != nil {
return "", "", fmt.Errorf("problem while attempting to find head tag: %w", err)
}
if releaseTag != "" {
return releaseTag, releaseTag, nil
}

// fallback to referencing the commit directly
commitRef, err := git.HeadCommit(repoPath)
if err != nil {
return "", "", fmt.Errorf("problem while attempting to find head ref: %w", err)
}

return commitRef, "(Unreleased)", nil
}
36 changes: 36 additions & 0 deletions internal/git/head.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,39 @@ func HeadTagOrCommit(repoPath string) (string, error) {

return ref.Hash().String(), nil
}

func HeadTag(repoPath string) (string, error) {
r, err := git.PlainOpen(repoPath)
if err != nil {
return "", fmt.Errorf("unable to open repo: %w", err)
}
ref, err := r.Head()
if err != nil {
return "", fmt.Errorf("unable fetch head: %w", err)
}
tagRefs, _ := r.Tags()
var tagName string

_ = tagRefs.ForEach(func(t *plumbing.Reference) error {
if t.Hash().String() == ref.Hash().String() {
tagName = t.Name().Short()
return fmt.Errorf("found")
}
return nil
})

// note: if there is no tag, then an empty value is returned
return tagName, nil
}

func HeadCommit(repoPath string) (string, error) {
r, err := git.PlainOpen(repoPath)
if err != nil {
return "", fmt.Errorf("unable to open repo: %w", err)
}
ref, err := r.Head()
if err != nil {
return "", fmt.Errorf("unable fetch head: %w", err)
}
return ref.Hash().String(), nil
}
78 changes: 76 additions & 2 deletions internal/git/head_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,97 @@ import (
"github.com/stretchr/testify/assert"
)

func TestHeadTagOrCommit(t *testing.T) {
tests := []struct {
name string
path string
expects string
expectsLength int
}{
{
name: "head has tag",
path: "test-fixtures/repos/tagged-repo",
expects: "v0.1.0",
},
{
name: "head has no tag",
path: "test-fixtures/repos/commit-in-repo",
// since we don't commit the exact fixture, we don't know what the value will be (but the length
// of a commit string is fixed and is a good proxy here)
expectsLength: 40,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual, err := HeadTagOrCommit(test.path)
assert.NoError(t, err)
if test.expects != "" {
assert.Equal(t, test.expects, actual)
}
if test.expectsLength != 0 {
assert.Len(t, actual, test.expectsLength)
}
})
}
}

func TestHeadTag(t *testing.T) {
tests := []struct {
name string
path string
expects string
}{
{
name: "go case",
name: "head has tag",
path: "test-fixtures/repos/tagged-repo",
expects: "v0.1.0",
},
{
name: "head has no tag",
path: "test-fixtures/repos/commit-in-repo",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual, err := HeadTagOrCommit(test.path)
actual, err := HeadTag(test.path)
assert.NoError(t, err)
assert.Equal(t, test.expects, actual)
})
}
}

func TestHeadCommit(t *testing.T) {
tests := []struct {
name string
path string
expects string
expectsLength int
}{
{
name: "head has tag",
path: "test-fixtures/repos/tagged-repo",
// since we don't commit the exact fixture, we don't know what the value will be (but the length
// of a commit string is fixed and is a good proxy here)
expectsLength: 40,
},
{
name: "head has no tag",
path: "test-fixtures/repos/commit-in-repo",
// since we don't commit the exact fixture, we don't know what the value will be (but the length
// of a commit string is fixed and is a good proxy here)
expectsLength: 40,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual, err := HeadCommit(test.path)
assert.NoError(t, err)
if test.expects != "" {
assert.Equal(t, test.expects, actual)
}
if test.expectsLength != 0 {
assert.Len(t, actual, test.expectsLength)
}
})
}
}
7 changes: 5 additions & 2 deletions internal/git/test-fixtures/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@

.PHONY: all
all: repos/remote-repo repos/tagged-repo
all: repos/remote-repo repos/tagged-repo repos/commit-in-repo

repos/remote-repo:
./create-remote-repo.sh

repos/tagged-repo:
./create-tagged-repo.sh
./create-tagged-repo.sh

repos/commit-in-repo:
./create-commit-in-repo.sh
21 changes: 21 additions & 0 deletions internal/git/test-fixtures/create-commit-in-repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -eux -o pipefail

if [ -d "/path/to/dir" ]
then
echo "fixture already exists!"
exit 0
else
echo "creating fixture..."
fi

git init repos/commit-in-repo

pushd repos/commit-in-repo

git config --local user.email "[email protected]"
git config --local user.name "nope"

trap 'popd' EXIT

git commit -m 'something' --allow-empty

0 comments on commit b79ebf3

Please sign in to comment.