diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 03a3aeb..e26b031 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -31,16 +31,24 @@ jobs: - name: File names run: .github/.goassets/scripts/lint-filename.sh - - name: Contributors - run: .github/assert-contributors.sh + - name: Logging messages should not have trailing newlines + run: .github/.goassets/scripts/lint-no-trailing-newline-in-log-messages.sh + + - name: Go version in go.mod + run: .github/.goassets/scripts/lint-go-mod-version.sh lint-go: name: Go runs-on: ubuntu-latest - strategy: - fail-fast: false + permissions: + contents: read + pull-requests: read steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + + - uses: actions/setup-go@v4 + with: + go-version: 'stable' - name: Update packages run: sudo apt-get update @@ -53,8 +61,7 @@ jobs: - name: Build data-channels run: cd c-data-channels && make - - name: Install golangci-lint - run: curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b /tmp v1.19.1 - - - name: Run golangci-lint - run: go list -f '{{.Dir}}' ./... | fgrep -v c-data-channels | xargs realpath --relative-to=. | xargs /tmp/golangci-lint run -v + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.52.2 diff --git a/.golangci.yml b/.golangci.yml index 6f07ab1..ef8f221 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,16 +1,129 @@ +# SPDX-FileCopyrightText: 2023 The Pion community +# SPDX-License-Identifier: MIT + linters-settings: govet: check-shadowing: true misspell: locale: US + gomodguard: + blocked: + modules: + - github.com/pkg/errors: + recommendations: + - errors + forbidigo: + forbid: + - ^print(ln)?$ + revive: + rules: + - name: package-comments + disabled: true linters: - enable-all: true + enable: + - asciicheck # Simple linter to check that your code does not contain non-ASCII identifiers + - bidichk # Checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context + - decorder # check declaration order and count of types, constants, variables and functions + - depguard # Go linter that checks if package imports are in a list of acceptable packages + - dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) + - dupl # Tool for code clone detection + - durationcheck # check for two durations multiplied together + - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + - errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted. + - errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. + - exportloopref # checks for pointers to enclosing loop variables + - forbidigo # Forbids identifiers + - gci # Gci control golang package import order and make it always deterministic. + - goconst # Finds repeated strings that could be replaced by a constant + - gocritic # The most opinionated Go source code linter + - godox # Tool for detection of FIXME, TODO and other comment keywords + - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification + - gofumpt # Gofumpt checks whether code was gofumpt-ed. + - goheader # Checks is file header matches to pattern + - goimports # Goimports does everything that gofmt does. Additionally it checks unused imports + - gomoddirectives # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. + - gomodguard # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. + - goprintffuncname # Checks that printf-like functions are named with `f` at the end + - gosec # Inspects source code for security problems + - gosimple # Linter for Go source code that specializes in simplifying a code + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - grouper # An analyzer to analyze expression groups. + - importas # Enforces consistent import aliases + - ineffassign # Detects when assignments to existing variables are not used + - misspell # Finds commonly misspelled English words in comments + - nakedret # Finds naked returns in functions greater than a specified function length + - nilerr # Finds the code that returns nil even if it checks that the error is not nil. + - nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value. + - noctx # noctx finds sending http request without context.Context + - predeclared # find code that shadows one of Go's predeclared identifiers + - revive # golint replacement, finds style mistakes + - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks + - stylecheck # Stylecheck is a replacement for golint + - tagliatelle # Checks the struct tags. + - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code + - unconvert # Remove unnecessary type conversions + - unparam # Reports unused function parameters + - unused # Checks Go code for unused constants, variables, functions and types + - wastedassign # wastedassign finds wasted assignment statements + - whitespace # Tool for detection of leading and trailing whitespace disable: - - lll - - gochecknoinits - - gochecknoglobals - - funlen + - containedctx # containedctx is a linter that detects struct contained context.Context field + - cyclop # checks function and package cyclomatic complexity + - exhaustivestruct # Checks if all struct's fields are initialized + - funlen # Tool for detection of long functions + - gocyclo # Computes and checks the cyclomatic complexity of functions + - godot # Check if comments end in a period + - gomnd # An analyzer to detect magic numbers. + - ifshort # Checks that your code uses short syntax for if-statements whenever possible + - ireturn # Accept Interfaces, Return Concrete Types + - lll # Reports long lines + - maintidx # maintidx measures the maintainability index of each function. + - makezero # Finds slice declarations with non-zero initial length + - maligned # Tool to detect Go structs that would take less memory if their fields were sorted + - nestif # Reports deeply nested if statements + - nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity + - nolintlint # Reports ill-formed or insufficient nolint directives + - paralleltest # paralleltest detects missing usage of t.Parallel() method in your Go test + - prealloc # Finds slice declarations that could potentially be preallocated + - promlinter # Check Prometheus metrics naming via promlint + - rowserrcheck # checks whether Err of rows is checked successfully + - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed. + - testpackage # linter that makes you use a separate _test package + - thelper # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers + - varnamelen # checks that the length of a variable's name matches its scope + - wrapcheck # Checks that errors returned from external packages are wrapped + - wsl # Whitespace Linter - Forces you to use empty lines! issues: exclude-use-default: false + exclude-rules: + # Allow complex tests, better to be self contained + - path: _test\.go + linters: + - gocognit + - forbidigo + + # Allow complex main function in examples + - path: examples + text: "of func `main` is high" + linters: + - gocognit + + # Allow forbidden identifiers in examples + - path: examples + linters: + - forbidigo + + # Allow forbidden identifiers in CLI commands + - path: cmd + linters: + - forbidigo + +run: + skip-dirs: + - c-data-channels diff --git a/examples.go b/examples.go index 0cc8465..ba172a3 100644 --- a/examples.go +++ b/examples.go @@ -100,7 +100,7 @@ func serve(addr string) error { }) // Start the server - return http.ListenAndServe(addr, nil) + return http.ListenAndServe(addr, nil) // nolint:gosec } // getExamples loads the examples from the examples.json file. diff --git a/gocv-receive/main.go b/gocv-receive/main.go index d4de6be..5f7994a 100644 --- a/gocv-receive/main.go +++ b/gocv-receive/main.go @@ -1,3 +1,4 @@ +//go:build gocv // +build gocv package main @@ -121,7 +122,6 @@ func startGoCVMotionDetect(ffmpegOut io.Reader) { break } } - } func createWebRTCConn(ffmpegIn io.Writer) { diff --git a/gstreamer-receive/main.go b/gstreamer-receive/main.go index e2ed445..c403cb1 100644 --- a/gstreamer-receive/main.go +++ b/gstreamer-receive/main.go @@ -6,11 +6,10 @@ import ( "strings" "time" - "github.com/pion/rtcp" - "github.com/pion/webrtc/v3" - gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-sink" "github.com/pion/example-webrtc-applications/v3/internal/signal" + "github.com/pion/rtcp" + "github.com/pion/webrtc/v3" ) // gstreamerReceiveMain is launched in a goroutine because the main thread is needed diff --git a/gstreamer-send-offer/main.go b/gstreamer-send-offer/main.go index 24e82f6..88f44fe 100644 --- a/gstreamer-send-offer/main.go +++ b/gstreamer-send-offer/main.go @@ -4,10 +4,9 @@ import ( "flag" "fmt" - "github.com/pion/webrtc/v3" - gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-src" "github.com/pion/example-webrtc-applications/v3/internal/signal" + "github.com/pion/webrtc/v3" ) func main() { diff --git a/gstreamer-send/main.go b/gstreamer-send/main.go index 9e2bf13..c5b040b 100644 --- a/gstreamer-send/main.go +++ b/gstreamer-send/main.go @@ -4,10 +4,9 @@ import ( "flag" "fmt" - "github.com/pion/webrtc/v3" - gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-src" "github.com/pion/example-webrtc-applications/v3/internal/signal" + "github.com/pion/webrtc/v3" ) func main() { diff --git a/internal/gstreamer-sink/gst.go b/internal/gstreamer-sink/gst.go index bfb1b94..d5c9e34 100644 --- a/internal/gstreamer-sink/gst.go +++ b/internal/gstreamer-sink/gst.go @@ -8,6 +8,7 @@ package gst */ import "C" + import ( "fmt" "strings" diff --git a/internal/gstreamer-src/gst.go b/internal/gstreamer-src/gst.go index 969d2d0..1b76e50 100644 --- a/internal/gstreamer-src/gst.go +++ b/internal/gstreamer-src/gst.go @@ -8,6 +8,7 @@ package gst */ import "C" + import ( "fmt" "sync" @@ -31,8 +32,10 @@ type Pipeline struct { clockRate float32 } -var pipelines = make(map[int]*Pipeline) -var pipelinesLock sync.Mutex +var ( + pipelines = make(map[int]*Pipeline) + pipelinesLock sync.Mutex +) const ( videoClockRate = 90000 diff --git a/internal/signal/http.go b/internal/signal/http.go index dbc2bee..f024c2f 100644 --- a/internal/signal/http.go +++ b/internal/signal/http.go @@ -21,7 +21,7 @@ func HTTPSDPServer() chan string { }) go func() { - err := http.ListenAndServe(":"+strconv.Itoa(*port), nil) + err := http.ListenAndServe(":"+strconv.Itoa(*port), nil) // nolint:gosec if err != nil { panic(err) } diff --git a/internal/signal/rand.go b/internal/signal/rand.go deleted file mode 100644 index e729bd4..0000000 --- a/internal/signal/rand.go +++ /dev/null @@ -1,17 +0,0 @@ -package signal - -import ( - "math/rand" - "time" -) - -// RandSeq generates a random string to serve as dummy data -func RandSeq(n int) string { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - b := make([]rune, n) - for i := range b { - b[i] = letters[r.Intn(len(letters))] - } - return string(b) -} diff --git a/janus-gateway/streaming/main.go b/janus-gateway/streaming/main.go index 6a0e125..0894ff4 100644 --- a/janus-gateway/streaming/main.go +++ b/janus-gateway/streaming/main.go @@ -111,10 +111,12 @@ func main() { // We must offer to send media for Janus to send anything if _, err = peerConnection.AddTransceiverFromKind(webrtc.RTPCodecTypeAudio, webrtc.RTPTransceiverInit{ - Direction: webrtc.RTPTransceiverDirectionRecvonly}); err != nil { + Direction: webrtc.RTPTransceiverDirectionRecvonly, + }); err != nil { panic(err) } else if _, err = peerConnection.AddTransceiverFromKind(webrtc.RTPCodecTypeVideo, webrtc.RTPTransceiverInit{ - Direction: webrtc.RTPTransceiverDirectionRecvonly}); err != nil { + Direction: webrtc.RTPTransceiverDirectionRecvonly, + }); err != nil { panic(err) } diff --git a/janus-gateway/video-room/main.go b/janus-gateway/video-room/main.go index 1acc80a..e6ab4a3 100644 --- a/janus-gateway/video-room/main.go +++ b/janus-gateway/video-room/main.go @@ -6,9 +6,8 @@ import ( "time" janus "github.com/notedit/janus-go" - "github.com/pion/webrtc/v3" - gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-src" + "github.com/pion/webrtc/v3" ) func watchHandle(handle *janus.Handle) { diff --git a/play-from-disk-h264/main.go b/play-from-disk-h264/main.go index d198fcb..a5756ad 100644 --- a/play-from-disk-h264/main.go +++ b/play-from-disk-h264/main.go @@ -1,3 +1,4 @@ +//go:build !js // +build !js package main diff --git a/rtmp-to-webrtc/main.go b/rtmp-to-webrtc/main.go index 1145966..d661aa0 100644 --- a/rtmp-to-webrtc/main.go +++ b/rtmp-to-webrtc/main.go @@ -1,3 +1,4 @@ +//go:build !js // +build !js package main diff --git a/save-to-webm/main.go b/save-to-webm/main.go index 18b4b00..08e24d1 100644 --- a/save-to-webm/main.go +++ b/save-to-webm/main.go @@ -8,7 +8,6 @@ import ( "time" "github.com/at-wat/ebml-go/webm" - webrtcsignal "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/rtp" @@ -57,6 +56,7 @@ func (s *webmSaver) Close() { } } } + func (s *webmSaver) PushOpus(rtpPacket *rtp.Packet) { s.audioBuilder.Push(rtpPacket) @@ -73,6 +73,7 @@ func (s *webmSaver) PushOpus(rtpPacket *rtp.Packet) { } } } + func (s *webmSaver) PushVP8(rtpPacket *rtp.Packet) { s.videoBuilder.Push(rtpPacket) @@ -102,8 +103,9 @@ func (s *webmSaver) PushVP8(rtpPacket *rtp.Packet) { } } } + func (s *webmSaver) InitWriter(width, height int) { - w, err := os.OpenFile("test.webm", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + w, err := os.OpenFile("test.webm", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o600) if err != nil { panic(err) } diff --git a/sfu-ws/main.go b/sfu-ws/main.go index f854295..e173cc9 100644 --- a/sfu-ws/main.go +++ b/sfu-ws/main.go @@ -71,7 +71,7 @@ func main() { }() // start HTTP server - log.Fatal(http.ListenAndServe(*addr, nil)) + log.Fatal(http.ListenAndServe(*addr, nil)) // nolint:gosec } // Add to list of tracks and fire renegotation for all PeerConnections diff --git a/snapshot/main.go b/snapshot/main.go index e00403c..c9268df 100644 --- a/snapshot/main.go +++ b/snapshot/main.go @@ -168,5 +168,5 @@ func main() { http.HandleFunc("/snapshot", snapshot) fmt.Println("Open http://localhost:8080 to access this demo") - panic(http.ListenAndServe(":8080", nil)) + panic(http.ListenAndServe(":8080", nil)) // nolint:gosec } diff --git a/twitch/main.go b/twitch/main.go index 0f5c4f8..9517904 100644 --- a/twitch/main.go +++ b/twitch/main.go @@ -9,13 +9,12 @@ import ( "time" "github.com/at-wat/ebml-go/webm" + "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/rtp" "github.com/pion/rtp/codecs" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media/samplebuilder" - - "github.com/pion/example-webrtc-applications/v3/internal/signal" ) var ( diff --git a/unreal-pixel-streaming/main.go b/unreal-pixel-streaming/main.go index fae5652..7102851 100644 --- a/unreal-pixel-streaming/main.go +++ b/unreal-pixel-streaming/main.go @@ -82,7 +82,7 @@ func main() { } // Given a Configuration create a PeerConnection and set the appropriate handlers. -//nolint +// nolint func createPeerConnection(conn *websocket.Conn, configuration webrtc.Configuration) *webrtc.PeerConnection { m := &webrtc.MediaEngine{}