Skip to content

Commit

Permalink
misc: rename rivertags packages to syntaxtags
Browse files Browse the repository at this point in the history
This commit renames rivertags packages to syntaxtags, and replaces as
many references of "River" to "syntax" or "Alloy syntax" as possible.

This is a safe change for syntax/internal/rivertags as it is an internal
package and cannot be imported from the top-level module.

The tag names themselves have not yet changed, so those are left
untouched.
  • Loading branch information
rfratto committed Mar 1, 2024
1 parent 50fcb6f commit 121c136
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package rivertags exposes an Analyzer which lints river tags.
package rivertags
// Package syntaxtags exposes an Analyzer which lints Alloy syntax tags.
package syntaxtags

import (
"fmt"
Expand All @@ -12,17 +12,17 @@ import (
)

var Analyzer = &analysis.Analyzer{
Name: "rivertags",
Doc: "perform validation checks on River tags",
Name: "syntaxtags",
Doc: "perform validation checks on Alloy syntax tags",
Run: run,
}

var noLintRegex = regexp.MustCompile(`//\s*nolint:(\S+)`)

var (
riverTagRegex = regexp.MustCompile(`river:"([^"]*)"`)
jsonTagRegex = regexp.MustCompile(`json:"([^"]*)"`)
yamlTagRegex = regexp.MustCompile(`yaml:"([^"]*)"`)
syntaxTagRegex = regexp.MustCompile(`river:"([^"]*)"`)
jsonTagRegex = regexp.MustCompile(`json:"([^"]*)"`)
yamlTagRegex = regexp.MustCompile(`yaml:"([^"]*)"`)
)

// Rules for river tag linting:
Expand Down Expand Up @@ -53,12 +53,12 @@ func run(p *analysis.Pass) (interface{}, error) {
sNode := sInfo.Node
s := sInfo.Type

var hasRiverTags bool
var hasSyntaxTags bool

for i := 0; i < s.NumFields(); i++ {
matches := riverTagRegex.FindAllStringSubmatch(s.Tag(i), -1)
matches := syntaxTagRegex.FindAllStringSubmatch(s.Tag(i), -1)
if len(matches) > 0 {
hasRiverTags = true
hasSyntaxTags = true
break
}
}
Expand All @@ -68,7 +68,7 @@ func run(p *analysis.Pass) (interface{}, error) {
field := s.Field(i)
nodeField := lookupField(sNode, i)

// Ignore fields with //nolint:rivertags in them.
// Ignore fields with //nolint:syntaxtags in them.
if comments := nodeField.Comment; comments != nil {
for _, comment := range comments.List {
if lintingDisabled(comment.Text) {
Expand All @@ -77,8 +77,8 @@ func run(p *analysis.Pass) (interface{}, error) {
}
}

matches := riverTagRegex.FindAllStringSubmatch(s.Tag(i), -1)
if len(matches) == 0 && hasRiverTags {
matches := syntaxTagRegex.FindAllStringSubmatch(s.Tag(i), -1)
if len(matches) == 0 && hasSyntaxTags {
// If this struct has River tags, but this field only has json/yaml
// tags, emit an error.
jsonMatches := jsonTagRegex.FindAllStringSubmatch(s.Tag(i), -1)
Expand All @@ -87,7 +87,7 @@ func run(p *analysis.Pass) (interface{}, error) {
if len(jsonMatches) > 0 || len(yamlMatches) > 0 {
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: "field has yaml or json tags, but no river tags",
})
}
Expand All @@ -98,7 +98,7 @@ func run(p *analysis.Pass) (interface{}, error) {
} else if len(matches) > 1 {
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: "field should not have more than one river tag",
})
}
Expand All @@ -107,32 +107,32 @@ func run(p *analysis.Pass) (interface{}, error) {
if field.Anonymous() {
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: "river tags may not be given to anonymous fields",
})
}
if !field.Exported() {
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: "river tags may only be given to exported fields",
})
}
if len(nodeField.Names) > 1 {
// Report "a, b, c int `river:"name,attr"`" as invalid usage.
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: "river tags should not be inserted on field names separated by commas",
})
}

