Repository: jesseduffield/lazygit
File: pkg/config/app_config.go (Go)

Code before:
// a single element at `allBranchesLogCmd` and the sequence at `allBranchesLogCmds`.
// Some users have explicitly set `allBranchesLogCmd` to be an empty string in order
// to remove it, so in that case we just delete the element, and add nothing to the list
func migrateAllBranchesLogCmd(rootNode *yaml.Node) error {
	return yaml_utils.TransformNode(rootNode, []string{"git"}, func(gitNode *yaml.Node) error {
		cmdKeyNode, cmdValueNode := yaml_utils.LookupKey(gitNode, "allBranchesLogCmd")
		// Nothing to do if they do not have the deprecated item
		if cmdKeyNode == nil {
			return nil
		}

		cmdsKeyNode, cmdsValueNode := yaml_utils.LookupKey(gitNode, "allBranchesLogCmds")
		if cmdsKeyNode == nil {
			// Create dummy node and attach it onto the root git node
			cmdsKeyNode = &yaml.Node{Kind: yaml.ScalarNode, Value: "allBranchesLogCmds"}
			cmdsValueNode = &yaml.Node{Kind: yaml.SequenceNode, Content: []*yaml.Node{}}
			gitNode.Content = append(gitNode.Content,
				cmdsKeyNode,
				cmdsValueNode,
			)
		}

		if cmdValueNode.Value != "" {
			if cmdsValueNode.Kind != yaml.SequenceNode {
				return fmt.Errorf("You should have an allBranchesLogCmds defined as a sequence!")
			}
			// Prepending the individual element to make it show up first in the list, which was prior behavior
			cmdsValueNode.Content = append([]*yaml.Node{{Kind: yaml.ScalarNode, Value: cmdValueNode.Value}}, cmdsValueNode.Content...)
		}

		// Clear out the existing allBranchesLogCmd, now that we have migrated it into the list
		_, _ = yaml_utils.RemoveKey(gitNode, "allBranchesLogCmd")

		return nil
	})
}

func (c *AppConfig) GetDebug() bool {
	return c.debug
}

func (c *AppConfig) GetVersion() string {
	return c.version
}

func (c *AppConfig) GetName() string {
	return c.name
}

// GetBuildSource returns the source of the build. For builds from goreleaser
// this will be binaryBuild

Review comment (bug):
I find it slightly confusing to do this here, where in half of the cases we have just created this ourselves and know it's the right type. I would move this up to an `else` block after line 370. (Yes, it then runs unnecessarily even when cmdValueNode is empty and there's nothing to migrate, but it doesn't hurt to throw the error in that case too; loading the non-migrated config file would have failed anyway.)

Code after:
			}
		}
		return nil
	})
}

func changeCustomCommandStreamAndOutputToOutputEnum(rootNode *yaml.Node) error {
	return yaml_utils.Walk(rootNode, func(node *yaml.Node, path string) {
		// We are being lazy here and rely on the fact that the only mapping
		// nodes in the tree under customCommands are actual custom commands. If
		// this ever changes (e.g. because we add a struct field to
		// customCommand), then we need to change this to iterate properly.
		if strings.HasPrefix(path, "customCommands[") && node.Kind == yaml.MappingNode {
			output := ""
			if streamKey, streamValue := yaml_utils.RemoveKey(node, "subprocess"); streamKey != nil {
				if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" {
					output = "terminal"
				}
			}
			if streamKey, streamValue := yaml_utils.RemoveKey(node, "stream"); streamKey != nil {
				if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" && output == "" {
					output = "log"
				}
			}
			if streamKey, streamValue := yaml_utils.RemoveKey(node, "showOutput"); streamKey != nil {
				if streamValue.Kind == yaml.ScalarNode && streamValue.Value == "true" && output == "" {
					output = "popup"
				}
			}
			if output != "" {
				outputKeyNode := &yaml.Node{
					Kind:  yaml.ScalarNode,
					Value: "output",
					Tag:   "!!str",
				}
				outputValueNode := &yaml.Node{
					Kind:  yaml.ScalarNode,
					Value: output,
					Tag:   "!!str",
				}
				node.Content = append(node.Content, outputKeyNode, outputValueNode)
			}
		}
	})
}

// This migration is special because users have already defined
// a single element at `allBranchesLogCmd` and the sequence at `allBranchesLogCmds`.
// Some users have explicitly set `allBranchesLogCmd` to be an empty string in order
// to remove it, so in that case we just delete the element, and add nothing to the list
func migrateAllBranchesLogCmd(rootNode *yaml.Node) error {