Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return an empty array from ValueWithShadows if there is none #313

Merged
merged 7 commits into from Jan 20, 2022
3 changes: 3 additions & 0 deletions .editorconfig
Expand Up @@ -7,3 +7,6 @@ charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*_test.go]
trim_trailing_whitespace = false
unknwon marked this conversation as resolved.
Show resolved Hide resolved
16 changes: 15 additions & 1 deletion file.go
Expand Up @@ -442,7 +442,21 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) {
kname = `"""` + kname + `"""`
}

for _, val := range key.ValueWithShadows() {
shadows := key.ValueWithShadows()
if len(shadows) == 0 {
if _, err := buf.WriteString(kname); err != nil {
return nil, err
}
// Write out alignment spaces before "=" sign
if PrettyFormat {
buf.Write(alignSpaces[:alignLength-len(kname)])
}
if _, err := buf.WriteString(equalSign + LineBreak); err != nil {
return nil, err
}
}

for _, val := range shadows {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this block is missing many handlings from where it is copied from (below).

We should either make this loop (starts on line 459) body to be an inline function .e.g writeKey := func(k *Key) error {...}, or do something like:

keys := make([]*Key, 1, len(shadows)+1)
keys[0] = key
keys = append(keys, shadows)
for _, val := range keys {
	...

But the latter is obviously more expensive IMO (due to allocations).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see what handlings are missing, the value check don't have any meaning since it is in a case where the key has no associated value, and I imagine a boolean key has a value so it wouldn't pass the condition and be handled in the loop like before, am I missing something ?
Anyways I am not a fan of the duplicated code like I did, I do prefer the first solution you proposed (partly because I don't really get how the second one would work) do you really prefer the function to be inline ? If so why ? (Not that I really have anything against it, I am just curious)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I see codecov is not happy with my patches, is it something I should care about ? (go test -cover gives a different code coverage value from codecov)

Copy link
Member

@unknwon unknwon Jan 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see what handlings are missing, the value check don't have any meaning since it is in a case where the key has no associated value, and I imagine a boolean key has a value so it wouldn't pass the condition and be handled in the loop like before, am I missing something ?

Ah, you're right. So alternatively, you could add a code commend explaining why we don't need to deal with values here.

But since we can factor out a function, I think having a unified logic with an inline function is relatively more robust (if anything changes to the key name handling).

(partly because I don't really get how the second one would work)

Hmm, that was for illustration mostly, on a second look I also forgot how it should work 😅 so forgot about it.

do you really prefer the function to be inline ? If so why ? (Not that I really have anything against it, I am just curious)

Yes, because I don't a reason why it shouldn't be inlined. It is only used here and never meant to be used outside, and the function body is also pretty sophisticated.

Copy link
Member

@unknwon unknwon Jan 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I see codecov is not happy with my patches, is it something I should care about ? (go test -cover gives a different code coverage value from codecov)

Yeah... the difference is annoying, CodeCov is more FYI, don't need to worry much unless diff coverage is 0 🤫.

if _, err := buf.WriteString(kname); err != nil {
return nil, err
}
Expand Down
3 changes: 3 additions & 0 deletions key.go
Expand Up @@ -113,6 +113,9 @@ func (k *Key) Value() string {
// ValueWithShadows returns raw values of key and its shadows if any.
func (k *Key) ValueWithShadows() []string {
if len(k.shadows) == 0 {
if k.value == "" {
return []string{}
}
return []string{k.value}
}
vals := make([]string, len(k.shadows)+1)
Expand Down
19 changes: 19 additions & 0 deletions key_test.go
Expand Up @@ -521,6 +521,25 @@ func TestKey_Helpers(t *testing.T) {
})
}

func TestKey_ValueWithShadows(t *testing.T) {
t.Run("", func(t *testing.T) {
f, err := ShadowLoad([]byte(`
keyName = value1
keyName = value2
`))
require.NoError(t, err)
require.NotNil(t, f)

k := f.Section("").Key("FakeKey")
require.NotNil(t, k)
assert.Equal(t, []string{}, k.ValueWithShadows())

k = f.Section("").Key("keyName")
require.NotNil(t, k)
assert.Equal(t, []string{"value1", "value2"}, k.ValueWithShadows())
})
}

func TestKey_StringsWithShadows(t *testing.T) {
t.Run("get strings of shadows of a key", func(t *testing.T) {
f, err := ShadowLoad([]byte(""))
Expand Down