Skip to content

Commit

Permalink
Merge pull request #63 from jmillerv/28-golang-linter
Browse files Browse the repository at this point in the history
28-add-golang-linter
  • Loading branch information
jmillerv committed Aug 5, 2023
2 parents 25d910f + b89ee72 commit 0119591
Show file tree
Hide file tree
Showing 23 changed files with 498 additions and 128 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,21 @@ jobs:
run: go build -v ./...

- name: Test
run: go test -v ./...
run: go test -v ./...
# configuration: https://github.com/golangci/golangci-lint-action
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.53
144 changes: 144 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
linters-settings:
gosec:
# To select a subset of rules to run.
# Available rules: https://github.com/securego/gosec#available-rules
# includes:
# To specify a set of rules to explicitly exclude.
# Available rules: https://github.com/securego/gosec#available-rules
excludes:
- G204
# To specify the configuration of rules.
# The configuration of rules is not fully documented by gosec:
# https://github.com/securego/gosec#configuration
# https://github.com/securego/gosec/blob/569328eade2ccbad4ce2d0f21ee158ab5356a5cf/rules/rulelist.go#L60-L102
linters:
# Enable specific linter
# https://golangci-lint.run/usage/linters/#enabled-by-default
enable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- containedctx
- contextcheck
- cyclop
- deadcode
- decorder
- dogsled
- dupl
- dupword
- durationcheck
- errcheck
- errchkjson
- errname
- errorlint
- execinquery
- exhaustive
- exhaustruct
- exportloopref
- forbidigo
- forcetypeassert
- funlen
- gci
- ginkgolinter
- gocheckcompilerdirectives
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- gofmt
- gofumpt
- goheader
- goimports
- revive
- gomnd
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- gosmopolitan
- govet
- grouper
- importas
- ineffassign
- interfacebloat
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- musttag
- nakedret
- nestif
- nilerr
- nilnil
- nlreturn
- noctx
- nolintlint
- nosprintfhostport
- paralleltest
- prealloc
- predeclared
- promlinter
- reassign
- revive
- rowserrcheck
- exportloopref
- sqlclosecheck
- staticcheck
- stylecheck
- tagalign
- tagliatelle
- tenv
- testableexamples
- testpackage
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- usestdlibvars
- varcheck
- wastedassign
- whitespace
- wsl
- zerologlint

disable:
- wrapcheck
- depguard
- varnamelen
- nonamedreturns
- ireturn
- ifshort
- gochecknoinits
- gochecknoglobals

# Enable presets.
# https://golangci-lint.run/usage/linters
presets:
- bugs
- comment
- complexity
- error
- format
- import
- metalinter
- module
- performance
- sql
- style
- test
- unused
# Run only fast linters from enabled linters set (first run won't be fast)
# Default: false
fast: true

run:
skip-files:
- '.*_test\.go'
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ streams don't work.
I've built this out for my specific use case and released it to the public when I considered it feature complete. Suggestions are welcome for adding additional features.

## Development Setup
Note: steps 3 & 4 assume a developer is on some distribution of Debian/Ubuntu. If not on that distribution,
you can simply look at what is happening in `taskfile.dev` and replicate that in your environment.

