Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions internal/config/config_plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ type ContributorsConfig struct {
// Icon is the icon/emoji for the contributors section header (optional).
Icon string `yaml:"icon,omitempty"`

// ShowName controls whether contributor names are displayed alongside their username link.
// Default: true. Set to false to show only the username link (e.g., "[@user](...)").
ShowName *bool `yaml:"show-name,omitempty"`

// ShowNewContributors enables the "New Contributors" section showing first-time contributors.
// Default: true when contributors are enabled.
ShowNewContributors *bool `yaml:"show-new-contributors,omitempty"`
Expand All @@ -382,6 +386,14 @@ type ContributorsConfig struct {
NewContributorsIcon string `yaml:"new-contributors-icon,omitempty"`
}

// GetShowName returns the show-name setting with default true.
func (c *ContributorsConfig) GetShowName() bool {
if c.ShowName == nil {
return true
}
return *c.ShowName
}

// GetShowNewContributors returns the show-new-contributors setting with default true.
func (c *ContributorsConfig) GetShowNewContributors() bool {
if c.ShowNewContributors == nil {
Expand Down
30 changes: 28 additions & 2 deletions internal/plugins/changeloggenerator/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const DefaultNewContributorsIcon = "\U0001F389" // party popper 🎉
// DefaultBreakingChangesIcon is the default icon for the breaking changes section.
const DefaultBreakingChangesIcon = "\u26A0\uFE0F" // warning sign ⚠️

// DefaultContributorFormat is the default Go template for contributor entries (with name).
const DefaultContributorFormat = "- {{.Name}} ([@{{.Username}}](https://{{.Host}}/{{.Username}}))"

// DefaultContributorFormatNoName is the Go template for contributor entries without name.
const DefaultContributorFormatNoName = "- [@{{.Username}}](https://{{.Host}}/{{.Username}})"

// Config holds the internal configuration for the changelog generator plugin.
type Config struct {
// Enabled controls whether the plugin is active.
Expand Down Expand Up @@ -111,6 +117,7 @@ type ContributorsConfig struct {
Enabled bool
Format string
Icon string
ShowName bool
ShowNewContributors bool
NewContributorsFormat string
NewContributorsIcon string
Expand All @@ -132,7 +139,8 @@ func DefaultConfig() *Config {
ExcludePatterns: DefaultExcludePatterns(),
Contributors: &ContributorsConfig{
Enabled: true,
Format: "- [@{{.Username}}](https://{{.Host}}/{{.Username}})",
Format: DefaultContributorFormat,
ShowName: true,
ShowNewContributors: true,
},
}
Expand Down Expand Up @@ -263,15 +271,19 @@ func convertContributorsConfig(cfg *config.ChangelogGeneratorConfig) *Contributo
return defaultContributorsConfig(cfg.UseDefaultIcons)
}

showName := cfg.Contributors.GetShowName()

contrib := &ContributorsConfig{
Enabled: cfg.Contributors.Enabled,
Format: cfg.Contributors.Format,
Icon: cfg.Contributors.Icon,
ShowName: showName,
ShowNewContributors: cfg.Contributors.GetShowNewContributors(),
NewContributorsFormat: cfg.Contributors.NewContributorsFormat,
NewContributorsIcon: cfg.Contributors.NewContributorsIcon,
}

applyDefaultContributorFormat(contrib)
applyDefaultContributorIcons(contrib, cfg.UseDefaultIcons)
return contrib
}
Expand All @@ -280,7 +292,8 @@ func convertContributorsConfig(cfg *config.ChangelogGeneratorConfig) *Contributo
func defaultContributorsConfig(useDefaultIcons bool) *ContributorsConfig {
contrib := &ContributorsConfig{
Enabled: true,
Format: "- {{.Name}} ([@{{.Username}}](https://{{.Host}}/{{.Username}}))",
Format: DefaultContributorFormat,
ShowName: true,
ShowNewContributors: true,
}
if useDefaultIcons {
Expand All @@ -290,6 +303,19 @@ func defaultContributorsConfig(useDefaultIcons bool) *ContributorsConfig {
return contrib
}

// applyDefaultContributorFormat sets the default format when no custom format is specified.
// When ShowName is false and no custom format is set, it uses the no-name format.
func applyDefaultContributorFormat(contrib *ContributorsConfig) {
if contrib.Format != "" {
return
}
if contrib.ShowName {
contrib.Format = DefaultContributorFormat
} else {
contrib.Format = DefaultContributorFormatNoName
}
}

// applyDefaultContributorIcons applies default icons if UseDefaultIcons is enabled.
func applyDefaultContributorIcons(contrib *ContributorsConfig, useDefaultIcons bool) {
if !useDefaultIcons {
Expand Down
6 changes: 5 additions & 1 deletion internal/plugins/changeloggenerator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,11 @@ func (g *Generator) writeContributorEntry(sb *strings.Builder, contrib Contribut
// Get format template
format := g.config.Contributors.Format
if format == "" {
format = "- [@{{.Username}}](https://{{.Host}}/{{.Username}})"
if g.config.Contributors.ShowName {
format = DefaultContributorFormat
} else {
format = DefaultContributorFormatNoName
}
}

// Parse template once (thread-safe)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestWriteContributorEntry_CustomFormat(t *testing.T) {
format: "",
contrib: Contributor{Name: "Dave", Username: "dave", Host: "github.com"},
remote: &RemoteInfo{Host: "github.com", Owner: "test", Repo: "repo"},
expected: "- [@dave](https://github.com/dave)\n",
expected: "- Dave ([@dave](https://github.com/dave))\n",
},
{
name: "Fallback on invalid template",
Expand Down Expand Up @@ -121,6 +121,28 @@ func TestWriteContributorEntry_CustomFormat(t *testing.T) {
}
}

func TestWriteContributorEntry_ShowNameFalse(t *testing.T) {
cfg := DefaultConfig()
cfg.Contributors.Format = "" // no custom format
cfg.Contributors.ShowName = false
g, err := NewGenerator(cfg, NewGitOps())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

contrib := Contributor{Name: "Alice Smith", Username: "alice", Host: "github.com"}
remote := &RemoteInfo{Host: "github.com", Owner: "test", Repo: "repo"}

var sb strings.Builder
g.writeContributorEntry(&sb, contrib, remote)
got := sb.String()

expected := "- [@alice](https://github.com/alice)\n"
if got != expected {
t.Errorf("writeContributorEntry() with ShowName=false = %q, want %q", got, expected)
}
}

func TestWriteContributorEntry_NoHost(t *testing.T) {

cfg := DefaultConfig()
Expand Down