diff --git a/cmd/root.go b/cmd/root.go index be375ab..c76a432 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -35,7 +35,7 @@ var rootCmd = &cobra.Command{ return } - config, err := config.LoadConfig(".goji.json") + config, err := config.ViperConfig() if err != nil { log.Fatalf(color.YellowString("Error loading config file: %v"), err) } diff --git a/go.mod b/go.mod index 40805e6..ed35ff5 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/muandane/goji -go 1.21.3 +go 1.21.5 require ( - github.com/charmbracelet/huh v0.1.0 + github.com/charmbracelet/huh v0.2.1 github.com/charmbracelet/huh/spinner v0.0.0-20231211205015-d16e6dd5b842 github.com/fatih/color v1.16.0 github.com/spf13/cobra v1.8.0 - github.com/stretchr/testify v1.8.4 + github.com/spf13/viper v1.18.1 ) require ( @@ -15,37 +15,49 @@ require ( github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/catppuccin/go v0.2.0 // indirect github.com/charmbracelet/bubbles v0.16.1 // indirect github.com/charmbracelet/bubbletea v0.24.2 // indirect github.com/charmbracelet/glamour v0.6.0 // indirect github.com/charmbracelet/lipgloss v0.9.1 // indirect - github.com/charmbracelet/x/exp/ordered v0.0.0-20231025135604-4a717d4fb812 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.10.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gorilla/css v1.0.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/microcosm-cc/bluemonday v1.0.26 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.1 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/yuin/goldmark v1.6.0 // indirect github.com/yuin/goldmark-emoji v1.0.2 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/term v0.14.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4b716c6..aab8734 100644 --- a/go.sum +++ b/go.sum @@ -7,37 +7,52 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= +github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY= github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg= github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= -github.com/charmbracelet/huh v0.1.0 h1:EvNILWc+x0/ohiAlGUCK2UYQMO630XZmD/eisKeUJGs= -github.com/charmbracelet/huh v0.1.0/go.mod h1:iJAyphekFE8ANFqmj3ge0VdFoj84OxH0WWSValzDLI0= +github.com/charmbracelet/huh v0.2.1 h1:TBgKwVBg8sZSsJH5tLGoPxUddohv+KHRPOFAO1XA1fs= +github.com/charmbracelet/huh v0.2.1/go.mod h1:+Jnrm/D08qEnnogItoQ63bqmqVF8t4nZWcN7WY0PYAs= github.com/charmbracelet/huh/spinner v0.0.0-20231211205015-d16e6dd5b842 h1:xDlIaXaflYYO3q4GaNfX6kqu0uqdSmdTZ7R5GQb/7Zg= github.com/charmbracelet/huh/spinner v0.0.0-20231211205015-d16e6dd5b842/go.mod h1:8oThTkY972pvMcVAIEtWGT/u4NVV1PXHJ1rZErqNrdw= github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= -github.com/charmbracelet/x/exp/ordered v0.0.0-20231025135604-4a717d4fb812 h1:wBbf9mGJyRlIxn7t4Ri0Ig+HLt6Cv6PC4P3AoBj6jwU= -github.com/charmbracelet/x/exp/ordered v0.0.0-20231025135604-4a717d4fb812/go.mod h1:aoG4bThKYIOnyB55r202eHqo6TkN7ZXV+cu4Do3eoBQ= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= @@ -53,6 +68,8 @@ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= @@ -64,28 +81,45 @@ github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM= +github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= -github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -94,27 +128,36 @@ github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5ta github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/config/config.go b/pkg/config/config.go index 5bdc13b..a9231fd 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,45 +1,34 @@ package config import ( - "encoding/json" "fmt" - "os" "os/exec" - "path/filepath" - "strings" + + "github.com/spf13/viper" ) -func LoadConfig(filename string) (*Config, error) { - // Get the root directory of the Git project +func ViperConfig() (*Config, error) { + viper.SetConfigName(".goji") + viper.SetConfigType("json") + cmd := exec.Command("git", "rev-parse", "--show-toplevel") - rootDirBytes, err := cmd.Output() + gitDirBytes, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("error finding git root directory: %v", err) + _ = fmt.Errorf("error finding git root directory: %v", err) + return nil, err } - rootDir := string(rootDirBytes) - rootDir = strings.TrimSpace(rootDir) // Remove newline character at the end + gitDir := string(gitDirBytes) + viper.AddConfigPath(gitDir) + viper.AddConfigPath("$HOME") - // Try to load the config file from the root of the Git project - configFile := filepath.Join(rootDir, filename) - data, err := os.ReadFile(configFile) + err = viper.ReadInConfig() if err != nil { - // If not found, try to load it from the home directory - homeDir, err := os.UserHomeDir() - if err != nil { - return nil, fmt.Errorf("error finding home directory: %v", err) - } - configFile = filepath.Join(homeDir, filename) - data, err = os.ReadFile(configFile) - if err != nil { - return nil, err - } + panic(fmt.Errorf("fatal error config file: %s", err)) } var config Config - err = json.Unmarshal(data, &config) - if err != nil { - return nil, err + if err := viper.Unmarshal(&config); err != nil { + fmt.Printf("unable to decode into struct, %v", err) } - return &config, nil } diff --git a/pkg/config/configInit.go b/pkg/config/configInit.go index e9feffc..c721143 100644 --- a/pkg/config/configInit.go +++ b/pkg/config/configInit.go @@ -1,12 +1,12 @@ package config import ( - "encoding/json" "fmt" "os" "os/exec" - "path/filepath" "strings" + + "github.com/spf13/viper" ) func AddCustomCommitTypes(gitmojis []Gitmoji) []Gitmoji { @@ -26,6 +26,7 @@ func AddCustomCommitTypes(gitmojis []Gitmoji) []Gitmoji { return append(gitmojis, customGitmojis...) } + func GetGitRootDir() (string, error) { gitRoot := exec.Command("git", "rev-parse", "--show-toplevel") gitDirBytes, err := gitRoot.Output() @@ -39,14 +40,31 @@ func GetGitRootDir() (string, error) { } func SaveGitmojisToFile(config initConfig, filename string, dir string) error { - configFile := filepath.Join(dir, filename) - data, err := json.MarshalIndent(config, "", " ") + viper.Set("Types", config.Types) + viper.Set("Scopes", config.Scopes) + viper.Set("Symbol", config.Symbol) + viper.Set("SkipQuestions", config.SkipQuestions) + viper.Set("SubjectMaxLength", config.SubjectMaxLength) + + viper.SetConfigName(filename) // name of config file (without extension) + viper.SetConfigType("json") // specifying the config type + viper.AddConfigPath(dir) // path to look for the config file in + + err := viper.SafeWriteConfig() if err != nil { - return err + if _, ok := err.(viper.ConfigFileAlreadyExistsError); ok { + err = viper.WriteConfig() + if err != nil { + return fmt.Errorf("error writing config file: %v", err) + } + } else { + return fmt.Errorf("error creating config file: %v", err) + } } - return os.WriteFile(configFile, data, 0644) + return nil } + func InitRepoConfig(global bool, repo bool) error { gitmojis := AddCustomCommitTypes([]Gitmoji{}) config := initConfig{ @@ -73,7 +91,7 @@ func InitRepoConfig(global bool, repo bool) error { return fmt.Errorf("no flag set for location to save configuration file") } - err = SaveGitmojisToFile(config, ".goji.json", dir) + err = SaveGitmojisToFile(config, ".goji", dir) if err != nil { return fmt.Errorf("error saving gitmojis to file: %v", err) diff --git a/pkg/config/configInit_test.go b/pkg/config/configInit_test.go index 636c49f..6f78f3a 100644 --- a/pkg/config/configInit_test.go +++ b/pkg/config/configInit_test.go @@ -7,16 +7,34 @@ import ( func TestAddCustomCommitTypes(t *testing.T) { gitmojis := AddCustomCommitTypes([]Gitmoji{}) if len(gitmojis) != 11 { - t.Errorf("Expected 11 gitmojis, got %d", len(gitmojis)) + t.Errorf("AddCustomCommitTypes() returned unexpected number of Gitmojis") } } func TestGetGitRootDir(t *testing.T) { - dir, err := GetGitRootDir() + _, err := GetGitRootDir() if err != nil { - t.Errorf("Expected no error, got %v", err) + t.Errorf("GetGitRootDir() error = %v", err) } - if dir == "" { - t.Errorf("Expected directory, got empty string") +} + +func TestSaveGitmojisToFile(t *testing.T) { + config := initConfig{ + Types: []Gitmoji{}, + Scopes: []string{"home", "accounts", "ci"}, + Symbol: true, + SkipQuestions: []string{}, + SubjectMaxLength: 50, + } + err := SaveGitmojisToFile(config, ".goji", ".") + if err != nil { + t.Errorf("SaveGitmojisToFile() error = %v", err) + } +} + +func TestInitRepoConfig(t *testing.T) { + err := InitRepoConfig(false, true) + if err != nil { + t.Errorf("InitRepoConfig() error = %v", err) } } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 19f4be2..538943d 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1,279 +1,12 @@ package config import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" "testing" - - "github.com/stretchr/testify/mock" ) -func TestLoadConfig(t *testing.T) { - cmd := exec.Command("git", "rev-parse", "--show-toplevel") - rootDirBytes, err := cmd.Output() - if err != nil { - t.Fatalf("Error finding git root directory: %v", err) - } - rootDir := string(rootDirBytes) - rootDir = strings.TrimSpace(rootDir) // Remove newline character at the end - - // Prepare a temporary configuration file for testing - filename := "test_config.json" - content := `{ - "Types": [ - { - "Emoji": "✨", - "Code": ":sparkles:", - "Description": "Introducing new features.", - "Name": "feat" - }, - { - "Emoji": "🐛", - "Code": ":bug:", - "Description": "Fixing a bug.", - "Name": "fix" - }, - { - "Emoji": "🧹", - "Code": ":broom:", - "Description": "A chore change.", - "Name": "chore" - } - ], - "Scopes": ["home", "accounts", "ci"], - "Symbol": true, - "SkipQuestions": [], - "SubjectMaxLength": 50 - } - ` - - tmpDir, err := os.MkdirTemp("", "goji-test") - if err != nil { - t.Fatalf("Failed to create temporary directory: %v", err) - } - defer os.RemoveAll(tmpDir) - // Set the temporary directory as the home directory for the test - os.Setenv("HOME", tmpDir) - defer os.Unsetenv("HOME") - - // Move the configuration file from the current directory to the temporary home directory - - testConfigPath := filepath.Join(rootDir, filename) - err = os.WriteFile(testConfigPath, []byte(content), 0644) - if err != nil { - t.Fatalf("Failed to create test config file: %v", err) - } - defer os.Remove(testConfigPath) - err = os.Rename(testConfigPath, filepath.Join(tmpDir, filename)) - if err != nil { - t.Fatalf("Failed to move test config file to the temporary home directory: %v", err) - } - - // Test the LoadConfig function - config, err := LoadConfig(filename) - if err != nil { - t.Errorf("LoadConfig failed: %v", err) - } - - if config == nil { - t.Fatal("config is nil") - } - - expectedTypeName := "feat" - if config.Types[0].Name != expectedTypeName { - t.Errorf("Expected type name %s, got %s", expectedTypeName, config.Types[0].Name) - } - expectedEmoji := "✨" - if config.Types[0].Emoji != expectedEmoji { - t.Errorf("Expected emoji %s, got %s", expectedEmoji, config.Types[0].Emoji) - } - - expectedCode := ":sparkles:" - if config.Types[0].Code != expectedCode { - t.Errorf("Expected code %s, got %s", expectedCode, config.Types[0].Code) - } - - expectedDescription := "Introducing new features." - if config.Types[0].Description != expectedDescription { - t.Errorf("Expected description %s, got %s", expectedDescription, config.Types[0].Description) - } -} - -func TestGitRootDirectory(t *testing.T) { - // Create a temporary directory for the test - tmpDir, err := os.MkdirTemp("", "git-test") - if err != nil { - t.Fatalf("Failed to create temporary directory: %v", err) - } - defer os.RemoveAll(tmpDir) - - // Initialize a Git repository in the temporary directory - cmd := exec.Command("git", "init") - cmd.Dir = tmpDir - if err := cmd.Run(); err != nil { - t.Fatalf("Failed to initialize Git repository: %v", err) - } - - // Create a subdirectory in the Git repository - subDir := filepath.Join(tmpDir, "subdir") - if err := os.Mkdir(subDir, 0755); err != nil { - t.Fatalf("Failed to create subdirectory: %v", err) - } - - // Execute the command in the subdirectory - cmd = exec.Command("git", "rev-parse", "--show-toplevel") - cmd.Dir = subDir - rootDirBytes, err := cmd.Output() - if err != nil { - t.Fatalf("Error finding git root directory: %v", err) - } - rootDir := string(rootDirBytes) - rootDir = strings.TrimSpace(rootDir) // Remove newline character at the end - - // Resolve symlinks in the paths - resolvedTmpDir, err := filepath.EvalSymlinks(tmpDir) +func TestViperConfig(t *testing.T) { + _, err := ViperConfig() if err != nil { - t.Fatalf("Failed to resolve symlinks in tmpDir: %v", err) + t.Errorf("ViperConfig() error = %v", err) } - resolvedRootDir, err := filepath.EvalSymlinks(rootDir) - if err != nil { - t.Fatalf("Failed to resolve symlinks in rootDir: %v", err) - } - - // Check if the command returned the correct repository root directory - if resolvedTmpDir != resolvedRootDir { - t.Errorf("Expected root directory: %s, got: %s", resolvedTmpDir, resolvedRootDir) - } -} -func TestLoadConfigInvalidJSON(t *testing.T) { - // Prepare a temporary configuration file with invalid JSON content - filename := "test_invalid_config.json" - content := `{ - "Types": [ - { - "Emoji": "✨", - "Code": ":sparkles:", - "Description": "Introducing new features.", - "Name": "feat", - }, // Extra comma here makes the JSON invalid - } - }` - - tmpDir, err := os.MkdirTemp("", "goji-test") - if err != nil { - t.Fatalf("Failed to create temporary directory: %v", err) - } - defer os.RemoveAll(tmpDir) - os.Setenv("HOME", tmpDir) - defer os.Unsetenv("HOME") - - testConfigPath := filepath.Join(tmpDir, filename) - err = os.WriteFile(testConfigPath, []byte(content), 0644) - if err != nil { - t.Fatalf("Failed to create test config file: %v", err) - } - - // Test the LoadConfig function with the invalid JSON file - config, err := LoadConfig(filename) - if err == nil { - t.Error("Expected an error for invalid JSON, but got no error") - } - - if config != nil { - t.Error("Expected config to be nil for invalid JSON") - } -} - -var mockedExitStatus = 1 -var mockedStdout = "" - -func TestHelperProcess(t *testing.T) { - if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { - return - } - - // Print the mocked stdout. - os.Stdout.WriteString(os.Getenv("STDOUT")) - - // Exit with the mocked exit status. - i, _ := strconv.Atoi(os.Getenv("EXIT_STATUS")) - os.Exit(i) -} - -func fakeExecCommand(command string, args ...string) *exec.Cmd { - cs := []string{"-test.run=TestHelperProcess", "--", command} - cs = append(cs, args...) - cmd := exec.Command(os.Args[0], cs...) - cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1", - "STDOUT=" + mockedStdout, - "EXIT_STATUS=" + strconv.Itoa(mockedExitStatus)} - return cmd -} - -var execCommand = exec.Command - -func TestLoadConfig_Failure(t *testing.T) { - // Replace the exec.Command function with the mock version. - execCommand = fakeExecCommand - defer func() { execCommand = exec.Command }() - - _, err := LoadConfig("config.json") - if err == nil { - t.Errorf("Expected error, but got nil") - } -} - -// Define interfaces for os and exec -type OS interface { - ReadFile(filename string) ([]byte, error) -} - -type Exec interface { - Command(name string, arg ...string) *exec.Cmd -} - -// Create mock types for the interfaces -type MockOS struct { - mock.Mock -} - -func (m *MockOS) ReadFile(filename string) ([]byte, error) { - args := m.Called(filename) - return args.Get(0).([]byte), args.Error(1) -} - -type MockExec struct { - mock.Mock -} - -func (m *MockExec) Command(name string, arg ...string) *exec.Cmd { - args := m.Called(name, arg) - return args.Get(0).(*exec.Cmd) -} -func TestLoadConfig_Failure1(t *testing.T) { - // Create a temporary directory for the test - tmpDir, err := os.MkdirTemp("", "test") - if err != nil { - t.Fatal(err) - } - - // Delete the temporary directory after the test - defer os.RemoveAll(tmpDir) - - // Change the working directory to the temporary directory - err = os.Chdir(tmpDir) - if err != nil { - fmt.Println("Error while changing working directory to the temporary directory:", err) - return - } - // Try to load a non-existent config file - _, err = LoadConfig("non_existent_file.json") - if err == nil { - t.Errorf("Expected error, got nil") - } - } diff --git a/pkg/utils/askQuestions.go b/pkg/utils/askQuestions.go index a251fe5..462e65c 100644 --- a/pkg/utils/askQuestions.go +++ b/pkg/utils/askQuestions.go @@ -30,6 +30,8 @@ func AskQuestions(config *config.Config) (string, error) { if !isInSkipQuestions("Scopes", config.SkipQuestions) { promptScope := huh.NewInput(). Title("What is the scope of this change? (class or file name): (press [enter] to skip)"). + CharLimit(50). + Placeholder("Example: ci, api, parser"). Value(&commitScope) err = promptScope.Run() @@ -38,9 +40,10 @@ func AskQuestions(config *config.Config) (string, error) { } } - promptSubject := huh.NewText(). + promptSubject := huh.NewInput(). Title("Write a short and imperative summary of the code changes: (lower case and no period)"). CharLimit(100). + Placeholder("Short description of your commit"). Value(&commitSubject) err = promptSubject.Run() diff --git a/pkg/utils/askQuestions_test.go b/pkg/utils/askQuestions_test.go new file mode 100644 index 0000000..d4b585b --- /dev/null +++ b/pkg/utils/askQuestions_test.go @@ -0,0 +1 @@ +package utils