diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..7ed36bd --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,59 @@ + +name: PR Check + +on: + pull_request: + push: + branches: [main] + +jobs: + vet: + defaults: + run: + working-directory: mpd-web-proxy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - run: go mod download + + - name: Go Vet + run: go vet ./... + + unit-test: + defaults: + run: + working-directory: mpd-web-proxy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - run: go mod download + + - run: go install github.com/jstemmer/go-junit-report/v2@latest + + - name: Unit Test + run: | + set +e + go test -v ./... | tee test.out + exitcode=$? + cat test.out | ~/go/bin/go-junit-report -set-exit-code > junit.xml + exit $exitcode + + - if: always() + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + files: mpd-web-proxy/junit.xml + diff --git a/mpd-web-proxy/Dockerfile b/mpd-web-proxy/Dockerfile index 2a7461e..2acfb3b 100644 --- a/mpd-web-proxy/Dockerfile +++ b/mpd-web-proxy/Dockerfile @@ -9,10 +9,9 @@ ARG VERSION='development' COPY go.mod go.sum ./ RUN go mod download COPY *.go ./ -COPY gpio/ ./gpio/ -COPY art/ ./art/ -COPY version/ ./version/ +COPY cmd/ ./cmd/ +COPY internal/ ./internal/ -RUN go build -ldflags "-X 'github.com/aspage2/remote/mpd-web-proxy/version.Version=${VERSION}'" -o /app/main +RUN go build -ldflags "-X 'github.com/aspage2/remote/mpd-web-proxy/internal/version.Version=${VERSION}'" -o /app/main /app/cmd ENTRYPOINT ["/app/main"] diff --git a/mpd-web-proxy/Makefile b/mpd-web-proxy/Makefile index b6da947..dc11b46 100644 --- a/mpd-web-proxy/Makefile +++ b/mpd-web-proxy/Makefile @@ -2,4 +2,4 @@ VERSION = $(shell git describe --exact-match --match='v[0-9].*' HEAD 2>/dev/null || git rev-parse --short HEAD) build/mpd-web-proxy: $(wildcard **/*.go *.go) - go build -ldflags="-X 'github.com/aspage2/remote/mpd-web-proxy.Version=$(VERSION)'" -o build/mpd-web-proxy . + go build -ldflags="-X 'github.com/aspage2/remote/mpd-web-proxy/internal.Version=$(VERSION)'" -o build/mpd-web-proxy ./cmd diff --git a/mpd-web-proxy/config.go b/mpd-web-proxy/cmd/config.go similarity index 100% rename from mpd-web-proxy/config.go rename to mpd-web-proxy/cmd/config.go diff --git a/mpd-web-proxy/main.go b/mpd-web-proxy/cmd/main.go similarity index 92% rename from mpd-web-proxy/main.go rename to mpd-web-proxy/cmd/main.go index db96940..eff949f 100644 --- a/mpd-web-proxy/main.go +++ b/mpd-web-proxy/cmd/main.go @@ -14,9 +14,10 @@ import ( "runtime/debug" "strings" - "github.com/aspage2/remote/mpd-web-proxy/art" - "github.com/aspage2/remote/mpd-web-proxy/gpio" - "github.com/aspage2/remote/mpd-web-proxy/version" + "github.com/aspage2/remote/mpd-web-proxy/internal" + "github.com/aspage2/remote/mpd-web-proxy/internal/art" + "github.com/aspage2/remote/mpd-web-proxy/internal/gpio" + "github.com/aspage2/remote/mpd-web-proxy/internal/version" ) const ( @@ -28,7 +29,7 @@ const ( type Server struct { Pins []gpio.Pin PinState *gpio.PinState - MPDStateTopic *Topic[Event] + MPDStateTopic *internal.Topic[internal.Event] } func (s *Server) WriteResponse(wr io.Writer) error { @@ -119,7 +120,7 @@ func (s *Server) MpdEvents(rw http.ResponseWriter, req *http.Request) { io.Copy(io.Discard, req.Body) }() - for ev := range getEvents(s.MPDStateTopic, req.Context()) { + for ev := range internal.GetEvents(s.MPDStateTopic, req.Context()) { eventPayload := ev.SSEPayload() _, err := io.WriteString(rw, eventPayload) if err != nil { @@ -141,7 +142,7 @@ func MpdCommand(rw http.ResponseWriter, req *http.Request) { return } q := qs[0] - data := Must(MpdQuery(q)) + data := Must(internal.MpdQuery(q, MpdAuthority)) rw.Write(data) } @@ -237,7 +238,7 @@ func httpServer(s *Server) { nonEventMux.HandleFunc("/go/channels", s.Channels) nonEventMux.HandleFunc("/go/art/{albumartist}/{album}", AlbumArt) - http.Handle("/go/", loggingMiddleware(&PanicCatchall{&nonEventMux})) + http.Handle("/go/", internal.LoggingMiddleware(&PanicCatchall{&nonEventMux})) http.Handle("/go/events", &PanicCatchall{http.HandlerFunc(s.MpdEvents)}) http.ListenAndServe(BindAddr, nil) @@ -290,7 +291,7 @@ func main() { var s Server s.PinState = ps s.Pins = pins - s.MPDStateTopic = NewTopic[Event]() - go MPDIdler(s.MPDStateTopic) + s.MPDStateTopic = internal.NewTopic[internal.Event]() + go internal.MPDIdler(s.MPDStateTopic, MpdAuthority) httpServer(&s) } diff --git a/mpd-web-proxy/art/art.go b/mpd-web-proxy/internal/art/art.go similarity index 100% rename from mpd-web-proxy/art/art.go rename to mpd-web-proxy/internal/art/art.go diff --git a/mpd-web-proxy/art/art_test.go b/mpd-web-proxy/internal/art/art_test.go similarity index 87% rename from mpd-web-proxy/art/art_test.go rename to mpd-web-proxy/internal/art/art_test.go index 67492b1..46d8130 100644 --- a/mpd-web-proxy/art/art_test.go +++ b/mpd-web-proxy/internal/art/art_test.go @@ -8,8 +8,10 @@ import ( "github.com/stretchr/testify/assert" ) +const DataPath = "../../testdata/file.mp3" + func TestFindAPIC(t *testing.T) { - f, err := os.Open("../testdata/file.mp3") + f, err := os.Open(DataPath) assert.NoError(t, err) mime, size, err := FindAPICInMP3(f) @@ -22,7 +24,7 @@ func TestFindAPIC(t *testing.T) { } func BenchmarkFindAPICInMP3(b *testing.B) { - f, err := os.Open("../testdata/file.mp3") + f, err := os.Open(DataPath) if err != nil { panic(err) } diff --git a/mpd-web-proxy/art/id3.go b/mpd-web-proxy/internal/art/id3.go similarity index 100% rename from mpd-web-proxy/art/id3.go rename to mpd-web-proxy/internal/art/id3.go diff --git a/mpd-web-proxy/art/id3_test.go b/mpd-web-proxy/internal/art/id3_test.go similarity index 100% rename from mpd-web-proxy/art/id3_test.go rename to mpd-web-proxy/internal/art/id3_test.go diff --git a/mpd-web-proxy/events.go b/mpd-web-proxy/internal/events.go similarity index 92% rename from mpd-web-proxy/events.go rename to mpd-web-proxy/internal/events.go index b0445eb..9ead276 100644 --- a/mpd-web-proxy/events.go +++ b/mpd-web-proxy/internal/events.go @@ -1,4 +1,4 @@ -package main +package internal import ( "bufio" @@ -62,11 +62,11 @@ func (ev Event) SSEPayload() string { // event and tries to re-create the connection. After re- // connecting, the idler sends a `server:mpd-connected` // event and continues idling. -func MPDIdler(tpc *Topic[Event]) { +func MPDIdler(tpc *Topic[Event], authority string) { oneRound := func() error { slog.Info("start idler") defer slog.Info("stop idler") - mpd, err := net.Dial("tcp", MpdAuthority) + mpd, err := net.Dial("tcp", authority) if err != nil { return err } @@ -124,9 +124,9 @@ func mpdIdle(mpd net.Conn, tpc *Topic[Event]) error { } } -// getEvents wraps the given Topic[Event] with a ticker +// GetEvents wraps the given Topic[Event] with a ticker // that sends a `ping` event every 5 seconds. -func getEvents(tpc *Topic[Event], ctx context.Context) chan Event { +func GetEvents(tpc *Topic[Event], ctx context.Context) chan Event { ret := make(chan Event) go func() { defer close(ret) diff --git a/mpd-web-proxy/gpio/amd.go b/mpd-web-proxy/internal/gpio/amd.go similarity index 100% rename from mpd-web-proxy/gpio/amd.go rename to mpd-web-proxy/internal/gpio/amd.go diff --git a/mpd-web-proxy/gpio/arm.go b/mpd-web-proxy/internal/gpio/arm.go similarity index 100% rename from mpd-web-proxy/gpio/arm.go rename to mpd-web-proxy/internal/gpio/arm.go diff --git a/mpd-web-proxy/gpio/config.go b/mpd-web-proxy/internal/gpio/config.go similarity index 100% rename from mpd-web-proxy/gpio/config.go rename to mpd-web-proxy/internal/gpio/config.go diff --git a/mpd-web-proxy/gpio/gpio.go b/mpd-web-proxy/internal/gpio/gpio.go similarity index 100% rename from mpd-web-proxy/gpio/gpio.go rename to mpd-web-proxy/internal/gpio/gpio.go diff --git a/mpd-web-proxy/gpio/state.go b/mpd-web-proxy/internal/gpio/state.go similarity index 100% rename from mpd-web-proxy/gpio/state.go rename to mpd-web-proxy/internal/gpio/state.go diff --git a/mpd-web-proxy/logging.go b/mpd-web-proxy/internal/logging.go similarity index 92% rename from mpd-web-proxy/logging.go rename to mpd-web-proxy/internal/logging.go index d1583e5..c5ff3c3 100644 --- a/mpd-web-proxy/logging.go +++ b/mpd-web-proxy/internal/logging.go @@ -1,4 +1,4 @@ -package main +package internal import ( "fmt" @@ -26,7 +26,7 @@ func (lr *StatusCaptureRW) WriteHeader(code int) { lr.ResponseWriter.WriteHeader(code) } -func loggingMiddleware(next http.Handler) http.Handler { +func LoggingMiddleware(next http.Handler) http.Handler { f := func(rw http.ResponseWriter, req *http.Request) { sc := NewStatusCaptureRW(rw) next.ServeHTTP(sc, req) diff --git a/mpd-web-proxy/mpd.go b/mpd-web-proxy/internal/mpd.go similarity index 83% rename from mpd-web-proxy/mpd.go rename to mpd-web-proxy/internal/mpd.go index 51d90aa..3de42bc 100644 --- a/mpd-web-proxy/mpd.go +++ b/mpd-web-proxy/internal/mpd.go @@ -1,4 +1,4 @@ -package main +package internal import ( "bufio" @@ -14,8 +14,8 @@ import ( // MpdQuery connects and queries the MPD server // with the given command. Returns the response body // or any connection error. -func MpdQuery(cmd string) ([]byte, error) { - mpd, err := net.Dial("tcp", MpdAuthority) +func MpdQuery(cmd string, authority string) ([]byte, error) { + mpd, err := net.Dial("tcp", authority) if err != nil { return nil, err } @@ -24,8 +24,8 @@ func MpdQuery(cmd string) ([]byte, error) { } // A cancellable MPD Query. -func MpdQueryContext(cmd string, ctx context.Context) ([]byte, error) { - mpd, err := net.Dial("tcp", MpdAuthority) +func MpdQueryContext(cmd string, authority string, ctx context.Context) ([]byte, error) { + mpd, err := net.Dial("tcp", authority) if err != nil { return nil, err } diff --git a/mpd-web-proxy/topic.go b/mpd-web-proxy/internal/topic.go similarity index 97% rename from mpd-web-proxy/topic.go rename to mpd-web-proxy/internal/topic.go index 205fb2b..7b255c4 100644 --- a/mpd-web-proxy/topic.go +++ b/mpd-web-proxy/internal/topic.go @@ -1,4 +1,4 @@ -package main +package internal import ( "log/slog" diff --git a/mpd-web-proxy/version/version.go b/mpd-web-proxy/internal/version/version.go similarity index 100% rename from mpd-web-proxy/version/version.go rename to mpd-web-proxy/internal/version/version.go