Skip to content

Commit

Permalink
ci(push): replace golangci-lint with super-linter
Browse files Browse the repository at this point in the history
  • Loading branch information
streambinder committed Sep 9, 2024
1 parent 46895a5 commit 3cb2cf2
Show file tree
Hide file tree
Showing 50 changed files with 412 additions and 273 deletions.
2 changes: 1 addition & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Spotitube <a href="https://davidepucci.it/doc/spotitube"><img align="left" src="https://github.com/streambinder.png?size=96"></a>
# Spotitube <a href="https://davidepucci.it/doc/spotitube"><img alt="documentation" align="left" src="https://github.com/streambinder.png?size=96"></a>

Documentation available at [davidepucci.it/doc/spotitube](https://davidepucci.it/doc/spotitube).
6 changes: 6 additions & 0 deletions .github/linters/.hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
failure-threshold: warning

ignored:
- DL3018 # Pin versions in apk add
- SC2215 # This flag is used as a command name
6 changes: 6 additions & 0 deletions .github/linters/.jscpd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"threshold": 3,
"reporters": ["consoleFull"],
"ignore": ["**/__snapshots__/**", "**/node_modules/**", "**/*_test.go"],
"absolute": true
}
38 changes: 33 additions & 5 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,21 @@ on:
branches:
- master

permissions: write-all
permissions:
actions: read
attestations: none
checks: none
contents: read
deployments: none
id-token: none
issues: none
discussions: none
packages: write
pages: none
pull-requests: read
repository-projects: none
security-events: none
statuses: none

jobs:
commitlint:
Expand All @@ -25,18 +39,23 @@ jobs:
- uses: codespell-project/actions-codespell@v2
with:
check_filenames: true
golangci-lint:
super-linter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: golangci/golangci-lint-action@v6
- uses: super-linter/super-linter@latest
env:
GITHUB_TOKEN: ${{ secrets.GH_ACTIONS_SPOTITUBE }}
VALIDATE_ALL_CODEBASE: false
VALIDATE_GO: false
gofumpt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- run: |
export PATH=$PATH:$(go env GOPATH)/bin
PATH="$PATH:$(go env GOPATH)/bin"
export PATH
go install mvdan.cc/gofumpt@latest
if gofumpt -l -e . | grep '^' -q; then exit 1; fi
go-channel-closure:
Expand All @@ -56,7 +75,16 @@ jobs:
- run: test "$(grep -cr 'defer gomonkey\.')" = "$(grep -cr 'Reset()$')"
test:
runs-on: ubuntu-latest
needs: [commitlint, codespell, golangci-lint, gofumpt, go-channel-closure, go-http-body-closure, go-monkey-unpatch]
needs:
[
commitlint,
codespell,
super-linter,
gofumpt,
go-channel-closure,
go-http-body-closure,
go-monkey-unpatch,
]
if: success()
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scrape.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- run: go test -v -run ^TestScraping$ ./...
- run: go test -v -run ^TestScraping$ ./...
env:
TEST_SCRAPING: true
GENIUS_TOKEN: ${{ secrets.GENIUS_TOKEN }}
18 changes: 16 additions & 2 deletions .github/workflows/tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,23 @@ name: tag
on:
push:
tags:
- 'v*.*.*'
- "v*.*.*"

permissions: write-all
permissions:
actions: read
attestations: none
checks: none
contents: read
deployments: none
id-token: none
issues: none
discussions: none
packages: write
pages: none
pull-requests: read
repository-projects: none
security-events: none
statuses: none

jobs:
test:
Expand Down
15 changes: 9 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@
FROM golang:alpine AS builder
WORKDIR /workspace
COPY . .
RUN go mod download
RUN --mount=type=secret,id=SPOTIFY_ID \
RUN go mod download && \
--mount=type=secret,id=SPOTIFY_ID \
--mount=type=secret,id=SPOTIFY_KEY \
--mount=type=secret,id=GENIUS_TOKEN \
go build -ldflags="-s -w -X github.com/streambinder/spotitube/spotify.fallbackSpotifyID=$(cat /run/secrets/SPOTIFY_ID) -X github.com/streambinder/spotitube/spotify.fallbackSpotifyKey=$(cat /run/secrets/SPOTIFY_KEY) -X github.com/streambinder/spotitube/lyrics.fallbackGeniusToken=$(cat /run/secrets/GENIUS_TOKEN)"

