Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 4 additions & 20 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/spf13/cobra"

"github.com/dotzero/git-profile/internal/config"
"github.com/dotzero/git-profile/internal/ui"
)

Expand Down Expand Up @@ -112,22 +111,17 @@ func profileUpdateEntries(
}

if entries, ok := cfg.Lookup(profile); ok {
values := entriesToMap(entries)
formData.UserName = values[userNameKey]
formData.UserEmail = values[userEmailKey]
formData.UserSigningKey = values[userSigningKeyKey]
formData.UserName = entries[userNameKey]
formData.UserEmail = entries[userEmailKey]
formData.UserSigningKey = entries[userSigningKeyKey]
}

result, err := editProfileFields(formData, cmd.InOrStdin(), cmd.OutOrStdout())
if err != nil {
return err
}

currentValues := map[string]string{}
if entries, ok := cfg.Lookup(result.Profile); ok {
currentValues = entriesToMap(entries)
}

currentValues, _ := cfg.Lookup(result.Profile)
changed := 0

values := map[string]string{
Expand Down Expand Up @@ -165,13 +159,3 @@ func profileUpdateEntries(

return nil
}

func entriesToMap(entries []config.Entry) map[string]string {
values := make(map[string]string, len(entries))

for _, entry := range entries {
values[entry.Key] = entry.Value
}

return values
}
16 changes: 8 additions & 8 deletions cmd/add_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ func TestAddInteractiveStoresOnlyChangedFilledValues(t *testing.T) {
is := is.New(t)

cfg := &storageMock{
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: userNameKey, Value: "Jane Doe"},
{Key: userEmailKey, Value: "old@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
userNameKey: "Jane Doe",
userEmailKey: "old@example.com",
}, true
},
SaveFunc: func(filename string) error {
Expand Down Expand Up @@ -105,10 +105,10 @@ func TestAddInteractiveSkipsSaveWhenNothingChanged(t *testing.T) {
is := is.New(t)

cfg := &storageMock{
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: userNameKey, Value: "Jane Doe"},
{Key: userEmailKey, Value: "work@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
userNameKey: "Jane Doe",
userEmailKey: "work@example.com",
}, true
},
SaveFunc: func(filename string) error {
Expand Down
8 changes: 4 additions & 4 deletions cmd/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ func TestExport(t *testing.T) {
is := is.New(t)

cfg := &storageMock{
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: "user.email", Value: "work@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
"user.email": "work@example.com",
}, true
},
}
Expand All @@ -29,5 +29,5 @@ func TestExport(t *testing.T) {
err := cmd.Execute()

is.NoErr(err)
is.Equal(trim(b.String()), `[{"key":"user.email","value":"work@example.com"}]`)
is.Equal(trim(b.String()), `{"user.email":"work@example.com"}`)
}
22 changes: 16 additions & 6 deletions cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"

"github.com/dotzero/git-profile/internal/config"
"github.com/dotzero/git-profile/internal/oldconfig"
"github.com/dotzero/git-profile/internal/ui"
)

Expand All @@ -18,21 +19,30 @@ func Import(cfg storage) *cobra.Command {
Short: "Import a profile",
Long: "Import a profile from JSON.",
Args: cobra.ExactArgs(2),
Example: `git-profile import my-profile '[{"key":"user.email","value":"work@example.com"}]'`,
Example: `git-profile import my-profile '{"user.email":"work@example.com"}'`,
Run: func(cmd *cobra.Command, args []string) {
profile := args[0]
filename, _ := cmd.Flags().GetString("config")

var entries []config.Entry
var entries config.Entry

err := json.Unmarshal([]byte(args[1]), &entries)
if err != nil {
ui.PrintErrln(cmd, ui.ErrorStyle, "Unable to decode profile values: %s", err)
os.Exit(1)
// Try to unmarshal as old format (array)
var oldEntries []oldconfig.OldEntry
errOld := json.Unmarshal([]byte(args[1]), &oldEntries)
if errOld != nil {
ui.PrintErrln(cmd, ui.ErrorStyle, "Unable to decode profile values: %s", err)
os.Exit(1)
}
entries = make(config.Entry)
for _, entry := range oldEntries {
entries[entry.Key] = entry.Value
}
}

for _, entry := range entries {
cfg.Store(profile, entry.Key, entry.Value)
for key, val := range entries {
cfg.Store(profile, key, val)
}

err = cfg.Save(filename)
Expand Down
64 changes: 50 additions & 14 deletions cmd/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,59 @@ import (
)

func TestImport(t *testing.T) {
is := is.New(t)
t.Run("map format", func(t *testing.T) {
is := is.New(t)

cfg := &storageMock{
SaveFunc: func(filename string) error {
return nil
},
StoreFunc: func(profile string, key string, value string) {},
}
stored := make(map[string]string)
cfg := &storageMock{
SaveFunc: func(filename string) error {
return nil
},
StoreFunc: func(profile string, key string, value string) {
is.Equal(profile, "profile")
stored[key] = value
},
}

var b bytes.Buffer
var b bytes.Buffer
cmd := Import(cfg)
cmd.SetOut(&b)
cmd.SetArgs([]string{"profile", `{"user.email": "work@example.com", "core.autocrlf": "input"}`})
err := cmd.Execute()

cmd := Import(cfg)
is.NoErr(err)
is.Equal(trim(b.String()), "Successfully imported `profile` profile.")
is.Equal(stored, map[string]string{
"user.email": "work@example.com",
"core.autocrlf": "input",
})
})

cmd.SetOut(&b)
cmd.SetArgs([]string{"profile", `[{"key":"user.email","value":"work@example.com"}]`})
err := cmd.Execute()
t.Run("array format", func(t *testing.T) {
is := is.New(t)

is.NoErr(err)
is.Equal(trim(b.String()), "Successfully imported `profile` profile.")
stored := make(map[string]string)
cfg := &storageMock{
SaveFunc: func(filename string) error {
return nil
},
StoreFunc: func(profile string, key string, value string) {
is.Equal(profile, "profile")
stored[key] = value
},
}

var b bytes.Buffer
cmd := Import(cfg)
cmd.SetOut(&b)
cmd.SetArgs([]string{"profile", `[{"key": "user.email", "value": "work@example.com"}, {"key": "core.autocrlf", "value": "input"}]`})
err := cmd.Execute()

is.NoErr(err)
is.Equal(trim(b.String()), "Successfully imported `profile` profile.")
is.Equal(stored, map[string]string{
"user.email": "work@example.com",
"core.autocrlf": "input",
})
})
}
2 changes: 1 addition & 1 deletion cmd/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

type storage interface {
Len() int
Lookup(name string) ([]config.Entry, bool)
Lookup(name string) (config.Entry, bool)
Names() []string
Delete(profile string, value string) bool
DeleteProfile(profile string) bool
Expand Down
11 changes: 9 additions & 2 deletions cmd/list.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"sort"

"github.com/spf13/cobra"

"github.com/dotzero/git-profile/internal/ui"
Expand All @@ -23,8 +25,13 @@ func List(cfg storage, v vcs) *cobra.Command {
ui.Println(cmd, ui.SuccessStyle, "- %s:", name)

profile, _ := cfg.Lookup(name)
for _, entry := range profile {
ui.Println(cmd, ui.DefaultStyle, " %s: %s", entry.Key, entry.Value)
keys := make([]string, 0, len(profile))
for key := range profile {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
ui.Println(cmd, ui.DefaultStyle, " %s: %s", key, profile[key])
}
}
},
Expand Down
9 changes: 5 additions & 4 deletions cmd/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ func TestList(t *testing.T) {
NamesFunc: func() []string {
return []string{"home"}
},
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: "user.email", Value: "work@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
"user.email": "work@example.com",
"core.autocrlf": "input",
}, true
},
}
Expand All @@ -43,5 +44,5 @@ func TestList(t *testing.T) {
err := cmd.Execute()

is.NoErr(err)
is.Equal(trim(b.String()), "Available profiles:\n- home:\n user.email: work@example.com")
is.Equal(trim(b.String()), "Available profiles:\n- home:\n core.autocrlf: input\n user.email: work@example.com")
}
6 changes: 3 additions & 3 deletions cmd/mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions cmd/unuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ func profileUnapply(cmd *cobra.Command, cfg storage, v vcs, profile string) {
os.Exit(0)
}

for _, entry := range entries {
err := v.Unset(entry.Key)
for key := range entries {
err := v.Unset(key)
if err != nil {
ui.PrintErrln(cmd, ui.ErrorStyle, "Unable to interact with git to remove current profile: %s", err)
os.Exit(1)
Expand Down
15 changes: 11 additions & 4 deletions cmd/unuse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"bytes"
"fmt"
"sort"
"testing"

"github.com/matryer/is"
Expand All @@ -17,9 +18,10 @@ func TestUnuse(t *testing.T) {
LenFunc: func() int {
return 1
},
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: "user.email", Value: "work@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
"user.email": "work@example.com",
"core.autocrlf": "input",
}, true
},
}
Expand All @@ -46,7 +48,12 @@ func TestUnuse(t *testing.T) {

is.NoErr(err)
is.Equal(trim(b.String()), "Successfully removed `profile` profile from current git repository.")
is.Equal(unset, []string{"user.email", currentProfileKey})
is.Equal(len(unset), 3)
is.Equal(unset[2], currentProfileKey)

keys := unset[:2]
sort.Strings(keys)
is.Equal(keys, []string{"core.autocrlf", "user.email"})
}

func TestUnuseProfileResolveArg(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/use.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ func profileApply(cmd *cobra.Command, cfg storage, v vcs, profile string) {
os.Exit(1)
}

for _, entry := range entries {
err := v.Set(entry.Key, entry.Value)
for key, value := range entries {
err := v.Set(key, value)
if err != nil {
ui.PrintErrln(cmd, ui.ErrorStyle, "Unable to interact with git to store current profile: %s", err)
os.Exit(1)
Expand Down
14 changes: 11 additions & 3 deletions cmd/use_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ func TestUse(t *testing.T) {
LenFunc: func() int {
return 1
},
LookupFunc: func(name string) ([]config.Entry, bool) {
return []config.Entry{
{Key: "user.email", Value: "work@example.com"},
LookupFunc: func(name string) (config.Entry, bool) {
return config.Entry{
"user.email": "work@example.com",
"core.autocrlf": "input",
}, true
},
}

setParams := make(map[string]string)
vcs := &vcsMock{
IsRepositoryFunc: func() bool {
return true
},
SetFunc: func(key string, value string) error {
setParams[key] = value
return nil
},
}
Expand All @@ -44,6 +47,11 @@ func TestUse(t *testing.T) {

is.NoErr(err)
is.Equal(trim(b.String()), "Successfully applied `profile` profile to current git repository.")
is.Equal(setParams, map[string]string{
"current-profile.name": "profile",
"user.email": "work@example.com",
"core.autocrlf": "input",
})
}

func TestProfileResolveInteractive(t *testing.T) {
Expand Down
Loading