diff --git a/internal/branches/branches.go b/internal/branches/branches.go index ec44ea4..8747228 100644 --- a/internal/branches/branches.go +++ b/internal/branches/branches.go @@ -114,7 +114,13 @@ func (b BranchProvider) formatBranchName(repoNameWithOwner string, branchType st branchName = fmt.Sprintf("%s-%s", branchName, issueContext) } - return strings.TrimSuffix(branchName[:min(63-len([]rune(repoNameWithOwner)), len([]rune(branchName)))], "-") + maxBranchNameLength := b.cfg.MaxLength - len([]rune(repoNameWithOwner)) + if maxBranchNameLength > 0 { + branchNameLength := len([]rune(branchName)) + branchName = branchName[:min(maxBranchNameLength, branchNameLength)] + } + + return strings.TrimSuffix(branchName, "-") } // min returns the smallest of x or y. diff --git a/internal/branches/branches_test.go b/internal/branches/branches_test.go index 9a3a010..50c85fe 100644 --- a/internal/branches/branches_test.go +++ b/internal/branches/branches_test.go @@ -45,6 +45,7 @@ func TestFormatBranchName(t *testing.T) { issueId string issueContext string branchPrefixOverride map[issue_types.IssueType]string + maxLength int } tests := []struct { name string @@ -53,7 +54,14 @@ func TestFormatBranchName(t *testing.T) { }{ { name: "Does format branch name", - args: args{repository: repositoryName, branchType: "feature", issueId: "GH-1", issueContext: "my-title"}, + args: args{ + repository: repositoryName, + branchType: "feature", + issueId: "GH-1", + issueContext: "my-title", + maxLength: 63, + }, + want: "feature/GH-1-my-title", }, { @@ -64,12 +72,19 @@ func TestFormatBranchName(t *testing.T) { issueId: "GH-1", issueContext: "my-title", branchPrefixOverride: map[issue_types.IssueType]string{issue_types.Feature: "feat"}, + maxLength: 63, }, want: "feat/GH-1-my-title", }, { name: "Does format long branch name", - args: args{repository: repositoryName, branchType: "feature", issueId: "GH-1", issueContext: "my-title-is-too-long-and-it-should-be-truncated"}, + args: args{ + repository: repositoryName, + branchType: "feature", + issueId: "GH-1", + issueContext: "my-title-is-too-long-and-it-should-be-truncated", + maxLength: 63, + }, want: "feature/GH-1-my-title-is-too-long-and-it-s", }, { @@ -80,6 +95,7 @@ func TestFormatBranchName(t *testing.T) { issueId: "GH-1", issueContext: "my-title-is-too-long-and-it-should-be-truncated", branchPrefixOverride: map[issue_types.IssueType]string{issue_types.Feature: "feat"}, + maxLength: 63, }, want: "feat/GH-1-my-title-is-too-long-and-it-shou", }, @@ -91,9 +107,32 @@ func TestFormatBranchName(t *testing.T) { issueId: "GH-1", issueContext: "refactor-issue", branchPrefixOverride: map[issue_types.IssueType]string{issue_types.Refactoring: ""}, + maxLength: 63, }, want: "refactoring/GH-1-refactor-issue", }, + { + name: "Does not crop the title if the maxLength is 0", + args: args{ + repository: repositoryName, + branchType: "feature", + issueId: "GH-1", + issueContext: "this-is-a-very-long-title-that-will-not-be-cropped", + maxLength: 0, + }, + want: "feature/GH-1-this-is-a-very-long-title-that-will-not-be-cropped", + }, + { + name: "Does not crop the title if the maxLength is negative", + args: args{ + repository: repositoryName, + branchType: "feature", + issueId: "GH-1", + issueContext: "this-is-a-very-long-title-that-will-not-be-cropped", + maxLength: -1, + }, + want: "feature/GH-1-this-is-a-very-long-title-that-will-not-be-cropped", + }, } for _, tt := range tests { @@ -102,7 +141,8 @@ func TestFormatBranchName(t *testing.T) { b := BranchProvider{ cfg: Configuration{ Branches: config.Branches{ - Prefixes: tt.args.branchPrefixOverride, + Prefixes: tt.args.branchPrefixOverride, + MaxLength: tt.args.maxLength, }, }, } diff --git a/internal/branches/interactive.go b/internal/branches/interactive.go index 02b1061..4c1177b 100644 --- a/internal/branches/interactive.go +++ b/internal/branches/interactive.go @@ -27,8 +27,13 @@ func (b BranchProvider) GetBranchName(issue domain.Issue, repo domain.Repository return "", err } - maxContextLen := calcIssueContextMaxLen(repo.NameWithOwner, branchType, formattedID) - promptIssueContext := fmt.Sprintf("additional description (optional). Truncate to %d chars", maxContextLen) + truncatePrompt := "" + maxContextLen := b.calcIssueContextMaxLen(repo.NameWithOwner, branchType, formattedID) + if maxContextLen > 0 { + truncatePrompt = fmt.Sprintf(" Truncate to %d chars", maxContextLen) + } + + promptIssueContext := "additional description (optional)." + truncatePrompt err = b.UserInteraction.SelectOrInput(promptIssueContext, []string{}, &issueSlug, false) if err != nil { return "", err @@ -62,10 +67,10 @@ func (b BranchProvider) getBugFixBranchType() (branchType string) { return branchType } -func calcIssueContextMaxLen(repository string, branchType string, issueId string) (lenIssueContext int) { +func (b BranchProvider) calcIssueContextMaxLen(repository string, branchType string, issueId string) (lenIssueContext int) { preBranchName := fmt.Sprintf("%s/%s-", branchType, issueId) - if lenIssueContext = 63 - (len([]rune(repository)) + len([]rune(preBranchName))); lenIssueContext < 0 { + if lenIssueContext = b.cfg.MaxLength - (len([]rune(repository)) + len([]rune(preBranchName))); lenIssueContext < 0 { lenIssueContext = 0 } diff --git a/internal/config/branches.go b/internal/config/branches.go index f056248..1b780eb 100644 --- a/internal/config/branches.go +++ b/internal/config/branches.go @@ -3,7 +3,8 @@ package config import "github.com/InditexTech/gh-sherpa/internal/domain/issue_types" type Branches struct { - Prefixes BranchesPrefixes `validate:"validIssueTypeKeys"` + Prefixes BranchesPrefixes `validate:"validIssueTypeKeys"` + MaxLength int `mapstructure:"max_length" validate:"gte=0"` } type BranchesPrefixes map[issue_types.IssueType]string diff --git a/internal/config/default-config.yml b/internal/config/default-config.yml index 539dc6b..a7ce4ea 100644 --- a/internal/config/default-config.yml +++ b/internal/config/default-config.yml @@ -77,3 +77,7 @@ branches: # bugfix: myfix # Example: map `feature` type to a branch prefix `feat/xxxx`: # feature: feat + # Bran max length configuration + # Useful when you want to crop the branch name to a specific length. + # By default it will use 63 due to compatibilities with Kubernetes. + max_length: 63 diff --git a/internal/config/testdata/test-configuration.yml b/internal/config/testdata/test-configuration.yml index a7ae7d8..ee8f9e0 100644 --- a/internal/config/testdata/test-configuration.yml +++ b/internal/config/testdata/test-configuration.yml @@ -25,3 +25,4 @@ branches: prefixes: feature: "feat" bugfix: "fix" + max_length: 63