Skip to content

Commit 85fc6af

Browse files
authored
feat(parameters): refactor parameters and validators (#62)
* <no value>: <no value> * feat(parameters): add parameters and validators * feat(template): update default template
1 parent 30512db commit 85fc6af

File tree

26 files changed

+995
-285
lines changed

26 files changed

+995
-285
lines changed

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ go 1.22
44

55
require (
66
github.com/charmbracelet/huh v0.3.0
7+
github.com/mitchellh/mapstructure v1.5.0
78
github.com/onsi/ginkgo/v2 v2.17.1
89
github.com/onsi/gomega v1.33.0
910
github.com/shipengqi/component-base v0.2.9
1011
github.com/shipengqi/golib v0.2.12
1112
github.com/spf13/cobra v1.8.0
1213
github.com/spf13/pflag v1.0.5
14+
github.com/stretchr/testify v1.9.0
1315
gopkg.in/yaml.v3 v3.0.1
1416
)
1517

@@ -22,6 +24,7 @@ require (
2224
github.com/charmbracelet/bubbletea v0.25.0 // indirect
2325
github.com/charmbracelet/lipgloss v0.10.0 // indirect
2426
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
27+
github.com/davecgh/go-spew v1.1.1 // indirect
2528
github.com/fatih/color v1.16.0 // indirect
2629
github.com/go-logr/logr v1.4.1 // indirect
2730
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
@@ -40,6 +43,7 @@ require (
4043
github.com/muesli/cancelreader v0.2.2 // indirect
4144
github.com/muesli/reflow v0.3.0 // indirect
4245
github.com/muesli/termenv v0.15.2 // indirect
46+
github.com/pmezard/go-difflib v1.0.0 // indirect
4347
github.com/rivo/uniseg v0.4.7 // indirect
4448
golang.org/x/net v0.23.0 // indirect
4549
golang.org/x/sync v0.6.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+Ei
5757
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
5858
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
5959
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
60+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
61+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
6062
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
6163
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
6264
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=

internal/config/config.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ import (
1515
"gopkg.in/yaml.v3"
1616

1717
"github.com/shipengqi/commitizen/internal/options"
18-
"github.com/shipengqi/commitizen/internal/render"
18+
"github.com/shipengqi/commitizen/internal/templates"
1919
)
2020

2121
const (
22-
RCFilename = ".git-czrc"
22+
RCFilename = ".czrc"
2323
ReservedDefaultName = "default"
2424
FieldKeyTemplateSelect = "template-select"
2525
)
2626

2727
type Config struct {
28-
defaultTmpl *render.Template
29-
more []*render.Template
28+
defaultTmpl *templates.Template
29+
more []*templates.Template
3030
}
3131

3232
func New() *Config {
@@ -81,7 +81,7 @@ func (c *Config) initialize() error {
8181
return nil
8282
}
8383

84-
func (c *Config) Run(opts *options.Options) (*render.Template, error) {
84+
func (c *Config) Run(opts *options.Options) (*templates.Template, error) {
8585
err := c.initialize()
8686
if err != nil {
8787
return nil, err
@@ -124,7 +124,7 @@ func (c *Config) Run(opts *options.Options) (*render.Template, error) {
124124

125125
func (c *Config) createTemplatesSelect(label string) *huh.Form {
126126
var choices []string
127-
var all []*render.Template
127+
var all []*templates.Template
128128
all = append(all, c.more...)
129129
all = append(all, c.defaultTmpl)
130130
// list custom templates and default templates
@@ -141,7 +141,7 @@ func (c *Config) createTemplatesSelect(label string) *huh.Form {
141141
)
142142
}
143143

144-
func LoadTemplates(file string) ([]*render.Template, error) {
144+
func LoadTemplates(file string) ([]*templates.Template, error) {
145145
if len(file) == 0 {
146146
return nil, nil
147147
}
@@ -153,24 +153,28 @@ func LoadTemplates(file string) ([]*render.Template, error) {
153153
return load(fd)
154154
}
155155

156-
func Load(data []byte) ([]*render.Template, error) {
156+
func Load(data []byte) ([]*templates.Template, error) {
157157
return load(bytes.NewReader(data))
158158
}
159159

160-
func load(reader io.Reader) ([]*render.Template, error) {
161-
var templates []*render.Template
160+
func load(reader io.Reader) ([]*templates.Template, error) {
161+
var tmpls []*templates.Template
162162
d := yaml.NewDecoder(reader)
163163
for {
164-
tmpl := new(render.Template)
164+
tmpl := new(templates.Template)
165165
err := d.Decode(tmpl)
166166
if err != nil {
167167
if errors.Is(err, io.EOF) {
168168
break
169169
}
170170
return nil, err
171171
}
172-
templates = append(templates, tmpl)
172+
err = tmpl.Initialize()
173+
if err != nil {
174+
return nil, err
175+
}
176+
tmpls = append(tmpls, tmpl)
173177
}
174178

175-
return templates, nil
179+
return tmpls, nil
176180
}

internal/config/default.go

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,48 @@
11
package config
22

33
const DefaultCommitTemplate = `---
4+
version: v2
45
name: default
56
default: true
67
items:
78
- name: type
8-
desc: "Select the type of change that you're committing:"
9-
type: select
9+
group: page1
10+
label: "Select the type of change that you're committing:"
11+
type: list
1012
options:
11-
- name: feat
12-
desc: "A new feature"
13-
- name: fix
14-
desc: "A bug fix"
15-
- name: docs
16-
desc: "Documentation only changes"
17-
- name: test
18-
desc: "Adding missing or correcting existing tests"
19-
- name: chore
20-
desc: "Changes to the build process or auxiliary tools and\n libraries such as documentation generation"
21-
- name: style
22-
desc: "Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)"
23-
- name: refactor
24-
desc: "A code change that neither fixes a bug nor adds a feature"
25-
- name: perf
26-
desc: "A code change that improves performance"
27-
- name: revert
28-
desc: "Reverts a previous commit"
13+
- value: feat
14+
key: "feat: A new feature"
15+
- value: fix
16+
key: "fix: A bug fix"
17+
- value: docs
18+
key: "docs: Documentation only changes"
19+
- value: test
20+
key: "test: Adding missing or correcting existing tests"
21+
- value: chore
22+
key: "chore: Changes to the build process or auxiliary tools and\n libraries such as documentation generation"
23+
- value: style
24+
key: "style: Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)"
25+
- value: refactor
26+
key: "refactor: A code change that neither fixes a bug nor adds a feature"
27+
- value: perf
28+
key: "perf: A code change that improves performance"
29+
- value: revert
30+
key: "revert: Reverts a previous commit"
2931
- name: scope
30-
desc: "Scope. What is the scope of this change? (class or file name):"
31-
type: input
32+
group: page2
33+
label: "Scope. What is the scope of this change? (class or file name):"
34+
type: string
3235
- name: subject
33-
desc: "Subject. Write a short and imperative summary of the code change (lower case and no period):"
34-
type: input
36+
group: page2
37+
label: "Subject. Write a short and imperative summary of the code change (lower case and no period):"
38+
type: string
3539
required: true
3640
- name: body
37-
desc: "Body. Provide additional contextual information about the code changes:"
38-
type: textarea
41+
group: page3
42+
label: "Body. Provide additional contextual information about the code changes:"
43+
type: text
3944
- name: footer
40-
desc: "Footer. Information about Breaking Changes and reference issues that this commit closes:"
41-
type: textarea
45+
group: page3
46+
label: "Footer. Information about Breaking Changes and reference issues that this commit closes:"
47+
type: text
4248
format: "{{.type}}{{with .scope}}({{.}}){{end}}: {{.subject}}{{with .body}}\n\n{{.}}{{end}}{{with .footer}}\n\n{{.}}{{end}}"`

internal/errors/errors.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package errors
2+
3+
import "errors"
4+
5+
var (
6+
ErrType = errors.New("type error")
7+
)

internal/errors/required.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package errors
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
type RequiredErr struct {
8+
field string
9+
}
10+
11+
func (e RequiredErr) Error() string {
12+
return fmt.Sprintf("%s is required", e.field)
13+
}
14+
15+
func NewRequiredErr(field string) error {
16+
return RequiredErr{field: field}
17+
}

internal/parameter/boolean/bool.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package boolean
2+
3+
import (
4+
"github.com/charmbracelet/huh"
5+
6+
"github.com/shipengqi/commitizen/internal/parameter"
7+
)
8+
9+
type Param struct {
10+
parameter.Parameter `mapstructure:",squash"`
11+
12+
DefaultValue bool `yaml:"default_value" json:"default_value" mapstructure:"default_value"`
13+
}
14+
15+
func (p Param) Render() huh.Field {
16+
param := huh.NewConfirm().Key(p.Name).
17+
Title(p.Label)
18+
19+
if len(p.Description) > 0 {
20+
param.Description(p.Description)
21+
}
22+
23+
param.Value(&p.DefaultValue)
24+
25+
return param
26+
}

internal/parameter/integer/int.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package integer
2+
3+
import (
4+
"github.com/charmbracelet/huh"
5+
6+
"github.com/shipengqi/commitizen/internal/parameter"
7+
"github.com/shipengqi/commitizen/internal/parameter/validators"
8+
)
9+
10+
type Param struct {
11+
parameter.Parameter `mapstructure:",squash"`
12+
13+
DefaultValue string `yaml:"default_value" json:"default_value" mapstructure:"default_value"`
14+
Required bool `yaml:"required" json:"required" mapstructure:"required"`
15+
Min *int `yaml:"min" json:"min" mapstructure:"min"`
16+
Max *int `yaml:"max" json:"max" mapstructure:"max"`
17+
}
18+
19+
func (p Param) Render() huh.Field {
20+
param := huh.NewInput().Key(p.Name).
21+
Title(p.Label)
22+
23+
if len(p.Description) > 0 {
24+
param.Description(p.Description)
25+
}
26+
27+
param.Value(&p.DefaultValue)
28+
29+
var group []validators.Validator
30+
if p.Required {
31+
group = append(group, validators.Required(p.Name, true))
32+
}
33+
if p.Min != nil {
34+
group = append(group, validators.Min(*p.Min))
35+
}
36+
if p.Max != nil {
37+
group = append(group, validators.Max(*p.Max))
38+
}
39+
40+
if len(group) > 0 {
41+
param.Validate(validators.Group(group...))
42+
}
43+
return param
44+
}

internal/parameter/list/list.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package list
2+
3+
import (
4+
"github.com/charmbracelet/huh"
5+
6+
"github.com/shipengqi/commitizen/internal/errors"
7+
"github.com/shipengqi/commitizen/internal/parameter"
8+
"github.com/shipengqi/commitizen/internal/parameter/validators"
9+
)
10+
11+
type Param struct {
12+
parameter.Parameter `mapstructure:",squash"`
13+
14+
Options []huh.Option[string] `yaml:"options" json:"options" mapstructure:"options"`
15+
DefaultValue string `yaml:"default_value" json:"default_value" mapstructure:"default_value"`
16+
Required bool `yaml:"required" json:"required" mapstructure:"required"`
17+
}
18+
19+
func (p Param) Validate() []error {
20+
errs := p.Parameter.Validate()
21+
if len(p.Options) < 1 {
22+
errs = append(errs, errors.NewRequiredErr("parameter.options"))
23+
}
24+
return errs
25+
}
26+
27+
func (p Param) Render() huh.Field {
28+
param := huh.NewSelect[string]().Key(p.Name).
29+
Options(p.Options...).
30+
Title(p.Label)
31+
if len(p.Description) > 0 {
32+
param.Description(p.Description)
33+
}
34+
35+
param.Value(&p.DefaultValue)
36+
37+
var group []validators.Validator
38+
if p.Required {
39+
group = append(group, validators.Required(p.Name, false))
40+
}
41+
42+
if len(group) > 0 {
43+
param.Validate(validators.Group(group...))
44+
}
45+
return param
46+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package multilist
2+
3+
import (
4+
"github.com/charmbracelet/huh"
5+
6+
"github.com/shipengqi/commitizen/internal/errors"
7+
"github.com/shipengqi/commitizen/internal/parameter"
8+
"github.com/shipengqi/commitizen/internal/parameter/validators"
9+
)
10+
11+
type Param struct {
12+
parameter.Parameter `mapstructure:",squash"`
13+
14+
Options []huh.Option[string] `yaml:"options" json:"options" mapstructure:"options"`
15+
DefaultValue []string `yaml:"default_value" json:"default_value" mapstructure:"default_value"`
16+
Required bool `yaml:"required" json:"required" mapstructure:"required"`
17+
}
18+
19+
func (p Param) Validate() []error {
20+
errs := p.Parameter.Validate()
21+
if len(p.Options) < 1 {
22+
errs = append(errs, errors.NewRequiredErr("parameter.options"))
23+
}
24+
return errs
25+
}
26+
27+
func (p Param) Render() huh.Field {
28+
param := huh.NewMultiSelect[string]().Key(p.Name).
29+
Options(p.Options...).
30+
Title(p.Label)
31+
if len(p.Description) > 0 {
32+
param.Description(p.Description)
33+
}
34+
35+
param.Value(&p.DefaultValue)
36+
37+
if p.Required {
38+
param.Validate(validators.MultiRequired(p.Name))
39+
}
40+
41+
return param
42+
}

0 commit comments

Comments
 (0)