for _, match := range matches {
diagnostics := lintRiverTag(field, match[1])
diagnostics := lintSyntaxTag(field, match[1])
for _, diag := range diagnostics {
p.Report(analysis.Diagnostic{
Pos: field.Pos(),
Category: "rivertags",
Category: "syntaxtags",
Message: diag,
})
}
Expand All @@ -149,7 +149,7 @@ func lintingDisabled(comment string) bool {
for _, match := range matches {
// Iterate over A,B,C by comma and see if our linter is included.
for _, disabledLinter := range strings.Split(match[1], ",") {
if disabledLinter == "rivertags" {
if disabledLinter == "syntaxtags" {
return true
}
}
Expand Down Expand Up @@ -216,7 +216,7 @@ type structInfo struct {
Type *types.Struct
}

func lintRiverTag(ty *types.Var, tag string) (diagnostics []string) {
func lintSyntaxTag(ty *types.Var, tag string) (diagnostics []string) {
if tag == "" {
diagnostics = append(diagnostics, "river tag should not be empty")
return
Expand Down Expand Up @@ -319,7 +319,7 @@ var fieldNameRegex = regexp.MustCompile("^[a-z][a-z0-9_]*$")

func validateFieldName(name string) (diagnostics []string) {
if !fieldNameRegex.MatchString(name) {
msg := fmt.Sprintf("%q must be a valid river snake_case identifier", name)
msg := fmt.Sprintf("%q must be a valid syntax snake_case identifier", name)
diagnostics = append(diagnostics, msg)
}

Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/agentlint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ package main

import (
"github.com/grafana/agent/internal/cmd/agentlint/internal/findcomponents"
"github.com/grafana/agent/internal/cmd/agentlint/internal/rivertags"
"github.com/grafana/agent/internal/cmd/agentlint/internal/syntaxtags"
"golang.org/x/tools/go/analysis/multichecker"
)

func main() {
multichecker.Main(
findcomponents.Analyzer,
rivertags.Analyzer,
syntaxtags.Analyzer,
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Package rivertags decodes a struct type into river object
// and structural tags.
package rivertags
// Package syntaxtags decodes a struct type into syntax object and structural
// tags.
package syntaxtags

import (
"fmt"
Expand Down Expand Up @@ -159,7 +159,7 @@ func Get(ty reflect.Type) []Field {
)

for _, field := range reflect.VisibleFields(ty) {
// River does not support embedding of fields
// Alloy's syntax does not support embedding of fields
if field.Anonymous {
panic(fmt.Sprintf("syntax: anonymous fields not supported %s", printPathToField(ty, field.Index)))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package rivertags_test
package syntaxtags_test

import (
"reflect"
"testing"

"github.com/grafana/river/internal/rivertags"
"github.com/grafana/river/internal/syntaxtags"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -22,16 +22,16 @@ func Test_Get(t *testing.T) {
Label string `river:",label"`
}

fs := rivertags.Get(reflect.TypeOf(Struct{}))
fs := syntaxtags.Get(reflect.TypeOf(Struct{}))

expect := []rivertags.Field{
{[]string{"req_attr"}, []int{1}, rivertags.FlagAttr},
{[]string{"opt_attr"}, []int{2}, rivertags.FlagAttr | rivertags.FlagOptional},
{[]string{"req_block"}, []int{3}, rivertags.FlagBlock},
{[]string{"opt_block"}, []int{4}, rivertags.FlagBlock | rivertags.FlagOptional},
{[]string{"req_enum"}, []int{5}, rivertags.FlagEnum},
{[]string{"opt_enum"}, []int{6}, rivertags.FlagEnum | rivertags.FlagOptional},
{[]string{""}, []int{7}, rivertags.FlagLabel},
expect := []syntaxtags.Field{
{[]string{"req_attr"}, []int{1}, syntaxtags.FlagAttr},
{[]string{"opt_attr"}, []int{2}, syntaxtags.FlagAttr | syntaxtags.FlagOptional},
{[]string{"req_block"}, []int{3}, syntaxtags.FlagBlock},
{[]string{"opt_block"}, []int{4}, syntaxtags.FlagBlock | syntaxtags.FlagOptional},
{[]string{"req_enum"}, []int{5}, syntaxtags.FlagEnum},
{[]string{"opt_enum"}, []int{6}, syntaxtags.FlagEnum | syntaxtags.FlagOptional},
{[]string{""}, []int{7}, syntaxtags.FlagLabel},
}

require.Equal(t, expect, fs)
Expand All @@ -48,7 +48,7 @@ func TestEmbedded(t *testing.T) {
InnerStruct
Field2 string `river:"parent_field_2,attr"`
}
require.PanicsWithValue(t, "river: anonymous fields not supported rivertags_test.Struct.InnerStruct", func() { rivertags.Get(reflect.TypeOf(Struct{})) })
require.PanicsWithValue(t, "river: anonymous fields not supported syntaxtags_test.Struct.InnerStruct", func() { syntaxtags.Get(reflect.TypeOf(Struct{})) })
}

func TestSquash(t *testing.T) {
Expand All @@ -69,33 +69,33 @@ func TestSquash(t *testing.T) {
Field2 string `river:"parent_field_2,attr"`
}

expect := []rivertags.Field{
expect := []syntaxtags.Field{
{
Name: []string{"parent_field_1"},
Index: []int{0},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
{
Name: []string{"inner_field_1"},
Index: []int{1, 0},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
{
Name: []string{"inner_field_2"},
Index: []int{1, 1},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
{
Name: []string{"parent_field_2"},
Index: []int{2},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
}

structActual := rivertags.Get(reflect.TypeOf(Struct{}))
structActual := syntaxtags.Get(reflect.TypeOf(Struct{}))
assert.Equal(t, expect, structActual)

structPointerActual := rivertags.Get(reflect.TypeOf(StructWithPointer{}))
structPointerActual := syntaxtags.Get(reflect.TypeOf(StructWithPointer{}))
assert.Equal(t, expect, structPointerActual)
}

Expand All @@ -113,61 +113,61 @@ func TestDeepSquash(t *testing.T) {
Inner InnerStruct `river:",squash"`
}

expect := []rivertags.Field{
expect := []syntaxtags.Field{
{
Name: []string{"inner_field_1"},
Index: []int{0, 0, 0},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
{
Name: []string{"inner_field_2"},
Index: []int{0, 0, 1},
Flags: rivertags.FlagAttr,
Flags: syntaxtags.FlagAttr,
},
}

structActual := rivertags.Get(reflect.TypeOf(Struct{}))
structActual := syntaxtags.Get(reflect.TypeOf(Struct{}))
assert.Equal(t, expect, structActual)
}

func Test_Get_Panics(t *testing.T) {
expectPanic := func(t *testing.T, expect string, v interface{}) {
t.Helper()
require.PanicsWithValue(t, expect, func() {
_ = rivertags.Get(reflect.TypeOf(v))
_ = syntaxtags.Get(reflect.TypeOf(v))
})
}

t.Run("Tagged fields must be exported", func(t *testing.T) {
type Struct struct {
attr string `river:"field,attr"` // nolint:unused //nolint:rivertags
attr string `river:"field,attr"` // nolint:unused //nolint:syntaxtags
}
expect := `river: river tag found on unexported field at rivertags_test.Struct.attr`
expect := `river: river tag found on unexported field at syntaxtags_test.Struct.attr`
expectPanic(t, expect, Struct{})
})

t.Run("Options are required", func(t *testing.T) {
type Struct struct {
Attr string `river:"field"` //nolint:rivertags
Attr string `river:"field"` //nolint:syntaxtags
}
expect := `river: field rivertags_test.Struct.Attr tag is missing options`
expect := `river: field syntaxtags_test.Struct.Attr tag is missing options`
expectPanic(t, expect, Struct{})
})

t.Run("Field names must be unique", func(t *testing.T) {
type Struct struct {
Attr string `river:"field1,attr"`
Block string `river:"field1,block,optional"` //nolint:rivertags
Block string `river:"field1,block,optional"` //nolint:syntaxtags
}
expect := `river: field name field1 already used by rivertags_test.Struct.Attr`
expect := `river: field name field1 already used by syntaxtags_test.Struct.Attr`
expectPanic(t, expect, Struct{})
})

t.Run("Name is required for non-label field", func(t *testing.T) {
type Struct struct {
Attr string `river:",attr"` //nolint:rivertags
Attr string `river:",attr"` //nolint:syntaxtags
}
expect := `river: non-empty field name required at rivertags_test.Struct.Attr`
expect := `river: non-empty field name required at syntaxtags_test.Struct.Attr`
expectPanic(t, expect, Struct{})
})

Expand All @@ -176,7 +176,7 @@ func Test_Get_Panics(t *testing.T) {
Label1 string `river:",label"`
Label2 string `river:",label"`
}
expect := `river: label field already used by rivertags_test.Struct.Label2`
expect := `river: label field already used by syntaxtags_test.Struct.Label2`
expectPanic(t, expect, Struct{})
})
}

0 comments on commit 121c136

Please sign in to comment.