Skip to content

Commit 6151def

Browse files
authored
feat(config): restricted scopes (#49)
* feat(config): ability to predefine scopes * docs(CHANGELOG): update changelog * fix(scopes): allow selecting no scope * docs(README): update readme with scopes info * refactor(scopes): change the label for no scopes * chore(README): move warning to before block
1 parent c1d2aaf commit 6151def

File tree

7 files changed

+90
-16
lines changed

7 files changed

+90
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## Unreleased
9+
### Added
10+
- ability to define restricted scopes (#48)
911

1012
## [v0.24.4](https://github.com/stefanlogue/meteor/releases/tag/v0.24.4) - 2024-12-12
1113

README.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@
44
<h5>Meteor is a simple, highly customisable CLI tool that helps you to write <a href="https://www.conventionalcommits.org/">conventional commits</a> with git.</h5>
55
</div>
66

7-
8-
You can call `meteor` where you'd normally type `git commit`. All flags supported in `git commit` will still work.
7+
You can call `meteor` where you'd normally type `git commit`. All flags
8+
supported in `git commit` will still work.
99

1010
![Demo](demos/demo-without-boards.gif)
1111

1212
## Installation
13+
1314
### Homebrew
15+
1416
```console
1517
brew tap stefanlogue/tools
1618
brew install meteor
1719
```
20+
1821
### Go
22+
1923
Install with Go (1.21+):
2024

2125
```console
@@ -26,8 +30,13 @@ Or grab a binary from [the latest release](https://github.com/stefanlogue/meteor
2630

2731
## Customisation
2832

29-
You can customise the options available by creating a `.meteor.json` file anywhere in the directory tree (at or above the current working directory). The config file closest to the current working directory will be preferred. This enables you to have different configs for different parent directories, such as one for your personal work, one for your actual work, one for open source work etc.
30-
For global configurations you can create a `config.json` file in the `~/.config/meteor/` directory.
33+
You can customise the options available by creating a `.meteor.json` file
34+
anywhere in the directory tree (at or above the current working directory). The
35+
config file closest to the current working directory will be preferred. This
36+
enables you to have different configs for different parent directories, such as
37+
one for your personal work, one for your actual work, one for open source work
38+
etc. For global configurations you can create a `config.json` file in the
39+
`~/.config/meteor/` directory.
3140

3241
### Boards
3342

@@ -53,7 +62,9 @@ The content should be in the following format:
5362
}
5463
```
5564

56-
If you use boards (Jira etc) but need a way to have commits without one, add the following to the `boards` array:
65+
If you use boards (Jira etc) but need a way to have commits without one, add the
66+
following to the `boards` array:
67+
5768
```json
5869
{
5970
"boards": [
@@ -63,8 +74,25 @@ If you use boards (Jira etc) but need a way to have commits without one, add the
6374
}
6475
```
6576

77+
If you want to define a set of predefined scopes to select from rather than
78+
typing the scope, a `scopes` array can be added to your config:
79+
80+
> [!WARNING]
81+
> Setting predefined scopes removes the ability to type the scope
82+
83+
```json
84+
{
85+
"scopes": [
86+
{ "name": "scope1" },
87+
{ "name": "scope2"}
88+
]
89+
}
90+
```
91+
6692
### Message Templates
67-
If the default commit message templates aren't exactly what you're looking for, you can provide your own! The syntax can be seen in the defaults below:
93+
94+
If the default commit message templates aren't exactly what you're looking for,
95+
you can provide your own! The syntax can be seen in the defaults below:
6896

6997
```json
7098
{
@@ -74,14 +102,19 @@ If the default commit message templates aren't exactly what you're looking for,
74102
```
75103

76104
`messageTemplate` needs to have:
77-
- `@type`: the conventional commit type i.e. `feat`, `chore` etc.
78-
- `@message`: the commit message
79-
- `(@scope)`: (optional but recommended) the scope of the commit, must be within parentheses
105+
106+
- `@type`: the conventional commit type i.e. `feat`, `chore` etc.
107+
- `@message`: the commit message
108+
- `(@scope)`: (optional but recommended) the scope of the commit, must be within
109+
parentheses
80110

81111
`messageWithTicketTemplate` also additionally takes `@ticket`
82112

83113
### Intro
84-
If you want to skip the intro screen to save a keypress, add the following to your config:
114+
115+
If you want to skip the intro screen to save a keypress, add the following to
116+
your config:
117+
85118
```json
86119
{
87120
"showIntro": false

config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type LoadConfigReturn struct {
2121
Prefixes []huh.Option[string]
2222
Coauthors []huh.Option[string]
2323
Boards []huh.Option[string]
24+
Scopes []huh.Option[string]
2425
CommitTitleCharLimit int
2526
ShowIntro bool
2627
}
@@ -89,6 +90,7 @@ func loadConfig(fs afero.Fs) (LoadConfigReturn, error) {
8990
Prefixes: c.Prefixes.Options(),
9091
Coauthors: c.Coauthors.Options(),
9192
Boards: c.Boards.Options(),
93+
Scopes: c.Scopes.Options(),
9294
CommitTitleCharLimit: *c.CommitTitleCharLimit,
9395
ShowIntro: *c.ShowIntro,
9496
}, nil

main.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,22 @@ func main() {
155155
}
156156
}
157157

158+
// if the user has specified scopes in their config, use a select input, otherwise use a text input
159+
var scopeInput huh.Field
160+
if len(config.Scopes) > 0 {
161+
scopeInput = huh.NewSelect[string]().
162+
Title("Scope").
163+
Description("Choose a scope for the changes").
164+
Options(config.Scopes...).
165+
Value(&newCommit.Scope)
166+
} else {
167+
scopeInput = huh.NewInput().
168+
Title("Scope").
169+
Description("Specify a scope of the changes").
170+
CharLimit(16).
171+
Value(&newCommit.Scope)
172+
}
173+
158174
mainForm := huh.NewForm(
159175
huh.NewGroup(
160176
huh.NewSelect[string]().
@@ -168,11 +184,7 @@ func main() {
168184
Affirmative("Yes!").
169185
Negative("Nope.").
170186
Value(&newCommit.IsBreakingChange),
171-
huh.NewInput().
172-
Title("Scope").
173-
Description("Specify a scope of the change").
174-
CharLimit(16).
175-
Value(&newCommit.Scope),
187+
scopeInput,
176188
),
177189
huh.NewGroup(
178190
huh.NewMultiSelect[string]().

pkg/config/co_author.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ func (p *CoAuthors) Options() []huh.Option[string] {
2727
}
2828
items = append(items, huh.Option[string]{})
2929
copy(items[1:], items)
30-
items[0] = huh.NewOption[string]("no coauthors", "none")
30+
items[0] = huh.NewOption("no coauthors", "none")
3131
return items
3232
}

pkg/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Config struct {
1717
Prefixes Prefixes `json:"prefixes"`
1818
Coauthors CoAuthors `json:"coauthors"`
1919
Boards Boards `json:"boards"`
20+
Scopes Scopes `json:"scopes"`
2021
}
2122

2223
// New returns a new Config

pkg/config/scope.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package config
2+
3+
import "github.com/charmbracelet/huh"
4+
5+
type Scope struct {
6+
Name string `json:"name"`
7+
}
8+
9+
type Scopes []Scope
10+
11+
func (s *Scopes) Options() []huh.Option[string] {
12+
scopes := []Scope(*s)
13+
if len(scopes) == 0 {
14+
return nil
15+
}
16+
items := []huh.Option[string]{}
17+
for _, scope := range scopes {
18+
items = append(items, huh.NewOption(scope.Name, scope.Name))
19+
}
20+
items = append(items, huh.Option[string]{})
21+
copy(items[1:], items)
22+
items[0] = huh.NewOption("none", "")
23+
return items
24+
}

0 commit comments

Comments
 (0)