Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/rare-carrots-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---

---

Consolidate on go.yaml.in/yaml/v3
2 changes: 1 addition & 1 deletion auth/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package auth
import (
"io"

"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v3"
)

type FileBasedKeyProvider struct {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ require (
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.28.0
go.uber.org/zap/exp v0.3.0
go.yaml.in/yaml/v3 v3.0.4
golang.org/x/exp v0.0.0-20260603202125-055de637280b
golang.org/x/mod v0.38.0
golang.org/x/sys v0.47.0
Expand Down Expand Up @@ -90,7 +91,6 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.53.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sync v0.22.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ github.com/lithammer/shortuuid/v4 v4.2.0 h1:LMFOzVB3996a7b8aBuEXxqOBflbfPQAiVzkI
github.com/lithammer/shortuuid/v4 v4.2.0/go.mod h1:D5noHZ2oFw/YaKCfGy0YxyE7M0wMbezmMjPdhyEFe6Y=
github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5ATTo469PQPkqzdoU7be46ryiCDO3boc=
github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ=
github.com/livekit/psrpc v0.7.2 h1:6oZ+NODJ2pLyaT6VqDq1F4Qc/3TpDUSpyphj/P9MhQc=
github.com/livekit/psrpc v0.7.2/go.mod h1:rAI+m2+/cb4x9RXhLRtUx5ZwdfjjXOl4zi46IjEetaw=
github.com/livekit/psrpc v0.7.3 h1:bekuZt/ZQzg8+/M8G6G5jq7bvV9fAKdPHSOZeTwrIIc=
github.com/livekit/psrpc v0.7.3/go.mod h1:rAI+m2+/cb4x9RXhLRtUx5ZwdfjjXOl4zi46IjEetaw=
github.com/mackerelio/go-osstat v0.2.8 h1:I2duicTaCGWoM53XwAwA9OIe1inu0xnVs8/pqOWWVr4=
Expand Down
55 changes: 30 additions & 25 deletions livekit/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import (
"buf.build/go/protoyaml"
"github.com/dennwc/iters"
"go.opentelemetry.io/otel/attribute"
"go.yaml.in/yaml/v3"
proto "google.golang.org/protobuf/proto"
"gopkg.in/yaml.v3"
)

const (
Expand Down Expand Up @@ -139,48 +139,53 @@ type Guid interface {

type GuidBlock [9]byte

func (r *RoomConfiguration) UnmarshalYAML(value *yaml.Node) error {
// Marshall the Node back to yaml to pass it to the protobuf specific unmarshaller
str, err := yaml.Marshal(value)
if err != nil {
return err
}

return protoyaml.Unmarshal(str, r)
func (r *RoomConfiguration) UnmarshalYAML(unmarshal func(interface{}) error) error {
return unmarshalProto(unmarshal, r)
}

func (r *RoomConfiguration) MarshalYAML() (interface{}, error) {
return marshalProto(r)
}

func (r *RoomEgress) UnmarshalYAML(value *yaml.Node) error {
// Marshall the Node back to yaml to pass it to the protobuf specific unmarshaller
str, err := yaml.Marshal(value)
if err != nil {
return err
}

return protoyaml.Unmarshal(str, r)
func (r *RoomEgress) UnmarshalYAML(unmarshal func(interface{}) error) error {
return unmarshalProto(unmarshal, r)
}

func (r *RoomEgress) MarshalYAML() (interface{}, error) {
return marshalProto(r)
}

func (r *RoomAgent) UnmarshalYAML(value *yaml.Node) error {
// Marshall the Node back to yaml to pass it to the protobuf specific unmarshaller
str, err := yaml.Marshal(value)
if err != nil {
return err
}

return protoyaml.Unmarshal(str, r)
func (r *RoomAgent) UnmarshalYAML(unmarshal func(interface{}) error) error {
return unmarshalProto(unmarshal, r)
}

func (r *RoomAgent) MarshalYAML() (interface{}, error) {
return marshalProto(r)
}

// unmarshalProto decodes a yaml value into a protobuf message using the protobuf
// specific unmarshaller.
//
// The func-based unmarshal signature is deliberate: unlike UnmarshalYAML(*yaml.Node),
// it names no types from any yaml package, so decoders from both gopkg.in/yaml.v3 and
// go.yaml.in/yaml/v3 recognize it. Taking a *yaml.Node would bind these types to
// whichever package protocol imports, and callers using the other one would silently
// fall back to reflective struct decoding.
func unmarshalProto(unmarshal func(interface{}) error, o proto.Message) error {
var v interface{}
if err := unmarshal(&v); err != nil {
return err
}

// Marshall the value back to yaml to pass it to the protobuf specific unmarshaller
str, err := yaml.Marshal(v)
if err != nil {
return err
}

return protoyaml.Unmarshal(str, o)
}

func marshalProto(o proto.Message) (map[string]interface{}, error) {
// Marshall the Node to yaml using the protobuf specific marshaller to ensure the proper field names are used
str, err := protoyaml.MarshalOptions{UseProtoNames: true}.Marshal(o)
Expand Down
48 changes: 47 additions & 1 deletion livekit/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (

"github.com/dennwc/iters"
"github.com/stretchr/testify/require"
"go.yaml.in/yaml/v3"
proto "google.golang.org/protobuf/proto"
"gopkg.in/yaml.v3"
gopkgyaml "gopkg.in/yaml.v3"
)

func TestUnmarshallRoomConfiguration(t *testing.T) {
Expand Down Expand Up @@ -44,6 +45,51 @@ a:

}

// TestUnmarshallRoomConfigurationBothYAMLPackages guards the func-based UnmarshalYAML
// signature on RoomConfiguration/RoomEgress/RoomAgent.
//
// Callers decode protocol types with either gopkg.in/yaml.v3 or go.yaml.in/yaml/v3.
// A UnmarshalYAML(*yaml.Node) method is only recognized by the package that owns the
// Node type; the other package silently falls back to reflective struct decoding,
// which leaves proto fields such as min_playout_delay at their zero value rather than
// returning an error. Both decoders must therefore keep producing a populated message.
func TestUnmarshallRoomConfigurationBothYAMLPackages(t *testing.T) {
y := `
name: room_name
egress:
room:
room_name: egress_room
agents:
- agent_name: ag
metadata: mm
min_playout_delay: 42
`

check := func(t *testing.T, rc *RoomConfiguration) {
t.Helper()
require.Equal(t, "room_name", rc.Name)
// zero here means the custom unmarshaller was skipped
require.Equal(t, uint32(42), rc.MinPlayoutDelay)
require.NotNil(t, rc.Egress)
require.Equal(t, "egress_room", rc.Egress.Room.RoomName)
require.Equal(t, 1, len(rc.Agents))
require.Equal(t, "ag", rc.Agents[0].AgentName)
require.Equal(t, "mm", rc.Agents[0].Metadata)
}

t.Run("go.yaml.in/yaml/v3", func(t *testing.T) {
var rc RoomConfiguration
require.NoError(t, yaml.Unmarshal([]byte(y), &rc))
check(t, &rc)
})

t.Run("gopkg.in/yaml.v3", func(t *testing.T) {
var rc RoomConfiguration
require.NoError(t, gopkgyaml.Unmarshal([]byte(y), &rc))
check(t, &rc)
})
}

func TestMarshallRoomConfiguration(t *testing.T) {
r := &RoomConfiguration{
Name: "name",
Expand Down
2 changes: 1 addition & 1 deletion utils/configutil/observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"go.uber.org/atomic"
"gopkg.in/yaml.v3"
"go.yaml.in/yaml/v3"

"github.com/livekit/protocol/logger"
"github.com/livekit/protocol/utils/events"
Expand Down
Loading