Skip to content
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
1 change: 0 additions & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
```bash
make test
make lint
make fmt
```

5. Commit your changes.
Expand Down
31 changes: 24 additions & 7 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,40 @@ concurrency:
cancel-in-progress: true

jobs:
lint:
detect-modules:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install tools
uses: ./.github/actions/install-tools

- name: ensure proper go formatting
run: make check-fmt
- id: set-modules
run: |
MODULES_JSON=$(find . -mindepth 2 -maxdepth 4 -type f -name 'go.mod' | cut -c 3- | sed 's|/go.mod$||' | sort -u | jq -R . | jq -c -s . || echo "[\".\"]")
echo "modules=$MODULES_JSON" >> $GITHUB_OUTPUT
echo "Found modules: $MODULES_JSON"

lint:
needs: detect-modules
runs-on: ubuntu-latest
strategy:
matrix:
modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }}
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install tools
uses: ./.github/actions/install-tools

- name: ensure all modules are on the same go version
run: make check-go-version-consistency

- name: Run Revive Action by pulling pre-built image
uses: docker://morphy/revive-action@sha256:087d4e61077087755711ab7e9fae3cc899b7bb07ff8f6a30c3dfb240b1620ae8 #v2.5.7
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # v7.0.0
with:
config: revive.toml
path: "./..."
working-directory: ${{ matrix.modules }}
82 changes: 82 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
version: "2"
linters:
default: none
enable:
- errcheck
- errorlint
- goheader
- govet
- ineffassign
- nolintlint
- revive
- staticcheck
- testifylint
- unused
- whitespace
settings:
errcheck:
check-type-assertions: true
goheader:
template: |-
SPDX-License-Identifier: Apache-2.0
SPDX-FileCopyrightText: 2024-Present Defense Unicorns
govet:
disable:
- shadow
- fieldalignment
- unusedwrite
- printf
enable-all: true
nolintlint:
require-specific: true
revive:
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: redefines-builtin-id
testifylint:
enable-all: true
exclusions:
generated: lax
presets:
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- goimports
settings:
goimports:
local-prefixes:
- github.com/defenseunicorns
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
9 changes: 1 addition & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,8 @@ repos:

- repo: local
hooks:

- id: fmt
name: go fmt
entry: make fmt
language: system
pass_filenames: false

- id: lint
name: go lint
name: golangci-lint
entry: make lint
language: system
pass_filenames: false
29 changes: 10 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,23 @@ tidy:
tidy-%:
cd $(subst :,/,$*); go mod tidy

fmt:
$(MAKE) $(addprefix fmt-, $(MODULES))

fmt-%:
cd $(subst :,/,$*); go fmt ./...

check-fmt:
$(MAKE) $(addprefix check-fmt-, $(MODULES))

check-fmt-%:
cd $(subst :,/,$*); test -z "$$(gofmt -l .)"

vet:
$(MAKE) $(addprefix vet-, $(MODULES))

vet-%:
cd $(subst :,/,$*); go vet ./... ;\

test:
$(MAKE) $(addprefix test-, $(MODULES))

test-%:
cd $(subst :,/,$*); go test ./... -coverprofile cover.out ;

lint:
revive -config revive.toml ./...
$(MAKE) $(addprefix lint-, $(MODULES))

lint-fix:
$(MAKE) $(addprefix lint-fix-, $(MODULES))

lint-%:
cd $(subst :,/,$*); golangci-lint run ./...

lint-fix-%:
cd $(subst :,/,$*); golangci-lint run --fix ./...

scan:
$(MAKE) $(addprefix scan-, $(MODULES))
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ View the [`Makefile`](Makefile) for available targets.

```bash
# Run all formatters
make fmt
make lint-fix

# Run all linters
make lint
Expand All @@ -36,7 +36,7 @@ To run any of the above against an individual module, append `-<module name>` to

```bash
# Run all formatters for the helpers module
make fmt-helpers
make lint-fix-helpers

# Run all linters for the helpers module
make lint-helpers
Expand Down
11 changes: 5 additions & 6 deletions hack/check_go_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
set -euo pipefail

first_version=""
# Find and iterate over all go.mod files, excluding the vendor directory
find . -name go.mod | while read -r mod; do
while read -r mod; do
current_version=$(grep '^go 1\.' "$mod" | cut -d ' ' -f 2)

if [[ -z "$first_version" ]]; then
first_version=$current_version
first_version=$current_version
elif [[ "$current_version" != "$first_version" ]]; then
echo "Inconsistency found: $mod uses Go version $current_version, this differs from another found version $first_version."
exit 1
echo "Inconsistency found: $mod uses Go version $current_version, this differs from another found version $first_version."
exit 1
fi
done
done < <(find . -name go.mod -not -path '*/vendor/*')

echo "All modules use the same Go version: $first_version."
8 changes: 1 addition & 7 deletions helpers/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func CreateFile(filepath string) error {
}

return nil

}

// InvalidPath checks if the given path is valid (if it is a permissions error it is there we just don't have access)
Expand Down Expand Up @@ -68,7 +67,6 @@ func ListDirectories(directory string) ([]string, error) {
// If skipHidden is true, hidden directories will be skipped.
func RecursiveFileList(dir string, pattern *regexp.Regexp, skipHidden bool) (files []string, err error) {
err = filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {

// Return errors
if err != nil {
return err
Expand Down Expand Up @@ -132,11 +130,7 @@ func ReadFileByChunks(path string, chunkSizeBytes int) (chunks [][]byte, sha256s
sha256sum = fmt.Sprintf("%x", sha256.Sum256(file))

// Loop over the tarball breaking it into chunks based on the payloadChunkSize
for {
if len(file) == 0 {
break
}

for len(file) != 0 {
// don't bust slice length
if len(file) < chunkSizeBytes {
chunkSizeBytes = len(file)
Expand Down
47 changes: 27 additions & 20 deletions helpers/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func RetryWithContext(ctx context.Context, fn func() error, attempts int, delay
var err error
timer := time.NewTimer(0)
defer timer.Stop()
for r := 0; r < attempts; r++ {
for r := range attempts {
select {
case <-ctx.Done():
return ctx.Err()
Expand Down Expand Up @@ -92,17 +92,13 @@ func TransformAndMergeMap[T any](m1, m2 map[string]T, transform func(string) str
}

// MergeMapRecursive recursively (nestedly) merges map m2 with m1 overwriting common values with m2's values.
func MergeMapRecursive(m1, m2 map[string]interface{}) (r map[string]interface{}) {
r = map[string]interface{}{}

for key, value := range m1 {
r[key] = value
}
func MergeMapRecursive(m1, m2 map[string]any) (r map[string]any) {
r = maps.Clone(m1)

for key, value := range m2 {
if value, ok := value.(map[string]interface{}); ok {
if value, ok := value.(map[string]any); ok {
if nestedValue, ok := r[key]; ok {
if nestedValue, ok := nestedValue.(map[string]interface{}); ok {
if nestedValue, ok := nestedValue.(map[string]any); ok {
r[key] = MergeMapRecursive(nestedValue, value)
continue
}
Expand Down Expand Up @@ -140,31 +136,42 @@ func IsNotZeroAndNotEqual[T any](given T, equal T) bool {
return true
}

for i := 0; i < givenValue.NumField(); i++ {
for i := range givenValue.NumField() {
if !givenValue.Field(i).IsZero() &&
givenValue.Field(i).CanInterface() &&
givenValue.Field(i).Interface() != equalValue.Field(i).Interface() {

return true
}
}
return false
}

// MergeNonZero is used to merge non-zero overrides from one struct into another of the same type
func MergeNonZero[T any](original T, overrides T) T {
originalValue := reflect.ValueOf(&original)
overridesValue := reflect.ValueOf(&overrides)
func MergeNonZero[T any](original, overrides T) T {
// Create a copy of original that we'll modify
result := original

for i := 0; i < originalValue.Elem().NumField(); i++ {
if !overridesValue.Elem().Field(i).IsZero() &&
overridesValue.Elem().Field(i).CanSet() {
// Get reflect values, using the actual values not pointers to them
resultValue := reflect.ValueOf(&result).Elem()
overridesValue := reflect.ValueOf(overrides)

overrideField := overridesValue.Elem().Field(i)
originalValue.Elem().Field(i).Set(overrideField)
// Ensure we're working with structs
if resultValue.Kind() != reflect.Struct || overridesValue.Kind() != reflect.Struct {
return original // Can't merge non-structs
}

// Iterate through fields
for i := range resultValue.NumField() {
resultField := resultValue.Field(i)
overrideField := overridesValue.Field(i)

// Check if override field is non-zero and result field can be set
if !overrideField.IsZero() && resultField.CanSet() {
resultField.Set(overrideField)
}
}
return originalValue.Elem().Interface().(T)

return result
}

// MergePathAndValueIntoMap takes a path in dot notation as a string and a value (also as a string for simplicity),
Expand Down
Loading
Loading