github.com/rivy-go/git-changelog@v0.0.0-20240424224517-b86e6ab57773/cmd/git-changelog/config.go (about)

     1  package main
     2  
     3  import (
     4  	"path/filepath"
     5  	"strings"
     6  
     7  	"github.com/imdario/mergo"
     8  
     9  	changelog "github.com/rivy-go/git-changelog/internal/changelog"
    10  )
    11  
    12  // Info ...
    13  type Info struct {
    14  	Title         string `yaml:"title"`
    15  	RepositoryURL string `yaml:"repository_url"`
    16  }
    17  
    18  // CommitOptions ...
    19  type CommitOptions struct {
    20  	Filters  map[string][]string `yaml:"filters"`
    21  	SortBy   string              `yaml:"sort_by"`
    22  	TypeMaps map[string]string   `yaml:"type_maps"`
    23  }
    24  
    25  // CommitGroupOptions ...
    26  type CommitGroupOptions struct {
    27  	GroupBy   string            `yaml:"group_by"`
    28  	SortBy    string            `yaml:"sort_by"`
    29  	TitleMaps map[string]string `yaml:"title_maps"`
    30  }
    31  
    32  // PatternOptions ...
    33  type PatternOptions struct {
    34  	Pattern     string   `yaml:"pattern"`
    35  	PatternMaps []string `yaml:"pattern_maps"`
    36  }
    37  
    38  // IssueOptions ...
    39  type IssueOptions struct {
    40  	Prefix []string `yaml:"prefix"`
    41  }
    42  
    43  // RefOptions ...
    44  type RefOptions struct {
    45  	Actions []string `yaml:"actions"`
    46  }
    47  
    48  // NoteOptions ...
    49  type NoteOptions struct {
    50  	Keywords []string `yaml:"keywords"`
    51  }
    52  
    53  // TagOptions ...
    54  type TagOptions struct {
    55  	Pattern string `yaml:"pattern"`
    56  }
    57  
    58  // Options ...
    59  type Options struct {
    60  	Commits      CommitOptions      `yaml:"commits"`
    61  	CommitGroups CommitGroupOptions `yaml:"commit_groups"`
    62  	Header       PatternOptions     `yaml:"header"`
    63  	Tag          TagOptions         `yaml:"tag"`
    64  	Issues       IssueOptions       `yaml:"issues"`
    65  	Refs         RefOptions         `yaml:"refs"`
    66  	Merges       PatternOptions     `yaml:"merges"`
    67  	Reverts      PatternOptions     `yaml:"reverts"`
    68  	Notes        NoteOptions        `yaml:"notes"`
    69  }
    70  
    71  // Config ...
    72  type Config struct {
    73  	Bin      string  `yaml:"bin"`
    74  	Template string  `yaml:"template"`
    75  	Style    string  `yaml:"style"`
    76  	Info     Info    `yaml:"info"`
    77  	Options  Options `yaml:"options"`
    78  }
    79  
    80  // Normalize ...
    81  func (config *Config) Normalize(ctx *CLIContext) error {
    82  	err := mergo.Merge(config, &Config{
    83  		Bin:      "git",
    84  		Template: "CHANGELOG.tpl.md",
    85  		Info: Info{
    86  			Title: "CHANGELOG",
    87  		},
    88  		Options: Options{
    89  			Commits: CommitOptions{
    90  				SortBy: "Scope",
    91  			},
    92  			CommitGroups: CommitGroupOptions{
    93  				GroupBy: "Type",
    94  				SortBy:  "Title",
    95  			},
    96  		},
    97  	})
    98  
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	config.Info.RepositoryURL = strings.TrimRight(config.Info.RepositoryURL, "/")
   104  
   105  	if !filepath.IsAbs(config.Template) {
   106  		config.Template = filepath.Join(filepath.Dir(ctx.ConfigPath), config.Template)
   107  	}
   108  
   109  	config.normalizeStyle()
   110  
   111  	return nil
   112  }
   113  
   114  // Normalize style
   115  func (config *Config) normalizeStyle() {
   116  	switch config.Style {
   117  	case "github":
   118  		config.normalizeStyleOfGitHub()
   119  	case "gitlab":
   120  		config.normalizeStyleOfGitLab()
   121  	case "bitbucket":
   122  		config.normalizeStyleOfBitbucket()
   123  	}
   124  }
   125  
   126  // For GitHub
   127  func (config *Config) normalizeStyleOfGitHub() {
   128  	opts := config.Options
   129  
   130  	if len(opts.Issues.Prefix) == 0 {
   131  		opts.Issues.Prefix = []string{
   132  			"#",
   133  			"gh-",
   134  		}
   135  	}
   136  
   137  	if len(opts.Refs.Actions) == 0 {
   138  		opts.Refs.Actions = []string{
   139  			"close",
   140  			"closes",
   141  			"closed",
   142  			"fix",
   143  			"fixes",
   144  			"fixed",
   145  			"resolve",
   146  			"resolves",
   147  			"resolved",
   148  		}
   149  	}
   150  
   151  	if opts.Merges.Pattern == "" && len(opts.Merges.PatternMaps) == 0 {
   152  		opts.Merges.Pattern = "^Merge pull request #(\\d+) from (.*)$"
   153  		opts.Merges.PatternMaps = []string{
   154  			"Ref",
   155  			"Source",
   156  		}
   157  	}
   158  
   159  	config.Options = opts
   160  }
   161  
   162  // For GitLab
   163  func (config *Config) normalizeStyleOfGitLab() {
   164  	opts := config.Options
   165  
   166  	if len(opts.Issues.Prefix) == 0 {
   167  		opts.Issues.Prefix = []string{
   168  			"#",
   169  		}
   170  	}
   171  
   172  	if len(opts.Refs.Actions) == 0 {
   173  		opts.Refs.Actions = []string{
   174  			"close",
   175  			"closes",
   176  			"closed",
   177  			"closing",
   178  			"fix",
   179  			"fixes",
   180  			"fixed",
   181  			"fixing",
   182  			"resolve",
   183  			"resolves",
   184  			"resolved",
   185  			"resolving",
   186  		}
   187  	}
   188  
   189  	if opts.Merges.Pattern == "" && len(opts.Merges.PatternMaps) == 0 {
   190  		opts.Merges.Pattern = "^Merge branch '.*' into '(.*)'$"
   191  		opts.Merges.PatternMaps = []string{
   192  			"Source",
   193  		}
   194  	}
   195  
   196  	config.Options = opts
   197  }
   198  
   199  // For Bitbucket
   200  func (config *Config) normalizeStyleOfBitbucket() {
   201  	opts := config.Options
   202  
   203  	if len(opts.Issues.Prefix) == 0 {
   204  		opts.Issues.Prefix = []string{
   205  			"#",
   206  		}
   207  	}
   208  
   209  	if len(opts.Refs.Actions) == 0 {
   210  		opts.Refs.Actions = []string{
   211  			"close",
   212  			"closes",
   213  			"closed",
   214  			"closing",
   215  			"fix",
   216  			"fixed",
   217  			"fixes",
   218  			"fixing",
   219  			"resolve",
   220  			"resolves",
   221  			"resolved",
   222  			"resolving",
   223  			"eopen",
   224  			"reopens",
   225  			"reopening",
   226  			"hold",
   227  			"holds",
   228  			"holding",
   229  			"wontfix",
   230  			"invalidate",
   231  			"invalidates",
   232  			"invalidated",
   233  			"invalidating",
   234  			"addresses",
   235  			"re",
   236  			"references",
   237  			"ref",
   238  			"refs",
   239  			"see",
   240  		}
   241  	}
   242  
   243  	if opts.Merges.Pattern == "" && len(opts.Merges.PatternMaps) == 0 {
   244  		opts.Merges.Pattern = "^Merged in (.*) \\(pull request #(\\d+)\\)$"
   245  		opts.Merges.PatternMaps = []string{
   246  			"Source",
   247  			"Ref",
   248  		}
   249  	}
   250  
   251  	config.Options = opts
   252  }
   253  
   254  // Convert ...
   255  func (config *Config) Convert(ctx *CLIContext) *changelog.Config {
   256  	info := config.Info
   257  	opts := config.Options
   258  
   259  	return &changelog.Config{
   260  		Bin:        config.Bin,
   261  		WorkingDir: ctx.WorkingDir,
   262  		Style:      config.Style,
   263  		Template:   config.Template,
   264  		Info: &changelog.Info{
   265  			Title:         info.Title,
   266  			RepositoryURL: info.RepositoryURL,
   267  		},
   268  		Options: &changelog.Options{
   269  			ShowUnreleased:       ctx.Unreleased,
   270  			NextTag:              ctx.NextTag,
   271  			NextTagNow:           ctx.NextTagNow,
   272  			TagFilterPattern:     (map[bool]string{true: ctx.TagFilterPattern, false: opts.Tag.Pattern})[ctx.TagFilterPattern != ""],
   273  			NoCaseSensitive:      ctx.NoCaseSensitive,
   274  			CommitFilters:        opts.Commits.Filters,
   275  			CommitSortBy:         opts.Commits.SortBy,
   276  			CommitTypeMaps:       opts.Commits.TypeMaps,
   277  			CommitGroupBy:        opts.CommitGroups.GroupBy,
   278  			CommitGroupSortBy:    opts.CommitGroups.SortBy,
   279  			CommitGroupTitleMaps: opts.CommitGroups.TitleMaps,
   280  			HeaderPattern:        opts.Header.Pattern,
   281  			HeaderPatternMaps:    opts.Header.PatternMaps,
   282  			IssuePrefix:          opts.Issues.Prefix,
   283  			RefActions:           opts.Refs.Actions,
   284  			MergePattern:         opts.Merges.Pattern,
   285  			MergePatternMaps:     opts.Merges.PatternMaps,
   286  			RevertPattern:        opts.Reverts.Pattern,
   287  			RevertPatternMaps:    opts.Reverts.PatternMaps,
   288  			NoteKeywords:         opts.Notes.Keywords,
   289  		},
   290  	}
   291  }