FROM alpine:latest
RUN apk add --no-cache ffmpeg yt-dlp
RUN mkdir /data
RUN mkdir /cache
FROM alpine:3
RUN apk add --no-cache ffmpeg yt-dlp && \
mkdir /data && \
mkdir /cache && \
adduser -S spotitube
USER spotitube
WORKDIR /data
ENV XDG_MUSIC_DIR=/data
ENV XDG_CACHE_HOME=/cache
COPY --from=builder /workspace/spotitube /usr/sbin/
HEALTHCHECK CMD [ "/usr/sbin/spotitube", "--help" ]
EXPOSE 65535/tcp
ENTRYPOINT ["/usr/sbin/spotitube"]
LABEL org.opencontainers.image.source=https://github.com/streambinder/spotitube
6 changes: 3 additions & 3 deletions cmd/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func cmdAttach() *cobra.Command {
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
var (
path = args[0]
id = args[1]
rename, _ = cmd.Flags().GetBool("rename")
path = args[0]
id = args[1]
rename = util.ErrWrap(false)(cmd.Flags().GetBool("rename"))
)

localTrack, err := id3.Open(path, id3v2.Options{Parse: false})
Expand Down
6 changes: 3 additions & 3 deletions cmd/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func cmdAuth() *cobra.Command {
Use: "auth",
Short: "Establish a Spotify session for future uses",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
var (
remote, _ = cmd.Flags().GetBool("remote")
logout, _ = cmd.Flags().GetBool("logout")
remote = util.ErrWrap(false)(cmd.Flags().GetBool("remote"))
logout = util.ErrWrap(false)(cmd.Flags().GetBool("logout"))
callback = "127.0.0.1"
processor = spotify.BrowserProcessor
)
Expand Down
2 changes: 1 addition & 1 deletion cmd/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestCmdAuth(t *testing.T) {
return nil
}).
ApplyFunc(spotify.Authenticate, func() (*spotify.Client, error) {
_ = printProcessor("")
util.ErrSuppress(printProcessor(""))
return &spotify.Client{}, nil
}).
Reset()
Expand Down
131 changes: 74 additions & 57 deletions cmd/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,74 +30,28 @@ func cmdLookup() *cobra.Command {
Short: "Utility to lookup for tracks in order to investigate general querying behaviour",
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
library, _ := cmd.Flags().GetBool("library")
random, _ := cmd.Flags().GetBool("random")
randomSize, _ := cmd.Flags().GetInt("random-size")
libraryLimit, _ := cmd.Flags().GetInt("library-limit")
library := util.ErrWrap(false)(cmd.Flags().GetBool("library"))
random := util.ErrWrap(false)(cmd.Flags().GetBool("random"))
randomSize := util.ErrWrap(defaultRandomSize)(cmd.Flags().GetInt("random-size"))
libraryLimit := util.ErrWrap(0)(cmd.Flags().GetInt("library-limit"))
if !library && !random && len(args) == 0 {
return errors.New("no track has been issued")
}

client, err := spotify.Authenticate(spotify.BrowserProcessor)
if err != nil {
return err
var authErr error
spotifyClient, authErr = spotify.Authenticate(spotify.BrowserProcessor)
if authErr != nil {
return authErr
}

var (
providerChannel = make(chan interface{}, 1)
lyricsChannel = make(chan interface{}, 1)
)
return nursery.RunConcurrently(
func(ctx context.Context, ch chan error) {
defer close(providerChannel)
defer close(lyricsChannel)
if random {
if err := client.Random(spotify.TypeTrack, randomSize, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
} else if library {
if err := client.Library(libraryLimit, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
} else {
for _, id := range args {
if _, err := client.Track(id, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
}
}
},
func(ctx context.Context, ch chan error) {
prefix := "[P]"
for event := range providerChannel {
track := event.(*entity.Track)
matches, err := provider.Search(track)
if err != nil {
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), err, colorReset)
} else if len(matches) == 0 {
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), "no result", colorReset)
} else {
fmt.Println(prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), matches[0].URL, matches[0].Score)
}
}
},
func(ctx context.Context, ch chan error) {
prefix := "[L]"
for event := range lyricsChannel {
track := event.(*entity.Track)
lyrics, err := lyrics.Search(track)
if err != nil {
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), err, colorReset)
} else if len(lyrics) == 0 {
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), "no result", colorReset)
} else {
fmt.Println(prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), util.Excerpt(lyrics, 80))
}
}
},
routineLookupFetch(random, library, randomSize, libraryLimit, args, providerChannel, lyricsChannel),
routineLookupProvider(providerChannel),
routineLookupLyrics(lyricsChannel),
)
},
}
Expand All @@ -107,3 +61,66 @@ func cmdLookup() *cobra.Command {
cmd.Flags().Int("library-limit", 0, "Number of tracks to fetch from library (unlimited if 0)")
return cmd
}

func routineLookupFetch(random, library bool, randomSize, libraryLimit int, ids []string, providerChannel, lyricsChannel chan interface{}) func(context.Context, chan error) {
return func(_ context.Context, ch chan error) {
defer close(providerChannel)
defer close(lyricsChannel)

switch {
case random:
if err := spotifyClient.Random(spotify.TypeTrack, randomSize, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
case library:
if err := spotifyClient.Library(libraryLimit, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
default:
for _, id := range ids {
if _, err := spotifyClient.Track(id, providerChannel, lyricsChannel); err != nil {
ch <- err
return
}
}
}
}
}

func routineLookupProvider(providerChannel chan interface{}) func(context.Context, chan error) {
return func(context.Context, chan error) {
prefix := "[P]"
for event := range providerChannel {
track := event.(*entity.Track)
matches, err := provider.Search(track)
switch {
case err != nil:
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), err, colorReset)
case len(matches) == 0:
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), "no result", colorReset)
default:
fmt.Println(prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), matches[0].URL, matches[0].Score)
}
}
}
}

func routineLookupLyrics(lyricsChannel chan interface{}) func(context.Context, chan error) {
return func(context.Context, chan error) {
prefix := "[L]"
for event := range lyricsChannel {
track := event.(*entity.Track)
lyrics, err := lyrics.Search(track)
switch {
case err != nil:
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), err, colorReset)
case len(lyrics) == 0:
fmt.Println(colorRed+prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), "no result", colorReset)
default:
fmt.Println(prefix, track.ID, util.Pad(track.Artists[0]), util.Pad(track.Title), util.Excerpt(lyrics, 80))
}
}
}
}
4 changes: 2 additions & 2 deletions cmd/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func TestCmdLookupLibraryFailure(t *testing.T) {
ApplyFunc(spotify.Authenticate, func() (*spotify.Client, error) {
return &spotify.Client{}, nil
}).
ApplyMethod(&spotify.Client{}, "Library", func(_ *spotify.Client, _ int, ch ...chan interface{}) error {
ApplyMethod(&spotify.Client{}, "Library", func(_ *spotify.Client, _ int, _ ...chan interface{}) error {
return errors.New("ko")
}).
Reset()
Expand All @@ -125,7 +125,7 @@ func TestCmdLookupTrackFailure(t *testing.T) {
ApplyFunc(spotify.Authenticate, func() (*spotify.Client, error) {
return &spotify.Client{}, nil
}).
ApplyMethod(&spotify.Client{}, "Track", func(_ *spotify.Client, _ string, ch ...chan interface{}) (*entity.Track, error) {
ApplyMethod(&spotify.Client{}, "Track", func(_ *spotify.Client, _ string, _ ...chan interface{}) (*entity.Track, error) {
return nil, errors.New("ko")
}).Reset()

Expand Down
4 changes: 2 additions & 2 deletions cmd/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ func cmdReset() *cobra.Command {
Short: "Clear cached objects",
SilenceUsage: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
var (
session, _ = cmd.Flags().GetBool("session")
session = util.ErrWrap(false)(cmd.Flags().GetBool("session"))
cacheDirectory = util.CacheDirectory()
)
return filepath.WalkDir(cacheDirectory, func(path string, entry fs.DirEntry, err error) error {
Expand Down
8 changes: 4 additions & 4 deletions cmd/reset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ func BenchmarkReset(b *testing.B) {
func TestCmdReset(t *testing.T) {
// monkey patching
defer gomonkey.NewPatches().
ApplyFunc(filepath.WalkDir, func(path string, f func(string, fs.DirEntry, error) error) error {
_ = f("", DirEntry{name: "", isDir: false}, errors.New("some error"))
_ = f(spotify.TokenBasename, DirEntry{name: spotify.TokenBasename, isDir: false}, nil)
_ = f("fname.txt", DirEntry{name: "fname.txt", isDir: false}, nil)
ApplyFunc(filepath.WalkDir, func(_ string, f func(string, fs.DirEntry, error) error) error {
util.ErrSuppress(f("", DirEntry{name: "", isDir: false}, errors.New("some error")))
util.ErrSuppress(f(spotify.TokenBasename, DirEntry{name: spotify.TokenBasename, isDir: false}, nil))
util.ErrSuppress(f("fname.txt", DirEntry{name: "fname.txt", isDir: false}, nil))
return nil
}).
ApplyFunc(os.RemoveAll, func() error {
Expand Down
Loading

0 comments on commit 3cb2cf2

Please sign in to comment.