Skip to content

Commit

Permalink
feat: ✨ (#20) bind viper flags with cobra flags (#22)
Browse files Browse the repository at this point in the history
* feat: ✨ (#20) bind viper flags with cobra flags

* feat: ✨ (#20) bind viper flags with cobra flags
  • Loading branch information
AndreasAugustin authored Aug 17, 2023
1 parent 103a1c8 commit dbb37a0
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 42 deletions.
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- [x] cli -> done with installers
- [x] info -> get infos like cache dir
- [x] check all config parameters implemented
- [ ] commit
- [x] commit
- [x] add dryrun
- [x] gitmoji
- [x] scope
Expand All @@ -30,7 +30,7 @@
- [x] docker for dev and release a example image
- [x] ci/cd -> releaser action [gorealeaser][goreleaser]
- [x] bug in config -> gitmoji url is not shown properly
- [ ] viper config params also as cli flags
- [x] viper config params also as cli flags
- [ ] issue with ctrl+c -> will get to next command
- [x] add hook functionality
- [x] update basic readme with nice terminal gifs
Expand Down
18 changes: 14 additions & 4 deletions cmd/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,27 @@ var CommitCmd = &cobra.Command{
spin.Stop()
return
}
gitmojis := pkg.GetGitmojis()
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("get current config issue, %s", err)
}
gitmojis := pkg.GetGitmojis(config)
spin.Stop()
initialCommitValues := pkg.InitialCommitValues{Type: _type, Scope: scope, Desc: desc, Body: body}
listSettings := ui.ListSettings{IsShowStatusBar: true, IsFilteringEnabled: true, Title: "Gitmojis"}
selectedGitmoji := ui.ListRun(listSettings, gitmojis.Gitmojis)
log.Debugf("selected gitmoji %s", selectedGitmoji)
textInputsData := initialCommitValues.BuildTextInputsData(pkg.ConfigInstance)
textInputsData := initialCommitValues.BuildTextInputsData(config)
inputsRes := ui.TextInputsRun("please add", textInputsData)

commitValues := pkg.CreateMessage(inputsRes, selectedGitmoji, initialCommitValues, pkg.ConfigInstance, isBreaking)
commitValues := pkg.CreateMessage(inputsRes, selectedGitmoji, initialCommitValues, config, isBreaking)

log.Debugf("complete title: %s", commitValues.Title)
if isDryRun {
log.Infof("The commit title: %s", commitValues.Title)
log.Infof("The commit body: %s", commitValues.Body)
} else {
pkg.ExecuteCommit(commitValues.Title, commitValues.Body, pkg.ConfigInstance)
pkg.ExecuteCommit(commitValues.Title, commitValues.Body, config)
}
},
}
Expand All @@ -66,4 +70,10 @@ func init() {
CommitCmd.PersistentFlags().StringVar(&desc, string(pkg.DESC), "", "add a description")
CommitCmd.PersistentFlags().StringVar(&body, string(pkg.BODY), "", "add the commit message body")
CommitCmd.PersistentFlags().BoolVar(&isBreaking, string(pkg.IS_BREAKING), false, "set if the commit is a breaking change")

bindAndAddBoolFlagP(CommitCmd, string(pkg.AUTO_ADD), "auto-add", "a", "call git add . before commit")
bindAndAddBoolFlagP(CommitCmd, string(pkg.AUTO_SIGN), "auto-sign", "S", "add -S flag to git commit")
bindAndAddBoolFlag(CommitCmd, string(pkg.CAPITALIZE_TITLE), "capitalize-title", "capitalize the title")
bindAndAddBoolFlag(CommitCmd, string(pkg.SCOPE_PROMPT), "scope-prompt", "enable scope prompt")
bindAndAddBoolFlag(CommitCmd, string(pkg.BODY_PROMPT), "body-prompt", "enable body prompt")
}
26 changes: 26 additions & 0 deletions cmd/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmd

import (
"fmt"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func bindAndAddBoolFlagP(cmd *cobra.Command, viperKey string, flagName string, shortHand string, usage string) {
cmd.PersistentFlags().BoolP(flagName, shortHand, false, fmt.Sprintf("%s. If not set the configured value is used", usage))
err := viper.BindPFlag(viperKey, CommitCmd.PersistentFlags().Lookup(flagName))

if err != nil {
log.Fatalf("issue with binding flags %s", err)
}
}

func bindAndAddBoolFlag(cmd *cobra.Command, viperKey string, flagName string, usage string) {
cmd.PersistentFlags().Bool(flagName, false, fmt.Sprintf("%s. If not set the configured value is used", usage))
err := viper.BindPFlag(viperKey, CommitCmd.PersistentFlags().Lookup(flagName))

if err != nil {
log.Fatalf("issue with binding flags %s", err)
}
}
5 changes: 4 additions & 1 deletion cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ var ConfigCmd = &cobra.Command{
by the local configuration file or a global configuration file within your OS config folder (use the info command to get the information where it is stored)`,
Run: func(cmd *cobra.Command, args []string) {
log.Debug("config called")
config := pkg.ConfigInstance
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("get current config issue, %s", err)
}
autoAdd := runConfigConfirmationPrompt("Enable automatic 'git add .'", config.AutoAdd)
autoSign := runConfigConfirmationPrompt("Automatically sign commits (add '-S' flag)", config.AutoSign)
emojiFormat := runEmojiSelectionPrompt("Select how emojis should be used in commits. For a comparison please visit https://gitmoji.dev/specification")
Expand Down
10 changes: 7 additions & 3 deletions cmd/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,20 @@ func hookCommit() {
spin.Stop()
return
}
gitmojis := pkg.GetGitmojis()
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("get current config issue, %s", err)
}
gitmojis := pkg.GetGitmojis(config)
spin.Stop()
initialCommitValues := pkg.InitialCommitValues{}
listSettings := ui.ListSettings{IsShowStatusBar: true, IsFilteringEnabled: true, Title: "Gitmojis"}
selectedGitmoji := ui.ListRun(listSettings, gitmojis.Gitmojis)
log.Debugf("selected gitmoji %s", selectedGitmoji)
textInputsData := initialCommitValues.BuildTextInputsData(pkg.ConfigInstance)
textInputsData := initialCommitValues.BuildTextInputsData(config)
inputsRes := ui.TextInputsRun("please add", textInputsData)

commitValues := pkg.CreateMessage(inputsRes, selectedGitmoji, initialCommitValues, pkg.ConfigInstance, isBreaking)
commitValues := pkg.CreateMessage(inputsRes, selectedGitmoji, initialCommitValues, config, isBreaking)

log.Debugf("complete title: %s", commitValues.Title)

Expand Down
6 changes: 5 additions & 1 deletion cmd/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ var InfoCmd = &cobra.Command{
Short: "Get some relevant information",
Long: `Get some information like config or cache directory on your OS where the cli is writing configuration or cache.`,
Run: func(cmd *cobra.Command, args []string) {
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("error while getting config %s", err)
}
globalConfigDir, _ := utils.GetGlobalConfigDir(pkg.ProgramName)
cacheDir, _ := utils.GetCacheDir(pkg.ProgramName)
log.Debug("info called")
log.Infof("program name: %s", pkg.ProgramName)
log.Infof("version: %s", pkg.Version)
log.Info("It is possible to store the configuration within the repository or globally")
log.Infof("The global config path: %s", globalConfigDir)
log.Infof("The gitmoji infomration is queried from the internet at the gitmoji defined in the config %s", pkg.ConfigInstance.GitmojisUrl)
log.Infof("The gitmoji information is queried from the internet at the gitmoji defined in the config %s", config.GitmojisUrl)
log.Info("and cached")
log.Infof("Gitmoji cache dir: %s", cacheDir)
},
Expand Down
6 changes: 5 additions & 1 deletion cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ var ListCmd = &cobra.Command{
log.Debug("list called")
spin := ui.NewSpinner()
spin.Run()
gitmojis := pkg.GetGitmojis()
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("get current config issue, %s", err)
}
gitmojis := pkg.GetGitmojis(config)
spin.Stop()
listSettings := ui.ListSettings{Title: "Gitmojis", IsShowStatusBar: true, IsFilteringEnabled: true}
selectedGitmoji := ui.ListRun(listSettings, gitmojis.Gitmojis)
Expand Down
6 changes: 5 additions & 1 deletion cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ var UpdateGitmojisCmd = &cobra.Command{
Long: fmt.Sprintf(`Update the gitmojis local cache from %s.`, pkg.DefaultGitmojiApiUrl),
Run: func(cmd *cobra.Command, args []string) {
log.Debug("update gitmojis called")
gitmojis := pkg.GetGitmojis()
config, err := pkg.GetCurrentConfig()
if err != nil {
log.Fatalf("get current config issue, %s", err)
}
gitmojis := pkg.GetGitmojis(config)
pkg.CacheGitmojis(gitmojis)
},
}
Expand Down
20 changes: 10 additions & 10 deletions pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ const EnvPrefix = "GO_GITMOJI_CLI"
const configName = ".gitmojirc"
const configPath = "."

var ConfigInstance Config
func GetCurrentConfig() (config Config, err error) {
err = viper.Unmarshal(&config)
log.Debugf("Config %+v", config)
return
}

func getGlobalConfigPath() (string, error) {
return utils.GetUserConfigDirCreateIfNotExists(ProgramName)
Expand All @@ -41,18 +45,14 @@ func InitConfig() {
if err != nil {
log.Fatalf("No global config path found")
}
ConfigInstance, err = LoadConfig([]string{configPath, globalConfigPath})
err = LoadConfig([]string{configPath, globalConfigPath})
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}
}

func AddEnvPrefix(suffix string) string {
return fmt.Sprintf("%s_%s", EnvPrefix, suffix)
}

func LoadConfig(configPaths []string) (config Config, err error) {
func LoadConfig(configPaths []string) (err error) {
viper.SetDefault(string(AUTO_ADD), false)
viper.SetDefault(string(AUTO_SIGN), false)
viper.SetDefault(string(EMOJI_FORMAT), string(CODE))
Expand All @@ -70,18 +70,18 @@ func LoadConfig(configPaths []string) (config Config, err error) {
}

viper.SetConfigName(configName)
if err = viper.ReadInConfig(); err != nil {
if expErr := viper.ReadInConfig(); expErr != nil {
// It's okay if there isn't a config file
var configFileNotFoundError viper.ConfigFileNotFoundError
if !errors.As(err, &configFileNotFoundError) {
if !errors.As(expErr, &configFileNotFoundError) {
return
}
}
viper.WatchConfig()
}

viper.AutomaticEnv()

err = viper.Unmarshal(&config)
return
}

Expand Down
44 changes: 31 additions & 13 deletions pkg/config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pkg_test

import (
"fmt"
"github.com/AndreasAugustin/go-gitmoji-cli/pkg"
"github.com/AndreasAugustin/go-gitmoji-cli/pkg/utils"
"github.com/stretchr/testify/assert"
Expand All @@ -10,14 +11,21 @@ import (
"testing"
)

func addEnvPrefix(suffix string) string {
return fmt.Sprintf("%s_%s", pkg.EnvPrefix, suffix)
}

func getTestConfigPath(T *testing.T) string {
wDir, err := os.Getwd()
assert.NoError(T, err)
return path.Join(wDir, "tmp", "test")
}

func TestConfigDefaultValuesEqualsExpected(t *testing.T) {
config, _ := pkg.LoadConfig([]string{})
err := pkg.LoadConfig([]string{})
assert.NoError(t, err)
config, err := pkg.GetCurrentConfig()
assert.NoError(t, err)
expected := pkg.Config{EmojiFormat: pkg.CODE, AutoAdd: false, ScopePrompt: false, BodyPrompt: false, CapitalizeTitle: false, GitmojisUrl: "https://gitmoji.dev/api/gitmojis"}
assert.Equal(t, expected, config)
}
Expand All @@ -31,27 +39,34 @@ func TestConfigEvnVariablesEqualsExpected(t *testing.T) {
var gitmojisUrl = "http://foo.bar"
var autoSign = true

t.Setenv(pkg.AddEnvPrefix(string(pkg.AUTO_ADD)), strconv.FormatBool(autoadd))
t.Setenv(pkg.AddEnvPrefix(string(pkg.EMOJI_FORMAT)), string(emojiFormat))
t.Setenv(pkg.AddEnvPrefix(string(pkg.SCOPE_PROMPT)), strconv.FormatBool(scopePrompt))
t.Setenv(pkg.AddEnvPrefix(string(pkg.BODY_PROMPT)), strconv.FormatBool(bodyPrompt))
t.Setenv(pkg.AddEnvPrefix(string(pkg.CAPITALIZE_TITLE)), strconv.FormatBool(capitalizeTitle))
t.Setenv(pkg.AddEnvPrefix(string(pkg.GITMOJIS_URL)), gitmojisUrl)
t.Setenv(pkg.AddEnvPrefix(string(pkg.AUTO_SIGN)), strconv.FormatBool(autoSign))
config, _ := pkg.LoadConfig([]string{})
t.Setenv(addEnvPrefix(string(pkg.AUTO_ADD)), strconv.FormatBool(autoadd))
t.Setenv(addEnvPrefix(string(pkg.EMOJI_FORMAT)), string(emojiFormat))
t.Setenv(addEnvPrefix(string(pkg.SCOPE_PROMPT)), strconv.FormatBool(scopePrompt))
t.Setenv(addEnvPrefix(string(pkg.BODY_PROMPT)), strconv.FormatBool(bodyPrompt))
t.Setenv(addEnvPrefix(string(pkg.CAPITALIZE_TITLE)), strconv.FormatBool(capitalizeTitle))
t.Setenv(addEnvPrefix(string(pkg.GITMOJIS_URL)), gitmojisUrl)
t.Setenv(addEnvPrefix(string(pkg.AUTO_SIGN)), strconv.FormatBool(autoSign))
err1 := pkg.LoadConfig([]string{})
assert.NoError(t, err1)
config, err := pkg.GetCurrentConfig()
assert.NoError(t, err)
expected := pkg.Config{EmojiFormat: emojiFormat, AutoAdd: autoadd, AutoSign: autoSign, ScopePrompt: scopePrompt, BodyPrompt: bodyPrompt, CapitalizeTitle: capitalizeTitle, GitmojisUrl: gitmojisUrl}
assert.Equal(t, expected, config)
}

func TestConfigConfigFileEqualsExpected(t *testing.T) {
config, _ := pkg.LoadConfig([]string{"./test_data"})
err1 := pkg.LoadConfig([]string{"./test_data"})
assert.NoError(t, err1)
config, err := pkg.GetCurrentConfig()
assert.NoError(t, err)
expected := pkg.Config{EmojiFormat: pkg.EMOJI, AutoAdd: true, ScopePrompt: true, BodyPrompt: false, CapitalizeTitle: false, GitmojisUrl: "http://from.file"}
assert.Equal(t, expected, config)
}

func TestWriteGlobalConfigAndReadEqualsExpected(t *testing.T) {
config, err := pkg.LoadConfig([]string{"./test_data"})

err1 := pkg.LoadConfig([]string{"./test_data"})
assert.NoError(t, err1)
config, err := pkg.GetCurrentConfig()
assert.NoError(t, err)
getGlobalConfigDirPersist := utils.GetGlobalConfigDir

Expand All @@ -62,7 +77,10 @@ func TestWriteGlobalConfigAndReadEqualsExpected(t *testing.T) {

pkg.UpdateConfig(config, true)
globalConfigPath := path.Join(getTestConfigPath(t), pkg.ProgramName)
configFromGlobal, err := pkg.LoadConfig([]string{globalConfigPath})
err1 = pkg.LoadConfig([]string{globalConfigPath})
assert.NoError(t, err1)
configFromGlobal, err := pkg.GetCurrentConfig()
assert.NoError(t, err)
defer func() {
utils.GetGlobalConfigDir = getGlobalConfigDirPersist
os.RemoveAll(getTestCacheProgramPath(t))
Expand Down
12 changes: 6 additions & 6 deletions pkg/gitmoji.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ func CacheGitmojis(gitmojis Gitmojis) {
cacheGitmojisTo(gitmojisCachePath, gitmojis)
}

func GetGitmojis() (gitmojis Gitmojis) {
func GetGitmojis(config Config) (gitmojis Gitmojis) {
gitmojis, err := GetGitmojisCache()
if err != nil {
log.Info("Haven't been able to read gitmojis from cache")
log.Infof("Reading from %s and write to cache", ConfigInstance.GitmojisUrl)
gitmojis, err = getGitmojisHttp()
log.Infof("Reading from %s and write to cache", config.GitmojisUrl)
gitmojis, err = getGitmojisHttp(config)
if err != nil {
log.Fatalf("Some error happened %s", err)
}
Expand Down Expand Up @@ -74,8 +74,8 @@ func getGitmojisCacheFrom(cachePath string) (gitmojis Gitmojis, err error) {
return
}

func getGitmojisHttp() (gitmojis Gitmojis, err error) {
res, err := http.Get(ConfigInstance.GitmojisUrl)
func getGitmojisHttp(config Config) (gitmojis Gitmojis, err error) {
res, err := http.Get(config.GitmojisUrl)
if err != nil {
fmt.Println("error", err)
}
Expand All @@ -98,6 +98,6 @@ func getGitmojisHttp() (gitmojis Gitmojis, err error) {
if err != nil {
return
}
log.Debugf("Finished retreiving gitmojis from %s", ConfigInstance.GitmojisUrl)
log.Debugf("Finished retreiving gitmojis from %s", config.GitmojisUrl)
return
}

0 comments on commit dbb37a0

Please sign in to comment.