1. Install [golang](https://go.dev/doc/install)
2. Install [taskfile.dev](https://taskfile.dev/installation/) on your machine.

Expand All @@ -158,3 +161,5 @@ I've built this out for my specific use case and released it to the public when
If all passes without errors, you should be set to use this binary. Checkout the `taskfile.dev` for additional features
commands you can run.

### Linting
Linting is performed by [golangci-lint](https://golangci-lint.run/)
3 changes: 2 additions & 1 deletion cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import (
)

const (
defaultPodcastCache = "podcastCache"
podcastCacheLocalFile = "./cache/podcastCache.json"
)

var PodcastPlayedCache *zcache.Cache

func ClearPodcastPlayedCache() error {
PodcastPlayedCache.Flush()

err := os.Remove(podcastCacheLocalFile)
if err != nil {
return err
}

return nil
}
59 changes: 43 additions & 16 deletions content/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import (
)

const (
wavFile = "wav"
mp3File = "mp3"
oggFile = "oggs"
flacFile = "flac"
wavFile = "wav"
mp3File = "mp3"
oggFile = "oggs"
flacFile = "flac"
sampleRateTime = 10
)

type LocalFile struct {
Expand All @@ -37,64 +38,78 @@ type LocalFile struct {

func (l *LocalFile) Get() error {
log.Infof("buffering file from %s", l.Path)

f, err := os.Open(l.Path)
if err != nil {
return errors.New(fmt.Sprintf("unable to open file from path: %v", err))
return errors.New(fmt.Sprintf("unable to open file from path: %v", err)) //nolint:lll,revive,gosimple,nolintlint // error pref
}

log.Infof("decoding file from %v", l.Path)
l.Content = f

return nil
}

func (l *LocalFile) Play() error {
var streamer beep.StreamSeekCloser
var format beep.Format
var format beep.Format //nolint:wsl // it's fine for declarations to touch

err := l.setDecoder()
if err != nil {
return errors.New(fmt.Sprintf("error setting decoder: %v", err))
return errors.New(fmt.Sprintf("error setting decoder: %v", err)) //nolint:revive,gosimple // error pref
}

_, err = l.Content.Seek(0, 0)
if err != nil {
return errors.New(fmt.Sprintf("unable to seek to beginning of file: %v", err))
return errors.New(fmt.Sprintf("unable to seek to beginning of file: %v", err)) //nolint:lll,revive,gosimple,nolintlint // error pref
}

if l.fileType == wavFile || l.fileType == flacFile {
streamer, format, err = l.decodeReader(l.Content)
if err != nil {
return errors.New(fmt.Sprintf("unable to decode file: %v", err))
return errors.New(fmt.Sprintf("unable to decode file: %v", err)) //nolint:revive,gosimple // error pref
}
}

if l.fileType == mp3File || l.fileType == oggFile {
streamer, format, err = l.decodeReadCloser(l.Content)
if err != nil {
log.WithError(err).Fatal("unable to decode file")
}
}

log.Infof("playing file buffer from %v", l.Path)
err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))

err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/sampleRateTime))
if err != nil {
return errors.New(fmt.Sprintf("unable to play file: %v", err))
return errors.New(fmt.Sprintf("unable to play file: %v", err)) //nolint:revive,gosimple,nolintlint // error pref
}

done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
speaker.Play(beep.Seq(streamer, beep.Callback(func() { //nolint:wsl // grouping makes sense here
done <- true
})))
<-done

return nil
}

func (l *LocalFile) Stop() error {
log.Infof("file.Stop::Stopping stream from %v ", l.Path)

return nil
}

func (l *LocalFile) setDecoder() error {
buf, err := io.ReadAll(l.Content)
if buf == nil {
return errors.New("empty bytes")
return errors.New("empty bytes") //nolint:goerr113 // we want this error as it is.
}

if err != nil {
return err
}

switch l.getFileType(buf) {
case wavFile:
l.fileType = wavFile
Expand All @@ -109,31 +124,43 @@ func (l *LocalFile) setDecoder() error {
l.fileType = oggFile
l.decodeReadCloser = vorbis.Decode
default:
l.Stop()
err := l.Stop()
if err != nil {
log.WithError(err).Error("localFile.setDecoder::error stopping local file")
}

unknownType, err := filetype.Match(buf)
if err != nil {
log.WithError(err).Error("error getting filetype")
log.WithError(err).Error("localFile.setDecoder::error getting filetype")
}
return errors.New("unsupported filetype " + unknownType.Extension)

return errors.New("unsupported filetype " + unknownType.Extension) //nolint:goerr113 // desired error
}

return nil
}

func (l *LocalFile) getFileType(buf []byte) string {
ext := filepath.Ext(l.Path)
trimmedExt := strings.TrimLeft(ext, ".") // remove the delimiter

// added the trim check because some supported filetypes were not recognized by
// the filetype.IsType function despite having proper extension and working with the respective decoder
if filetype.IsType(buf, filetype.GetType("wav")) || trimmedExt == wavFile {
return wavFile
}

if filetype.IsType(buf, filetype.GetType("mp3")) || trimmedExt == mp3File {
return mp3File
}

if filetype.IsType(buf, filetype.GetType("ogg")) || trimmedExt == oggFile {
return oggFile
}

if filetype.IsType(buf, filetype.GetType("flac")) || trimmedExt == flacFile {
return flacFile
}

return ""
}
Loading

0 comments on commit 0119591

Please sign in to comment.