diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b92430fd..4d19d148 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -14,10 +14,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: 'stable' - - - run: test -z "$(gofmt -l .)" || { gofmt -d .; exit 1; } - name: gofmt + go-version: '1.26.6' - run: go vet ./... @@ -27,3 +24,66 @@ jobs: - run: go mod tidy && git diff --exit-code go.mod go.sum name: go mod tidy is up to date + + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.26.6' + + - name: Check gofmt -s + run: | + unformatted=$(gofmt -l -s .) + if [ -n "$unformatted" ]; then + echo "These files need 'gofmt -s -w':" + echo "$unformatted" + exit 1 + fi + + - name: Check go fix ./... + if: ${{ !cancelled() }} + run: | + changed=$(go fix -diff ./... 2>/dev/null | sed -n "s#^--- $PWD/\(.*\) (old)#\1#p") + if [ -n "$changed" ]; then + echo "These files need 'go fix ./...':" + echo "$changed" + exit 1 + fi + + analysis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.26.6' + + - name: gopls modernize + run: go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest ./... + + - uses: golangci/golangci-lint-action@v8 + if: ${{ !cancelled() }} + with: + version: v2.12.2 + + security: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.26.6' + + - uses: actions/cache@v4 + with: + path: ~/go/bin/govulncheck + key: govulncheck-v1.6.0 + - name: install govulncheck + run: test -x ~/go/bin/govulncheck || go install golang.org/x/vuln/cmd/govulncheck@v1.6.0 + - name: govulncheck + run: govulncheck ./... diff --git a/internal/aggregate/aggregate.go b/internal/aggregate/aggregate.go index f74a0624..060210fe 100644 --- a/internal/aggregate/aggregate.go +++ b/internal/aggregate/aggregate.go @@ -3,6 +3,7 @@ package aggregate import ( + "slices" "sort" "strconv" @@ -99,12 +100,7 @@ func functionKey(name string, position int) string { } func contains(values []string, needle string) bool { - for _, value := range values { - if value == needle { - return true - } - } - return false + return slices.Contains(values, needle) } func without(values []string, needle string) []string { diff --git a/internal/apply/apply.go b/internal/apply/apply.go index d7b12980..f60d6a98 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -211,8 +211,8 @@ func takeVarLeading(param *ast.Parameter) []*token.Token { // typeText turns a resolved type into the text written into source. The trailing // space that separates the type from the variable is added by the caller. func typeText(resolved string) string { - if strings.HasPrefix(resolved, "object:") { - return "\\" + strings.TrimPrefix(resolved, "object:") + if after, ok := strings.CutPrefix(resolved, "object:"); ok { + return "\\" + after } return resolved } diff --git a/internal/collect/collect.go b/internal/collect/collect.go index 3cb66cf1..bf622ed8 100644 --- a/internal/collect/collect.go +++ b/internal/collect/collect.go @@ -3,6 +3,7 @@ package collect import ( + "maps" "strings" "github.com/rectorphp/argtyper/internal/phpast" @@ -216,9 +217,7 @@ func (c *collector) classProperties(class ast.Vertex, enclosing string) map[stri if phpast.ShortName(typed.Name) != "__construct" { continue } - for name, className := range c.promotedProperties(typed.Params, enclosing) { - properties[name] = className - } + maps.Copy(properties, c.promotedProperties(typed.Params, enclosing)) } } @@ -301,12 +300,8 @@ func merge(base, over map[string]string) map[string]string { return base } merged := make(map[string]string, len(base)+len(over)) - for name, class := range base { - merged[name] = class - } - for name, class := range over { - merged[name] = class - } + maps.Copy(merged, base) + maps.Copy(merged, over) return merged } diff --git a/internal/phpast/phpast.go b/internal/phpast/phpast.go index e91f347c..867f8f74 100644 --- a/internal/phpast/phpast.go +++ b/internal/phpast/phpast.go @@ -24,7 +24,7 @@ var docParamLine = regexp.MustCompile(`^\s*\*?\s*@param\s+(\S+)\s+\$(\w+)\s*$`) var phpVersion, _ = version.New("8.3") -var vertexType = reflect.TypeOf((*ast.Vertex)(nil)).Elem() +var vertexType = reflect.TypeFor[ast.Vertex]() // Parse turns PHP source into an AST root. func Parse(src []byte) (ast.Vertex, error) { @@ -45,8 +45,7 @@ func Children(node ast.Vertex) []ast.Vertex { value := reflect.ValueOf(node).Elem() var children []ast.Vertex - for i := 0; i < value.NumField(); i++ { - field := value.Field(i) + for _, field := range value.Fields() { switch field.Kind() { case reflect.Interface: