mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 12:25:47 +02:00
feat: Support multiple commit prefixes
This implementation, unlike that proposed in https://github.com/jesseduffield/lazygit/pull/4253 keeps the yaml schema easy, and does a migration from the single elements to a sequence of elements.
This commit is contained in:
parent
a7bfeca9c0
commit
2fa4ee2cac
14 changed files with 395 additions and 65 deletions
|
@ -341,14 +341,6 @@ git:
|
|||
# If true, do not allow force pushes
|
||||
disableForcePushing: false
|
||||
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
|
||||
commitPrefix:
|
||||
# pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*"
|
||||
pattern: ""
|
||||
|
||||
# Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
|
||||
replace: ""
|
||||
|
||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix
|
||||
branchPrefix: ""
|
||||
|
||||
|
@ -922,27 +914,40 @@ Where:
|
|||
## Predefined commit message prefix
|
||||
|
||||
In situations where certain naming pattern is used for branches and commits, pattern can be used to populate commit message with prefix that is parsed from the branch name.
|
||||
If you define multiple naming patterns, they will be attempted in order until one matches.
|
||||
|
||||
Example:
|
||||
Example hitting first match:
|
||||
|
||||
- Branch name: feature/AB-123
|
||||
- Commit message: [AB-123] Adding feature
|
||||
- Generated commit message prefix: [AB-123]
|
||||
|
||||
Example hitting second match:
|
||||
|
||||
- Branch name: CD-456_fix_problem
|
||||
- Generated commit message prefix: (CD-456)
|
||||
|
||||
```yaml
|
||||
git:
|
||||
commitPrefix:
|
||||
pattern: "^\\w+\\/(\\w+-\\w+).*"
|
||||
replace: '[$1] '
|
||||
- pattern: "^\\w+\\/(\\w+-\\w+).*"
|
||||
replace: '[$1] '
|
||||
- pattern: "^([^_]+)_.*" # Take all text prior to the first underscore
|
||||
replace: '($1) '
|
||||
```
|
||||
|
||||
If you want repository-specific prefixes, you can map them with `commitPrefixes`. If you have both `commitPrefixes` defined and an entry in `commitPrefixes` for the current repo, the `commitPrefixes` entry is given higher precedence. Repository folder names must be an exact match.
|
||||
If you want repository-specific prefixes, you can map them with `commitPrefixes`. If you have both entries in `commitPrefix` defined and an repository match in `commitPrefixes` for the current repo, the `commitPrefixes` entries will be attempted first. Repository folder names must be an exact match.
|
||||
|
||||
```yaml
|
||||
git:
|
||||
commitPrefixes:
|
||||
my_project: # This is repository folder name
|
||||
pattern: "^\\w+\\/(\\w+-\\w+).*"
|
||||
replace: '[$1] '
|
||||
- pattern: "^\\w+\\/(\\w+-\\w+).*"
|
||||
replace: '[$1] '
|
||||
commitPrefix:
|
||||
- pattern: "^(\\w+)-.*" # A more general match for any leading word
|
||||
replace : '[$1] '
|
||||
- pattern: ".*" # The final fallthrough regex that copies over the whole branch name
|
||||
replace : '[$0] '
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
|
|
|
@ -217,6 +217,26 @@ func loadUserConfig(configFiles []*ConfigFile, base *UserConfig) (*UserConfig, e
|
|||
// from one container to another, or changing the type of a key (e.g. from bool
|
||||
// to an enum).
|
||||
func migrateUserConfig(path string, content []byte) ([]byte, error) {
|
||||
changedContent, err := computeMigratedConfig(path, content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Write config back if changed
|
||||
if string(changedContent) != string(content) {
|
||||
fmt.Println("Provided user config is deprecated but auto-fixable. Attempting to write fixed version back to file...")
|
||||
if err := os.WriteFile(path, changedContent, 0o644); err != nil {
|
||||
return nil, fmt.Errorf("While attempting to write back fixed user config to %s, an error occurred: %s", path, err)
|
||||
}
|
||||
fmt.Printf("Success. New config written to %s\n", path)
|
||||
return changedContent, nil
|
||||
}
|
||||
|
||||
return content, nil
|
||||
}
|
||||
|
||||
// A pure function helper for testing purposes
|
||||
func computeMigratedConfig(path string, content []byte) ([]byte, error) {
|
||||
changedContent := content
|
||||
|
||||
pathsToReplace := []struct {
|
||||
|
@ -241,19 +261,18 @@ func migrateUserConfig(path string, content []byte) ([]byte, error) {
|
|||
return nil, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
|
||||
}
|
||||
|
||||
// Add more migrations here...
|
||||
|
||||
// Write config back if changed
|
||||
if string(changedContent) != string(content) {
|
||||
fmt.Println("Provided user config is deprecated but auto-fixable. Attempting to write fixed version back to file...")
|
||||
if err := os.WriteFile(path, changedContent, 0o644); err != nil {
|
||||
return nil, fmt.Errorf("While attempting to write back fixed user config to %s, an error occurred: %s", path, err)
|
||||
}
|
||||
fmt.Printf("Success. New config written to %s\n", path)
|
||||
return changedContent, nil
|
||||
changedContent, err = changeElementToSequence(changedContent, []string{"git", "commitPrefix"})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
|
||||
}
|
||||
|
||||
return content, nil
|
||||
changedContent, err = changeCommitPrefixesMap(changedContent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
|
||||
}
|
||||
// Add more migrations here...
|
||||
|
||||
return changedContent, nil
|
||||
}
|
||||
|
||||
func changeNullKeybindingsToDisabled(changedContent []byte) ([]byte, error) {
|
||||
|
@ -267,6 +286,46 @@ func changeNullKeybindingsToDisabled(changedContent []byte) ([]byte, error) {
|
|||
})
|
||||
}
|
||||
|
||||
func changeElementToSequence(changedContent []byte, path []string) ([]byte, error) {
|
||||
return yaml_utils.TransformNode(changedContent, path, func(node *yaml.Node) (bool, error) {
|
||||
if node.Kind == yaml.MappingNode {
|
||||
nodeContentCopy := node.Content
|
||||
node.Kind = yaml.SequenceNode
|
||||
node.Value = ""
|
||||
node.Tag = "!!seq"
|
||||
node.Content = []*yaml.Node{{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: nodeContentCopy,
|
||||
}}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
func changeCommitPrefixesMap(changedContent []byte) ([]byte, error) {
|
||||
return yaml_utils.TransformNode(changedContent, []string{"git", "commitPrefixes"}, func(prefixesNode *yaml.Node) (bool, error) {
|
||||
if prefixesNode.Kind == yaml.MappingNode {
|
||||
for _, contentNode := range prefixesNode.Content {
|
||||
if contentNode.Kind == yaml.MappingNode {
|
||||
nodeContentCopy := contentNode.Content
|
||||
contentNode.Kind = yaml.SequenceNode
|
||||
contentNode.Value = ""
|
||||
contentNode.Tag = "!!seq"
|
||||
contentNode.Content = []*yaml.Node{{
|
||||
Kind: yaml.MappingNode,
|
||||
Content: nodeContentCopy,
|
||||
}}
|
||||
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *AppConfig) GetDebug() bool {
|
||||
return c.debug
|
||||
}
|
||||
|
|
78
pkg/config/app_config_test.go
Normal file
78
pkg/config/app_config_test.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestCommitPrefixMigrations(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
"Empty String",
|
||||
"",
|
||||
"",
|
||||
}, {
|
||||
"Single CommitPrefix Rename",
|
||||
`
|
||||
git:
|
||||
commitPrefix:
|
||||
pattern: "^\\w+-\\w+.*"
|
||||
replace: '[JIRA $0] '`,
|
||||
`
|
||||
git:
|
||||
commitPrefix:
|
||||
- pattern: "^\\w+-\\w+.*"
|
||||
replace: '[JIRA $0] '`,
|
||||
}, {
|
||||
"Complicated CommitPrefixes Rename",
|
||||
`
|
||||
git:
|
||||
commitPrefixes:
|
||||
foo:
|
||||
pattern: "^\\w+-\\w+.*"
|
||||
replace: '[OTHER $0] '
|
||||
CrazyName!@#$^*&)_-)[[}{f{[]:
|
||||
pattern: "^foo.bar*"
|
||||
replace: '[FUN $0] '`,
|
||||
`
|
||||
git:
|
||||
commitPrefixes:
|
||||
foo:
|
||||
- pattern: "^\\w+-\\w+.*"
|
||||
replace: '[OTHER $0] '
|
||||
CrazyName!@#$^*&)_-)[[}{f{[]:
|
||||
- pattern: "^foo.bar*"
|
||||
replace: '[FUN $0] '`,
|
||||
}, {
|
||||
"Incomplete Configuration",
|
||||
"git:",
|
||||
"git:",
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
expectedConfig := GetDefaultConfig()
|
||||
err := yaml.Unmarshal([]byte(s.expected), expectedConfig)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
actual, err := computeMigratedConfig("path doesn't matter", []byte(s.input))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
actualConfig := GetDefaultConfig()
|
||||
err = yaml.Unmarshal(actual, actualConfig)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
assert.Equal(t, expectedConfig, actualConfig)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -256,9 +256,9 @@ type GitConfig struct {
|
|||
// If true, do not allow force pushes
|
||||
DisableForcePushing bool `yaml:"disableForcePushing"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
|
||||
CommitPrefix *CommitPrefixConfig `yaml:"commitPrefix"`
|
||||
CommitPrefix []CommitPrefixConfig `yaml:"commitPrefix"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
|
||||
CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"`
|
||||
CommitPrefixes map[string][]CommitPrefixConfig `yaml:"commitPrefixes"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix
|
||||
BranchPrefix string `yaml:"branchPrefix"`
|
||||
// If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀
|
||||
|
@ -784,7 +784,7 @@ func GetDefaultConfig() *UserConfig {
|
|||
BranchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --",
|
||||
AllBranchesLogCmd: "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium",
|
||||
DisableForcePushing: false,
|
||||
CommitPrefixes: map[string]CommitPrefixConfig(nil),
|
||||
CommitPrefixes: map[string][]CommitPrefixConfig(nil),
|
||||
BranchPrefix: "",
|
||||
ParseEmoji: false,
|
||||
TruncateCopiedCommitHashesTo: 12,
|
||||
|
|
|
@ -152,8 +152,8 @@ func (self *WorkingTreeHelper) HandleCommitPress() error {
|
|||
message := self.c.Contexts().CommitMessage.GetPreservedMessageAndLogError()
|
||||
|
||||
if message == "" {
|
||||
commitPrefixConfig := self.commitPrefixConfigForRepo()
|
||||
if commitPrefixConfig != nil {
|
||||
commitPrefixConfigs := self.commitPrefixConfigsForRepo()
|
||||
for _, commitPrefixConfig := range commitPrefixConfigs {
|
||||
prefixPattern := commitPrefixConfig.Pattern
|
||||
prefixReplace := commitPrefixConfig.Replace
|
||||
branchName := self.refHelper.GetCheckedOutRef().Name
|
||||
|
@ -165,6 +165,7 @@ func (self *WorkingTreeHelper) HandleCommitPress() error {
|
|||
if rgx.MatchString(branchName) {
|
||||
prefix := rgx.ReplaceAllString(branchName, prefixReplace)
|
||||
message = prefix
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,11 +229,11 @@ func (self *WorkingTreeHelper) prepareFilesForCommit() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (self *WorkingTreeHelper) commitPrefixConfigForRepo() *config.CommitPrefixConfig {
|
||||
func (self *WorkingTreeHelper) commitPrefixConfigsForRepo() []config.CommitPrefixConfig {
|
||||
cfg, ok := self.c.UserConfig().Git.CommitPrefixes[self.c.Git().RepoPaths.RepoName()]
|
||||
if ok {
|
||||
return &cfg
|
||||
return append(cfg, self.c.UserConfig().Git.CommitPrefix...)
|
||||
} else {
|
||||
return self.c.UserConfig().Git.CommitPrefix
|
||||
}
|
||||
|
||||
return self.c.UserConfig().Git.CommitPrefix
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ var CommitWipWithPrefix = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.CommitPrefixes = map[string]config.CommitPrefixConfig{"repo": {Pattern: "^\\w+\\/(\\w+-\\w+).*", Replace: "[$1]: "}}
|
||||
cfg.GetUserConfig().Git.CommitPrefixes = map[string][]config.CommitPrefixConfig{"repo": {{Pattern: "^\\w+\\/(\\w+-\\w+).*", Replace: "[$1]: "}}}
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.NewBranch("feature/TEST-002")
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package commit
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var CommitWithFallthroughPrefix = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Commit with multiple CommitPrefixConfig",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.CommitPrefix = []config.CommitPrefixConfig{
|
||||
{Pattern: "^doesntmatch-(\\w+).*", Replace: "[BAD $1]: "},
|
||||
{Pattern: "^\\w+\\/(\\w+-\\w+).*", Replace: "[GOOD $1]: "},
|
||||
}
|
||||
cfg.GetUserConfig().Git.CommitPrefixes = map[string][]config.CommitPrefixConfig{
|
||||
"DifferentProject": {{Pattern: "^otherthatdoesn'tmatch-(\\w+).*", Replace: "[BAD $1]: "}},
|
||||
}
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.NewBranch("feature/TEST-001")
|
||||
shell.CreateFile("test-commit-prefix", "This is foo bar")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Commits().
|
||||
IsEmpty()
|
||||
|
||||
t.Views().Files().
|
||||
IsFocused().
|
||||
PressPrimaryAction().
|
||||
Press(keys.Files.CommitChanges)
|
||||
|
||||
t.ExpectPopup().CommitMessagePanel().
|
||||
Title(Equals("Commit summary")).
|
||||
InitialText(Equals("[GOOD TEST-001]: ")).
|
||||
Type("my commit message").
|
||||
Cancel()
|
||||
|
||||
t.Views().Files().
|
||||
IsFocused().
|
||||
Press(keys.Files.CommitChanges)
|
||||
|
||||
t.ExpectPopup().CommitMessagePanel().
|
||||
Title(Equals("Commit summary")).
|
||||
InitialText(Equals("[GOOD TEST-001]: my commit message")).
|
||||
Type(". Added something else").
|
||||
Confirm()
|
||||
|
||||
t.Views().Commits().Focus()
|
||||
t.Views().Main().Content(Contains("[GOOD TEST-001]: my commit message. Added something else"))
|
||||
},
|
||||
})
|
|
@ -10,7 +10,7 @@ var CommitWithGlobalPrefix = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.CommitPrefix = &config.CommitPrefixConfig{Pattern: "^\\w+\\/(\\w+-\\w+).*", Replace: "[$1]: "}
|
||||
cfg.GetUserConfig().Git.CommitPrefix = []config.CommitPrefixConfig{{Pattern: "^\\w+\\/(\\w+-\\w+).*", Replace: "[$1]: "}}
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.NewBranch("feature/TEST-001")
|
||||
|
|
|
@ -10,10 +10,10 @@ var CommitWithNonMatchingBranchName = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.CommitPrefix = &config.CommitPrefixConfig{
|
||||
cfg.GetUserConfig().Git.CommitPrefix = []config.CommitPrefixConfig{{
|
||||
Pattern: "^\\w+\\/(\\w+-\\w+).*",
|
||||
Replace: "[$1]: ",
|
||||
}
|
||||
}}
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
shell.NewBranch("branchnomatch")
|
||||
|
|
|
@ -10,11 +10,11 @@ var CommitWithPrefix = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(cfg *config.AppConfig) {
|
||||
cfg.GetUserConfig().Git.CommitPrefixes = map[string]config.CommitPrefixConfig{
|
||||
"repo": {
|
||||
cfg.GetUserConfig().Git.CommitPrefixes = map[string][]config.CommitPrefixConfig{
|
||||
"repo": {{
|
||||
Pattern: `^\w+/(\w+-\w+).*`,
|
||||
Replace: "[$1]: ",
|
||||
},
|
||||
}},
|
||||
}
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
|
|
|
@ -93,6 +93,7 @@ var tests = []*components.IntegrationTest{
|
|||
commit.CommitMultiline,
|
||||
commit.CommitSwitchToEditor,
|
||||
commit.CommitWipWithPrefix,
|
||||
commit.CommitWithFallthroughPrefix,
|
||||
commit.CommitWithGlobalPrefix,
|
||||
commit.CommitWithNonMatchingBranchName,
|
||||
commit.CommitWithPrefix,
|
||||
|
|
|
@ -99,6 +99,55 @@ func lookupKey(node *yaml.Node, key string) (*yaml.Node, *yaml.Node) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// Walks a yaml document to the specified path, and then applies the transformation to that node.
|
||||
//
|
||||
// The transform must return true if it made changes to the node.
|
||||
// If the requested path is not defined in the document, no changes are made to the document.
|
||||
//
|
||||
// If no changes are made, the original document is returned.
|
||||
// If changes are made, a newly marshalled document is returned. (This may result in different indentation for all nodes)
|
||||
func TransformNode(yamlBytes []byte, path []string, transform func(node *yaml.Node) (bool, error)) ([]byte, error) {
|
||||
// Parse the YAML file.
|
||||
var node yaml.Node
|
||||
err := yaml.Unmarshal(yamlBytes, &node)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse YAML: %w", err)
|
||||
}
|
||||
|
||||
// Empty document: nothing to do.
|
||||
if len(node.Content) == 0 {
|
||||
return yamlBytes, nil
|
||||
}
|
||||
|
||||
body := node.Content[0]
|
||||
|
||||
if didTransform, err := transformNode(body, path, transform); err != nil || !didTransform {
|
||||
return yamlBytes, err
|
||||
}
|
||||
|
||||
// Convert the updated YAML node back to YAML bytes.
|
||||
updatedYAMLBytes, err := yaml.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert YAML node to bytes: %w", err)
|
||||
}
|
||||
|
||||
return updatedYAMLBytes, nil
|
||||
}
|
||||
|
||||
// A recursive function to walk down the tree. See TransformNode for more details.
|
||||
func transformNode(node *yaml.Node, path []string, transform func(node *yaml.Node) (bool, error)) (bool, error) {
|
||||
if len(path) == 0 {
|
||||
return transform(node)
|
||||
}
|
||||
|
||||
keyNode, valueNode := lookupKey(node, path[0])
|
||||
if keyNode == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return transformNode(valueNode, path[1:], transform)
|
||||
}
|
||||
|
||||
// takes a yaml document in bytes, a path to a key, and a new name for the key.
|
||||
// Will rename the key to the new name if it exists, and do nothing otherwise.
|
||||
func RenameYamlKey(yamlBytes []byte, path []string, newKey string) ([]byte, error) {
|
||||
|
@ -106,7 +155,7 @@ func RenameYamlKey(yamlBytes []byte, path []string, newKey string) ([]byte, erro
|
|||
var node yaml.Node
|
||||
err := yaml.Unmarshal(yamlBytes, &node)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse YAML: %w", err)
|
||||
return nil, fmt.Errorf("failed to parse YAML: %w for bytes %s", err, string(yamlBytes))
|
||||
}
|
||||
|
||||
// Empty document: nothing to do.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package yaml_utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -314,3 +315,80 @@ func TestWalk_inPlaceChanges(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransformNode(t *testing.T) {
|
||||
transformIntValueToString := func(node *yaml.Node) (bool, error) {
|
||||
if node.Kind == yaml.ScalarNode {
|
||||
if node.ShortTag() == "!!int" {
|
||||
node.Tag = "!!str"
|
||||
return true, nil
|
||||
} else if node.ShortTag() == "!!str" {
|
||||
// We have already transformed it,
|
||||
return false, nil
|
||||
} else {
|
||||
return false, fmt.Errorf("Node was of bad type")
|
||||
}
|
||||
} else {
|
||||
return false, fmt.Errorf("Node was not a scalar")
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
path []string
|
||||
transform func(node *yaml.Node) (bool, error)
|
||||
expectedOut string
|
||||
}{
|
||||
{
|
||||
name: "Path not present",
|
||||
in: "foo: 1",
|
||||
path: []string{"bar"},
|
||||
transform: transformIntValueToString,
|
||||
expectedOut: "foo: 1",
|
||||
},
|
||||
{
|
||||
name: "Part of path present",
|
||||
in: `
|
||||
foo:
|
||||
bar: 2`,
|
||||
path: []string{"foo", "baz"},
|
||||
transform: transformIntValueToString,
|
||||
expectedOut: `
|
||||
foo:
|
||||
bar: 2`,
|
||||
},
|
||||
{
|
||||
name: "Successfully Transforms to string",
|
||||
in: `
|
||||
foo:
|
||||
bar: 2`,
|
||||
path: []string{"foo", "bar"},
|
||||
transform: transformIntValueToString,
|
||||
expectedOut: `foo:
|
||||
bar: "2"
|
||||
`, // Note the indentiation change and newlines because of how it re-marshalls
|
||||
},
|
||||
{
|
||||
name: "Does nothing when already transformed",
|
||||
in: `
|
||||
foo:
|
||||
bar: "2"`,
|
||||
path: []string{"foo", "bar"},
|
||||
transform: transformIntValueToString,
|
||||
expectedOut: `
|
||||
foo:
|
||||
bar: "2"`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
result, err := TransformNode([]byte(test.in), test.path, test.transform)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, test.expectedOut, string(result))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -638,28 +638,7 @@
|
|||
"default": false
|
||||
},
|
||||
"commitPrefix": {
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"description": "pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use \"^\\\\w+\\\\/(\\\\w+-\\\\w+).*\"",
|
||||
"examples": [
|
||||
"^\\w+\\/(\\w+-\\w+).*"
|
||||
]
|
||||
},
|
||||
"replace": {
|
||||
"type": "string",
|
||||
"description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"",
|
||||
"examples": [
|
||||
"[$1]"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix"
|
||||
},
|
||||
"commitPrefixes": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
|
@ -679,6 +658,33 @@
|
|||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array",
|
||||
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix"
|
||||
},
|
||||
"commitPrefixes": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string",
|
||||
"description": "pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use \"^\\\\w+\\\\/(\\\\w+-\\\\w+).*\"",
|
||||
"examples": [
|
||||
"^\\w+\\/(\\w+-\\w+).*"
|
||||
]
|
||||
},
|
||||
"replace": {
|
||||
"type": "string",
|
||||
"description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"",
|
||||
"examples": [
|
||||
"[$1]"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"type": "object",
|
||||
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix"
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue