Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

downloader: pre/post request hooks #22

Merged
merged 5 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.21.7
go-version: 1.23

- name: Run unit tests
run: |
Expand All @@ -35,7 +35,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.57
version: v1.62
args: --issues-exit-code=1 --timeout 10m
only-new-issues: false
# the cache is already managed above, enabling it here
Expand Down
112 changes: 4 additions & 108 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,123 +124,26 @@ linters:
#
# DEPRECATED by golangi-lint
#
- deadcode
- exhaustivestruct
- golint
- ifshort
- interfacer
- maligned
- nosnakecase
- scopelint
- structcheck
- varcheck

#
# Disabled until fixed for go 1.22
#

- copyloopvar # copyloopvar is a linter detects places where loop variables are copied
- intrange # intrange is a linter to find places where for loops could make use of an integer range.

#
# Enabled
#

# - asasalint # check for pass []any as any in variadic func(...any)
# - asciicheck # checks that all code identifiers does not have non-ASCII symbols in the name
# - bidichk # Checks for dangerous unicode character sequences
# - bodyclose # checks whether HTTP response body is closed successfully
# - cyclop # checks function and package cyclomatic complexity
# - 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
# - dupword # checks for duplicate words in the source code
# - durationcheck # check for two durations multiplied together
# - errcheck # errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases
# - errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
# - execinquery # execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds
# - exportloopref # checks for pointers to enclosing loop variables
# - funlen # Tool for detection of long functions
# - ginkgolinter # enforces standards of using ginkgo and gomega
# - gocheckcompilerdirectives # Checks that go compiler directive comments (//go:) are valid.
# - gochecknoinits # Checks that no init functions are present in Go code
# - gochecksumtype # Run exhaustiveness checks on Go "sum types"
# - gocognit # Computes and checks the cognitive complexity of functions
# - gocritic # Provides diagnostics that check for bugs, performance and style issues.
# - gocyclo # Computes and checks the cyclomatic complexity of functions
# - goheader # Checks is file header matches to pattern
# - 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
# - gosimple # (megacheck): Linter for Go source code that specializes in simplifying code
# - gosmopolitan # Report certain i18n/l10n anti-patterns in your Go codebase
# - govet # (vet, vetshadow): Vet examines Go source code and reports suspicious constructs. It is roughly the same as 'go vet' and uses its passes.
# - grouper # Analyze expression groups.
# - importas # Enforces consistent import aliases
# - ineffassign # Detects when assignments to existing variables are not used
# - interfacebloat # A linter that checks the number of methods inside an interface.
# - lll # Reports long lines
# - loggercheck # (logrlint): Checks key value pairs for common logger libraries (kitlog,klog,logr,zap).
# - logrlint # Check logr arguments.
# - maintidx # maintidx measures the maintainability index of each function.
# - makezero # Finds slice declarations with non-zero initial length
# - mirror # reports wrong mirror patterns of bytes/strings usage
# - misspell # Finds commonly misspelled English words
# - nakedret # Checks that functions with naked returns are not longer than a maximum size (can be zero).
# - nestif # Reports deeply nested if statements
# - nilerr # Finds the code that returns nil even if it checks that the error is not nil.
# - nolintlint # Reports ill-formed or insufficient nolint directives
# - nonamedreturns # Reports all named returns
# - nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL.
# - perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative.
# - predeclared # find code that shadows one of Go's predeclared identifiers
# - reassign # Checks that package variables are not reassigned
# - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.
# - rowserrcheck # checks whether Rows.Err of rows is checked successfully
# - sloglint # ensure consistent code style when using log/slog
# - spancheck # Checks for mistakes with OpenTelemetry/Census spans.
# - sqlclosecheck # Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed.
# - staticcheck # (megacheck): It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.
# - tenv # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
# - testableexamples # linter checks if examples are testable (have an expected output)
# - testifylint # Checks usage of github.com/stretchr/testify.
# - tparallel # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
# - unconvert # Remove unnecessary type conversions
# - unused # (megacheck): Checks Go code for unused constants, variables, functions and types
# - usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library.
# - wastedassign # Finds wasted assignment statements
# - zerologlint # Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg`
- exportloopref

#
# Recommended? (easy)
#

- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted.
- exhaustive # check exhaustiveness of enum switch statements
- gci # Gci control golang package import order and make it always deterministic.
- godot # Check if comments end in a period
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification
- goimports # Check import statements are formatted according to the 'goimport' command. Reformat imports in autofix mode.
- gosec # (gas): Inspects source code for security problems
- inamedparam # reports interfaces with unnamed method parameters
- musttag # enforce field tags in (un)marshaled structs
- promlinter # Check Prometheus metrics naming via promlint
- protogetter # Reports direct reads from proto message fields when getters should be used
- tagalign # check that struct tags are well aligned
- thelper # thelper detects tests helpers which is not start with t.Helper() method.
- wrapcheck # Checks that errors returned from external packages are wrapped

#
# Recommended? (requires some work)
#

- containedctx # containedctx is a linter that detects struct contained context.Context field
- contextcheck # check whether the function uses a non-inherited context
- errname # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.
- gomnd # An analyzer to detect magic numbers.
- ireturn # Accept Interfaces, Return Concrete Types
- mnd # An analyzer to detect magic numbers.
- nilnil # Checks that there is no simultaneous return of `nil` error and an invalid value.
- noctx # Finds sending http request without context.Context
- unparam # Reports unused function parameters

#
Expand All @@ -249,28 +152,21 @@ linters:

- gofumpt # Gofumpt checks whether code was gofumpt-ed.
- nlreturn # nlreturn checks for a new line before return and branch statements to increase code clarity
- whitespace # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc.
- wsl # add or remove empty lines

#
# Well intended, but not ready for this
#
- dupl # Tool for code clone detection
- forcetypeassert # finds forced type assertions
- godox # Tool for detection of FIXME, TODO and other comment keywords
- goerr113 # Go linter to check the errors handling expressions
- err113 # Go linter to check the errors handling expressions
- paralleltest # Detects missing usage of t.Parallel() method in your Go test
- testpackage # linter that makes you use a separate _test package

#
# Too strict / too many false positives (for now?)
#
- exhaustruct # Checks if all structure fields are initialized
- forbidigo # Forbids identifiers
- gochecknoglobals # Check that no global variables exist.
- goconst # Finds repeated strings that could be replaced by a constant
- stylecheck # Stylecheck is a replacement for golint
- tagliatelle # Checks the struct tags.
- varnamelen # checks that the length of a variable's name matches its scope

#
Expand All @@ -290,7 +186,7 @@ issues:
- yamlpatch/merge.go
- yamlpatch/merge_test.go

exclude-generated-strict: true
exclude-generated: strict

max-issues-per-linter: 0
max-same-issues: 0
Expand Down
1 change: 0 additions & 1 deletion csstring/expand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ func TestStrictExpand(t *testing.T) {
}

for _, tc := range tests {
tc := tc
t.Run(tc.input, func(t *testing.T) {
t.Parallel()

Expand Down
14 changes: 12 additions & 2 deletions downloader/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (e NotFoundError) Error() string {
return "document not found at " + e.URL
}

// BadHTTPCodeError returned when the server responds with unexpected HTTP code.
// BadHTTPCodeError is returned when the server responds with unexpected HTTP code.
type BadHTTPCodeError struct {
URL string
Code int
Expand All @@ -42,6 +42,16 @@ func (e BadHTTPCodeError) Error() string {
return fmt.Sprintf("bad HTTP code %d for %s", e.Code, e.URL)
}

// HashMismatchError is returned when the downloaded file does not match the expected hash.
type HashMismatchError struct {
Expected string
Got string
}

func (e HashMismatchError) Error() string {
return fmt.Sprintf("hash mismatch: expected %s, got %s", e.Expected, e.Got)
}

func nullLogger() *logrus.Entry {
log := logrus.New()
log.SetOutput(io.Discard)
Expand Down Expand Up @@ -635,7 +645,7 @@ func (d *Downloader) Download(ctx context.Context, url string) (bool, error) {
if hasher != nil {
got := hex.EncodeToString(hasher.Sum(nil))
if got != d.verifyHashValue {
return false, fmt.Errorf("hash mismatch: expected %s, got %s", d.verifyHashValue, got)
return false, HashMismatchError{Expected: d.verifyHashValue, Got: got}
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/crowdsecurity/go-cs-lib

go 1.20
go 1.23

require (
github.com/blackfireio/osinfo v1.0.5
Expand Down
12 changes: 12 additions & 0 deletions slicetools/backward.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package slicetools

// Backward iterates over a slice in reverse order.
func Backward[E any](s []E) func(func(int, E) bool) {
return func(yield func(int, E) bool) {
for i := len(s)-1; i >= 0; i-- {
if !yield(i, s[i]) {
return
}
}
}
}
74 changes: 74 additions & 0 deletions slicetools/backward_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package slicetools

import (
"testing"

"github.com/stretchr/testify/assert"
)


func TestBackwardInts(t *testing.T) {
ints := []int{10, 20, 30, 40, 50}
expected := []int{50, 40, 30, 20, 10}
expectedIdx := []int{4, 3, 2, 1, 0}

result := []int{}
resultIdx := []int{}

for i, value := range Backward(ints) {
result = append(result, value)
resultIdx = append(resultIdx, i)
}

assert.Equal(t, expected, result)
assert.Equal(t, expectedIdx, resultIdx)
}

// TestBackwardStrings tests the Backward function with a slice of strings.
func TestBackwardStrings(t *testing.T) {
strs := []string{"apple", "banana", "cherry", "date"}
expected := []string{"date", "cherry", "banana", "apple"}
expectedIdx := []int{3, 2, 1, 0}

result := []string{}
resultIdx := []int{}

for i, value := range Backward(strs) {
result = append(result, value)
resultIdx = append(resultIdx, i)
}

assert.Equal(t, expected, result)
assert.Equal(t, expectedIdx, resultIdx)
}

func TestBackwardEarlyTermination(t *testing.T) {
ints := []int{10, 20, 30, 40, 50}
expected := []int{50, 40, 30} // Stop after reaching 30

var result []int

for _, value := range Backward(ints) {
result = append(result, value)
if value == 30 {
break
}
}

assert.Equal(t, expected, result)
}

func TestBackwardEmptySlice(t *testing.T) {
ints := []int{}

result := []int{}
resultIdx := []int{}

for i, value := range Backward(ints) {
result = append(result, value)
resultIdx = append(resultIdx, i)
}

assert.Empty(t, result)
assert.Empty(t, resultIdx)
}
2 changes: 0 additions & 2 deletions yamlpatch/patcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ func TestMergedPatchContent(t *testing.T) {
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -287,7 +286,6 @@ func TestPrependedPatchContent(t *testing.T) {
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

Expand Down
Loading