Skip to content

Commit

Permalink
Add ancestors-only & filter flags to new command
Browse files Browse the repository at this point in the history
  • Loading branch information
chelnak committed May 7, 2024
1 parent 8ee99d6 commit 6b60825
Show file tree
Hide file tree
Showing 6 changed files with 750 additions and 275 deletions.
54 changes: 40 additions & 14 deletions cmd/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,61 @@ package cmd
import (
"os"
"path/filepath"
"regexp"

"github.com/chelnak/gh-changelog/internal/configuration"
"github.com/chelnak/gh-changelog/internal/log"
"github.com/chelnak/gh-changelog/internal/writer"
"github.com/chelnak/gh-changelog/pkg/builder"
"github.com/spf13/cobra"
)

var nextVersion string
var fromVersion string
var latestVersion bool
var logger string
var (
nextVersion string
fromVersion string
latestVersion bool
filter string
ancestorsOnly bool
logger string
)

// newCmd is the entry point for creating a new changelog
var newCmd = &cobra.Command{
Use: "new",
Short: "Creates a new changelog from activity in the current repository",
Long: "Creates a new changelog from activity in the current repository.",
RunE: func(command *cobra.Command, args []string) error {
opts := builder.BuilderOptions{
Logger: logger,
NextVersion: nextVersion,
FromVersion: fromVersion,
LatestVersion: latestVersion,
}

builder, err := builder.NewBuilder(opts)
log.SetupLogging(log.GetLoggerType(logger))
builder, err := builder.NewBuilder()
if err != nil {
return err
}

changelog, err := builder.BuildChangelog()
if nextVersion != "" {
builder.NextVersion(nextVersion)
}

if fromVersion != "" {
builder.FromVersion(fromVersion)
}

if latestVersion {
builder.LatestVersion()
}

if filter != "" {
fil, err := regexp.Compile(filter)
if err != nil {
return err
}
builder.Filter(fil)
}

if ancestorsOnly {
builder.AncestorsOnly()
}

changelog, err := builder.Build()
if err != nil {
return err
}
Expand Down Expand Up @@ -70,7 +94,9 @@ func init() {
"Build the changelog starting from the latest tag. Using this flag will result in a changelog with one entry.\nIt can be useful for generating a changelog to be used in release notes.",
)

newCmd.Flags().StringVar(&logger, "logger", "", "The type of logger to use. Valid values are 'spinner' and 'console'. The default is 'spinner'.")
newCmd.Flags().StringVar(&filter, "filter", "", "Filter the results by tag name. This flag supports regular expressions.")
newCmd.Flags().BoolVar(&ancestorsOnly, "ancestors-only", false, "Builds the changelog with tags that are ancestor of the current branch.")
newCmd.Flags().StringVar(&logger, "logger", "spinner", "The type of logger to use. Valid values are 'spinner' and 'console'. The default is 'spinner'.")

newCmd.MarkFlagsMutuallyExclusive("from-version", "latest")
newCmd.Flags().SortFlags = false
Expand Down
62 changes: 49 additions & 13 deletions internal/gitclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,17 @@ import (
"time"
)

type GitClient interface {
GetFirstCommit() (string, error)
GetLastCommit() (string, error)
GetDateOfHash(hash string) (time.Time, error)
}

type execContext = func(name string, arg ...string) *exec.Cmd

type execOptions struct {
args []string
}

type git struct {
type Git struct {
execContext execContext
}

func (g git) exec(opts execOptions) (string, error) {
func (g Git) exec(opts execOptions) (string, error) {
// TODO: Consider not using a private exec function and hardcode
// each call to git in the respective command.
// For now, the lint check is disabled.
Expand All @@ -39,7 +33,7 @@ func (g git) exec(opts execOptions) (string, error) {
return strings.Trim(string(output), "\n"), nil
}

func (g git) GetFirstCommit() (string, error) {
func (g Git) GetFirstCommit() (string, error) {
response, err := g.exec(execOptions{
args: []string{"rev-list", "--max-parents=0", "HEAD", "--reverse"},
})
Expand All @@ -60,13 +54,13 @@ func (g git) GetFirstCommit() (string, error) {
return hashes[0], nil
}

func (g git) GetLastCommit() (string, error) {
func (g Git) GetLastCommit() (string, error) {
return g.exec(execOptions{
args: []string{"log", "-1", "--pretty=format:%H"},
})
}

func (g git) GetDateOfHash(hash string) (time.Time, error) {
func (g Git) GetDateOfHash(hash string) (time.Time, error) {
date, err := g.exec(execOptions{
args: []string{"log", "-1", "--format=%cI", hash, "--date=local"},
})
Expand All @@ -78,8 +72,50 @@ func (g git) GetDateOfHash(hash string) (time.Time, error) {
return time.ParseInLocation(time.RFC3339, date, time.Local)
}

func NewGitClient(cmdContext execContext) GitClient {
return git{
func (g Git) GetCurrentBranch() (string, error) {
return g.exec(execOptions{
args: []string{"rev-parse", "--abbrev-ref", "HEAD"},
})
}

func (g Git) FetchAll() error {
_, err := g.exec(execOptions{
args: []string{"fetch", "--all"},
})

return err
}

func (g Git) Tags() ([]string, error) {
tags, err := g.exec(execOptions{
args: []string{"for-each-ref", "--format='%(refname:short) %(objectname) %(taggerdate:iso-strict)'", "refs/tags"},
})

if err != nil {
return nil, err
}
t := strings.Split(tags, "\n")
return t, nil
}

func (g Git) IsAncestorOf(commit, ancestor string) (bool, error) {
_, err := g.exec(execOptions{
args: []string{"merge-base", "--is-ancestor", commit, ancestor},
})

if err != nil {
if strings.Contains(err.Error(), "exit status 1") {
return false, nil
}

return false, err
}

return true, nil
}

func NewGitClient(cmdContext execContext) Git {
return Git{
execContext: cmdContext,
}
}
22 changes: 11 additions & 11 deletions internal/gitclient/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"time"

"github.com/chelnak/gh-changelog/internal/gitclient"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var testStdoutValue = "test"
Expand Down Expand Up @@ -63,15 +63,15 @@ func TestGetFirstCommitSuccess(t *testing.T) {
gitClient := gitclient.NewGitClient(fakeExecSuccess)
commit, err := gitClient.GetFirstCommit()

assert.NoError(t, err)
assert.Equal(t, "test", commit)
require.NoError(t, err)
require.Equal(t, "test", commit)
}

func TestGetFirstCommitFailure(t *testing.T) {
gitClient := gitclient.NewGitClient(fakeExecFailure)
_, err := gitClient.GetFirstCommit()

assert.Error(t, err)
require.Error(t, err)
}

func TestGetFirstCommitWithOrphansSuccess(t *testing.T) {
Expand All @@ -80,23 +80,23 @@ func TestGetFirstCommitWithOrphansSuccess(t *testing.T) {
gitClient := gitclient.NewGitClient(fakeExecSuccess)
commit, err := gitClient.GetFirstCommit()

assert.NoError(t, err)
assert.Equal(t, "test-hash-0", commit)
require.NoError(t, err)
require.Equal(t, "test-hash-0", commit)
}

func TestGetLastCommitSuccess(t *testing.T) {
gitClient := gitclient.NewGitClient(fakeExecSuccess)
commit, err := gitClient.GetLastCommit()

assert.NoError(t, err)
assert.Equal(t, "test", commit)
require.NoError(t, err)
require.Equal(t, "test", commit)
}

func TestGetLastCommitFailure(t *testing.T) {
gitClient := gitclient.NewGitClient(fakeExecFailure)
_, err := gitClient.GetLastCommit()

assert.Error(t, err)
require.Error(t, err)
}

func TestGetDateOfHashSuccess(t *testing.T) {
Expand All @@ -107,6 +107,6 @@ func TestGetDateOfHashSuccess(t *testing.T) {
date, err := gitClient.GetDateOfHash("test-hash")
expectedDate, _ := time.ParseInLocation(time.RFC3339, mockDate, time.Local)

assert.NoError(t, err)
assert.Equal(t, expectedDate, date)
require.NoError(t, err)
require.Equal(t, expectedDate, date)
}
1 change: 0 additions & 1 deletion internal/show/show_test.go

This file was deleted.

Loading

0 comments on commit 6b60825

Please sign in to comment.