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

tagliatelle now warns on inline struct fields #8

Closed
silverlyra opened this issue Jan 25, 2022 · 9 comments · Fixed by #9
Closed

tagliatelle now warns on inline struct fields #8

silverlyra opened this issue Jan 25, 2022 · 9 comments · Fixed by #9
Labels
bug Something isn't working

Comments

@silverlyra
Copy link
Contributor

Since 7b21925, structs with json:",inline" fields now prompt a warning from tagliatelle that a name should be given in the expected camelCase.

I think this is incorrect behavior as there is no field name for an inline struct.

silverlyra added a commit to silverlyra/tagliatelle that referenced this issue Jan 25, 2022
@ldez
Copy link
Owner

ldez commented Jan 25, 2022

Hello,

currently, tagliatelle is format neutral, so inline is not interpreted.

I need to think about how to about that.

Ref: #6

@ldez
Copy link
Owner

ldez commented Jan 25, 2022

I see your PR, it's an opinionated approach because it's not following a neutral format.

@silverlyra
Copy link
Contributor Author

Hi,

currently, tagliatelle is format neutral, so inline is not interpreted.

I understand where you’re coming from. The latest tagliatelle is included in the latest golanglint-ci, so all projects that use golanglint-ci, have tagliatelle enabled, and use json:",inline" fields are now going to have false positive lint errors.

This package already can’t process xml struct tags correctly, as that can encode parent tags like xml:"child>plant". I'd recommend moving away from this format-neutral approach. I'll roll back the golanglint-ci version we're using for now, but a fix is needed here.

@ldez
Copy link
Owner

ldez commented Jan 25, 2022

I'd recommend moving away from this format-neutral approach.

It's a bit more complex: currently, you can define any struct tag, so it must be "neutral" or at least configurable.

This package already can’t process xml struct tags correctly,

This is interesting, maybe you can open another issue on this topic.

@silverlyra
Copy link
Contributor Author

silverlyra commented Jan 25, 2022

This package already can’t process xml struct tags correctly,

This is interesting, maybe you can open another issue on this topic.

It's not an issue that affects me directly. I'm saying that, while you've been thinking tagliatelle is format-neutral, I think it’s actually only compatible with struct tags that are compatible with json tags. So I don't think scanning for ,inline is as big of a departure from the current behavior as you do.

@ldez
Copy link
Owner

ldez commented Jan 25, 2022

a small note:

https://go.dev/play/p/GqQtABzKMmK

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"testing"
)

type Foo struct {
	Bar Bar `json:",inline"`
}

type Bar struct {
	Name string `json:"name"`
}

func TestName(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(json.NewEncoder(os.Stdout).Encode(f))
}
// {"Bar":{"name":"goo"}}
// <nil>

https://go.dev/play/p/oAhZPIAD8n9

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"testing"
)

type Foo struct {
	Bar `json:",inline"`
}

type Bar struct {
	Name string `json:"name"`
}

func TestName(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(json.NewEncoder(os.Stdout).Encode(f))
}

// {"name":"goo"}
// <nil>

🤔 the yaml parser doesn't have the same behavior as json with inline.

https://go.dev/play/p/0_GnAfICLTu

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"testing"

	yamlv2 "gopkg.in/yaml.v2"
	yamlv3 "gopkg.in/yaml.v3"
)

type Foo struct {
	Bar Bar `json:",inline" yaml:",inline"`
}

type Bar struct {
	Name string `json:"name" yaml:"name"`
}

func TestJSON(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(json.NewEncoder(os.Stdout).Encode(f))
}

func TestYAMLv2(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(yamlv2.NewEncoder(os.Stdout).Encode(f))
}

func TestYAMLv3(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(yamlv3.NewEncoder(os.Stdout).Encode(f))
}

@ldez
Copy link
Owner

ldez commented Jan 25, 2022

So I'm not happy with this decision but I will follow you.

In the future, I will rewrite tagliatelle to handle tag with a less neutral approach.

FYI I'm also a maintainer of golangci-lint.

@ldez ldez added the bug Something isn't working label Jan 25, 2022
@ldez ldez closed this as completed in #9 Jan 25, 2022
@ldez
Copy link
Owner

ldez commented Jan 25, 2022

After more research, in fact, inline is not supported by the json encoder.

The "inline" effect is produced by the empty value and an embedded field.

https://go.dev/play/p/X7GB3rBC5fh

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"testing"
)

type Foo struct {
	Bar `json:""`
}

type Bar struct {
	Name string `json:"name"`
}

func TestJSON(t *testing.T) {
	f := &Foo{Bar: Bar{Name: "goo"}}
	fmt.Println(json.NewEncoder(os.Stdout).Encode(f))
}

But inline inside the json tag is used by YAML encoder...

The encoders don't follow the same specification but they overuse the json tags... 😢

@seaneagan
Copy link

seaneagan commented May 11, 2023

here's the workarond that I'm currently using in my .golangci.yml:

issues:
  exclude-rules:
    # Workaround: https://github.com/ldez/tagliatelle/issues/8
    - source: \`json:"(,inline)?"
      linters:
        - tagliatelle

ideally it should also check that it is attached to a struct embedding and not a field declaration but this got me by

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants