15 Commits

Author SHA1 Message Date
Joel Wetzell
bd3b8a19d5 Merge pull request #47 from jwetzell/fix/module-id-required
add check to prevent empty module Id
2026-02-02 13:00:36 -06:00
Joel Wetzell
cb738a9b8e combine route and router labels 2026-02-02 12:59:50 -06:00
Joel Wetzell
1b59dbc1e5 add router to labeler 2026-02-02 12:55:23 -06:00
Joel Wetzell
c75a2327d5 add check to prevent empty module Id 2026-02-02 12:51:56 -06:00
Joel Wetzell
a17be985e6 todo 2026-02-01 20:52:58 -06:00
Joel Wetzell
78737f57af Merge pull request #46 from jwetzell/chore/upgrade-artnet
update artnet dependency
2026-01-31 19:32:12 -06:00
Joel Wetzell
720c0cd52a update artnet dependency 2026-01-31 19:29:30 -06:00
Joel Wetzell
3e1d4f07f9 Merge pull request #43 from jwetzell/dependabot/go_modules/github.com/emiago/diago-0.25.0
Bump github.com/emiago/diago from 0.24.0 to 0.25.0
2026-01-20 11:47:43 -06:00
dependabot[bot]
452e308f8f Bump github.com/emiago/diago from 0.24.0 to 0.25.0
Bumps [github.com/emiago/diago](https://github.com/emiago/diago) from 0.24.0 to 0.25.0.
- [Release notes](https://github.com/emiago/diago/releases)
- [Commits](https://github.com/emiago/diago/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: github.com/emiago/diago
  dependency-version: 0.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-20 17:38:15 +00:00
Joel Wetzell
d16d833520 Merge pull request #44 from jwetzell/dependabot/go_modules/github.com/emiago/sipgo-1.1.1
Bump github.com/emiago/sipgo from 1.1.0 to 1.1.1
2026-01-20 11:37:02 -06:00
Joel Wetzell
f203b32261 Merge pull request #45 from jwetzell/dependabot/go_modules/github.com/urfave/cli/v3-3.6.2
Bump github.com/urfave/cli/v3 from 3.6.1 to 3.6.2
2026-01-20 11:36:51 -06:00
dependabot[bot]
361c4f4499 Bump github.com/urfave/cli/v3 from 3.6.1 to 3.6.2
Bumps [github.com/urfave/cli/v3](https://github.com/urfave/cli) from 3.6.1 to 3.6.2.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v3.6.1...v3.6.2)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v3
  dependency-version: 3.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 19:15:13 +00:00
dependabot[bot]
a76d12d799 Bump github.com/emiago/sipgo from 1.1.0 to 1.1.1
Bumps [github.com/emiago/sipgo](https://github.com/emiago/sipgo) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/emiago/sipgo/releases)
- [Commits](https://github.com/emiago/sipgo/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: github.com/emiago/sipgo
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 19:14:56 +00:00
Joel Wetzell
7d91e64ec4 add complete test coverage for string processors 2026-01-17 20:42:37 -06:00
Joel Wetzell
589c59c693 fix label for cli 2026-01-17 20:02:50 -06:00
9 changed files with 204 additions and 15 deletions

3
.github/labeler.yml vendored
View File

@@ -14,9 +14,10 @@ processor:
- changed-files:
- any-glob-to-any-file: 'internal/processor/**'
route:
routing:
- changed-files:
- any-glob-to-any-file: 'internal/route/**'
- any-glob-to-any-file: 'router*'
cli:
- changed-files:

5
.github/release.yml vendored
View File

@@ -17,12 +17,13 @@ changelog:
- title: Processor 🏭
labels:
- processor
- title: Route 🛣️
- title: Routing 🛣️
labels:
- router
- route
- title: CLI ⌨️
labels:
- cmd
- cli
- title: Other Changes
labels:
- '*'

8
go.mod
View File

@@ -4,16 +4,16 @@ go 1.25.5
require (
github.com/eclipse/paho.mqtt.golang v1.5.1
github.com/emiago/diago v0.24.0
github.com/emiago/sipgo v1.1.0
github.com/emiago/diago v0.25.0
github.com/emiago/sipgo v1.1.1
github.com/expr-lang/expr v1.17.7
github.com/extism/go-sdk v1.7.1
github.com/jwetzell/artnet-go v0.1.0
github.com/jwetzell/artnet-go v0.2.1
github.com/jwetzell/free-d-go v0.1.0
github.com/jwetzell/osc-go v0.1.0
github.com/jwetzell/psn-go v0.3.0
github.com/nats-io/nats.go v1.48.0
github.com/urfave/cli/v3 v3.6.1
github.com/urfave/cli/v3 v3.6.2
gitlab.com/gomidi/midi/v2 v2.3.18
go.bug.st/serial v1.6.4
modernc.org/quickjs v0.17.1

16
go.sum
View File

@@ -8,10 +8,10 @@ github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a h1:UwSIFv5g
github.com/dylibso/observe-sdk/go v0.0.0-20240819160327-2d926c5d788a/go.mod h1:C8DzXehI4zAbrdlbtOByKX6pfivJTBiV9Jjqv56Yd9Q=
github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE=
github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU=
github.com/emiago/diago v0.24.0 h1:NJ94m/h04SPIDet9x19IZoMDss+fRJ58HHqUqfHI4GY=
github.com/emiago/diago v0.24.0/go.mod h1:MwO7aQbGtgOdfm0Soj6XqEfAcskstixiS9gnxMV9xeo=
github.com/emiago/sipgo v1.1.0 h1:ryr9DhoDercbyCmCtGiZD/uB1NY745DZpsUHfSbWWaI=
github.com/emiago/sipgo v1.1.0/go.mod h1:DuwAxBZhKMqIzQFPGZb1MVAGU6Wuxj64oTOhd5dx/FY=
github.com/emiago/diago v0.25.0 h1:YkjHahAMyIhvk5TKTMYoFJvsbNaJhyMBAiGggc97HDc=
github.com/emiago/diago v0.25.0/go.mod h1:HQNLzmwucATviInW5OqpnpqFjtz2jAtxKKWx8Nh98wo=
github.com/emiago/sipgo v1.1.1 h1:egwB7o9b3QpeTbqRFT9ECOYcWT/rw2UVTWA1qYG1HBs=
github.com/emiago/sipgo v1.1.1/go.mod h1:DuwAxBZhKMqIzQFPGZb1MVAGU6Wuxj64oTOhd5dx/FY=
github.com/expr-lang/expr v1.17.7 h1:Q0xY/e/2aCIp8g9s/LGvMDCC5PxYlvHgDZRQ4y16JX8=
github.com/expr-lang/expr v1.17.7/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
github.com/extism/go-sdk v1.7.1 h1:lWJos6uY+tRFdlIHR+SJjwFDApY7OypS/2nMhiVQ9Sw=
@@ -38,8 +38,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca h1:T54Ema1
github.com/ianlancetaylor/demangle v0.0.0-20240805132620-81f5be970eca/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4=
github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
github.com/jwetzell/artnet-go v0.1.0 h1:cW2BUkEwLMMMsYSlvGhDtE3ZTgYpvjnRy/OYLPNPk1U=
github.com/jwetzell/artnet-go v0.1.0/go.mod h1:gli97Z32a0kMkZ6taoTiK7/lqHcF/dhiGjGJdx/PxqA=
github.com/jwetzell/artnet-go v0.2.1 h1:iYTKWcwYrF5kBkYfkw2UbWvoueeA23iKEn7fR27mWZE=
github.com/jwetzell/artnet-go v0.2.1/go.mod h1:gli97Z32a0kMkZ6taoTiK7/lqHcF/dhiGjGJdx/PxqA=
github.com/jwetzell/free-d-go v0.1.0 h1:xHt6dvyit98X+OC3jVzV0aLidxbyzi3vI9QiYkteEtA=
github.com/jwetzell/free-d-go v0.1.0/go.mod h1:KmrkooRARRaxJTBSPvwt/6IMAIaHH1R8bSA8cwbbELw=
github.com/jwetzell/osc-go v0.1.0 h1:EXxup5VWBErHot2Ri4MFToPf6KCzLDTbCt2x6GLfw8I=
@@ -86,8 +86,8 @@ github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 h1:ZF+QBjOI+tILZ
github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834/go.mod h1:m9ymHTgNSEjuxvw8E7WWe4Pl4hZQHXONY8wE6dMLaRk=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo=
github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/urfave/cli/v3 v3.6.2 h1:lQuqiPrZ1cIz8hz+HcrG0TNZFxU70dPZ3Yl+pSrH9A8=
github.com/urfave/cli/v3 v3.6.2/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/zaf/g711 v1.4.0 h1:XZYkjjiAg9QTBnHqEg37m2I9q3IIDv5JRYXs2N8ma7c=
github.com/zaf/g711 v1.4.0/go.mod h1:eCDXt3dSp/kYYAoooba7ukD/Q75jvAaS4WOMr0l1Roo=
gitlab.com/gomidi/midi/v2 v2.3.18 h1:sj2fOhtvOe+zI8YJe8qTxLw5zv0ntULLUDwcFOaZQbI=

View File

@@ -89,6 +89,7 @@ func (pc *PSNClient) Run(ctx context.Context) error {
}
if pc.router != nil {
// TODO(jwetzell): better input handling
for _, tracker := range pc.decoder.Trackers {
pc.router.HandleInput(pc.ctx, pc.Id(), tracker)
}

View File

@@ -4,6 +4,7 @@ import (
"testing"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
)
@@ -15,6 +16,39 @@ func (t TestStruct) GetData() string {
return t.Data
}
func TestStringCreateFromRegistry(t *testing.T) {
registration, ok := processor.ProcessorRegistry["string.create"]
if !ok {
t.Fatalf("string.create processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.create",
Params: map[string]any{
"template": "{{.}}",
},
})
if err != nil {
t.Fatalf("failed to create string.create processor: %s", err)
}
if processorInstance.Type() != "string.create" {
t.Fatalf("string.create processor has wrong type: %s", processorInstance.Type())
}
payload := "hello"
expected := "hello"
got, err := processorInstance.Process(t.Context(), payload)
if err != nil {
t.Fatalf("string.create processing failed: %s", err)
}
if got != expected {
t.Fatalf("string.create got %+v, expected %+v", got, expected)
}
}
func TestGoodStringCreate(t *testing.T) {
tests := []struct {
@@ -79,3 +113,75 @@ func TestGoodStringCreate(t *testing.T) {
})
}
}
func TestBadStringCreate(t *testing.T) {
tests := []struct {
name string
params map[string]any
payload any
errorString string
}{
{
name: "no template param",
payload: "hello",
params: map[string]any{},
errorString: "string.create requires a template parameter",
},
{
name: "non string template",
payload: "hello",
params: map[string]any{
"template": 1,
},
errorString: "string.create template must be a string",
},
{
name: "invalid template",
payload: "hello",
params: map[string]any{
"template": "{{.",
},
errorString: "template: template:1: illegal number syntax: \".\"",
},
{
name: "bad property in template",
payload: "hello",
params: map[string]any{
"template": "{{.Invalid}}",
},
errorString: "template: template:1:2: executing \"template\" at <.Invalid>: can't evaluate field Invalid in type string",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
registration, ok := processor.ProcessorRegistry["string.create"]
if !ok {
t.Fatalf("string.create processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.create",
Params: test.params,
})
if err != nil {
if test.errorString != err.Error() {
t.Fatalf("string.encode got error '%s', expected '%s'", err.Error(), test.errorString)
}
return
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("string.encode expected to fail but got payload: %s", got)
}
if err.Error() != test.errorString {
t.Fatalf("string.encode got error '%s', expected '%s'", err.Error(), test.errorString)
}
})
}
}

View File

@@ -3,9 +3,40 @@ package processor_test
import (
"testing"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
)
func TestStringDecodeFromRegistry(t *testing.T) {
registration, ok := processor.ProcessorRegistry["string.decode"]
if !ok {
t.Fatalf("string.decode processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.decode",
})
if err != nil {
t.Fatalf("failed to create string.decode processor: %s", err)
}
if processorInstance.Type() != "string.decode" {
t.Fatalf("string.decode processor has wrong type: %s", processorInstance.Type())
}
payload := []byte{'h', 'e', 'l', 'l', 'o'}
expected := "hello"
got, err := processorInstance.Process(t.Context(), payload)
if err != nil {
t.Fatalf("string.decode processing failed: %s", err)
}
if got != expected {
t.Fatalf("string.decode got %+v, expected %+v", got, expected)
}
}
func TestGoodStringDecode(t *testing.T) {
stringDecoder := processor.StringDecode{}
tests := []struct {

View File

@@ -4,9 +4,46 @@ import (
"slices"
"testing"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
)
func TestStringEncodeFromRegistry(t *testing.T) {
registration, ok := processor.ProcessorRegistry["string.encode"]
if !ok {
t.Fatalf("string.encode processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.encode",
})
if err != nil {
t.Fatalf("failed to create string.encode processor: %s", err)
}
if processorInstance.Type() != "string.encode" {
t.Fatalf("string.encode processor has wrong type: %s", processorInstance.Type())
}
payload := "hello"
expected := []byte{'h', 'e', 'l', 'l', 'o'}
got, err := processorInstance.Process(t.Context(), payload)
if err != nil {
t.Fatalf("string.encode processing failed: %s", err)
}
gotBytes, ok := got.([]byte)
if !ok {
t.Fatalf("string.encode should return byte slice")
}
if !slices.Equal(gotBytes, expected) {
t.Fatalf("string.encode got %+v, expected %+v", got, expected)
}
}
func TestGoodStringEncode(t *testing.T) {
stringEncoder := processor.StringEncode{}
tests := []struct {

View File

@@ -34,6 +34,18 @@ func NewRouter(config config.Config) (*Router, []module.ModuleError, []route.Rou
for moduleIndex, moduleDecl := range config.Modules {
if moduleDecl.Id == "" {
if moduleErrors == nil {
moduleErrors = []module.ModuleError{}
}
moduleErrors = append(moduleErrors, module.ModuleError{
Index: moduleIndex,
Config: moduleDecl,
Error: errors.New("module id cannot be empty"),
})
continue
}
moduleInfo, ok := module.ModuleRegistry[moduleDecl.Type]
if !ok {
if moduleErrors == nil {