Skip to content

Commit

Permalink
HTTP verb constant support for net/http (#39)
Browse files Browse the repository at this point in the history
* Add support for `net/http` HTTP verb constants
* Update README with basic instructions for running locally.
* Update gitignore
* Fix removed goreleaser flags in ci.yml
  • Loading branch information
enzowritescode authored Jul 11, 2024
1 parent 2703fdd commit 5fc973b
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 5 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

env:
go-version: "1.19.5"

jobs:
check-golangci-lint:
name: Check golangci-lint
Expand Down Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0
with:
args: release --skip-sign --skip-publish --snapshot --rm-dist
args: release --skip=sign,publish --snapshot --clean

test:
name: Run Tests
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
dist/
.DS_Store
.idea/
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Mattermost Go Vet
# Mattermost Go Vet

This repository contains mattermost-specific go-vet rules that are used to maintain code consistency in `mattermost-server`.

Expand All @@ -16,3 +16,26 @@ This repository contains mattermost-specific go-vet rules that are used to maint
1. **pointerToSlice** - check for usage of pointer to slice in function definitions
1. **mutexLock** - check for cases where a mutex is left locked before returning
1. **wrapError** - check for original errors being passed as details rather then wrapped

## Running Locally
Mattermost Go Vet is designed to run against the `mattermost/mattermost` repo. It assumes that you have the `mattermost/mattermost` and `mattermost/mattermost-govet` in the same top-level directory.

The following can be used to test locally:
```
# ENV vars
MM_ROOT=</path/to/mattermost/>
MM_GOVET=</path/to/mattermost-govet>
GOBIN=</path/to/go/bin>
API_YAML=$MM_ROOT/api/v4/html/static/mattermost-openapi-v4.yaml
# Make OpenAPI file
if [ ! -f $API_YAML ]; then
make -C $MM_ROOT/api build
fi
# Install
go install $MM_GOVET
# Run
go vet -vettool=$GOBIN/mattermost-govet -openApiSync -openApiSync.spec=$API_YAML ./... 2>&1 || true
```
38 changes: 37 additions & 1 deletion openApiSync/openApiSync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"go/ast"
"go/printer"
"go/token"
"net/http"
"os"
"regexp"
"strconv"
Expand Down Expand Up @@ -91,7 +92,8 @@ func processRouterInit(pass *analysis.Pass, names []string, routerPrefixes map[s
continue
}
prefix, _ := strconv.Unquote(aexpr.Args[0].(*ast.BasicLit).Value)
method, _ := strconv.Unquote(expr.X.(*ast.CallExpr).Args[0].(*ast.BasicLit).Value)
method := getMethodFromExpr(expr)

name := aexpr.Fun.(*ast.SelectorExpr).X.(*ast.SelectorExpr).Sel.Name
handler := cleanRegexp(routerPrefixes[name]) + cleanRegexp(prefix)
if stringInSlice(handler, IgnoredCases, true) { // ignore special cases
Expand Down Expand Up @@ -240,3 +242,37 @@ func run(pass *analysis.Pass) (interface{}, error) {

return nil, nil
}

func getMethodFromExpr(expr *ast.ExprStmt) string {
var method string
methodArg := expr.X.(*ast.CallExpr).Args[0]

if methodSelectorExpr, ok := methodArg.(*ast.SelectorExpr); ok {
if methodSelectorExpr.X.(*ast.Ident).Name == "http" {
switch methodSelectorExpr.Sel.Name {
case "MethodGet":
method = http.MethodGet
case "MethodHead":
method = http.MethodHead
case "MethodPost":
method = http.MethodPost
case "MethodPut":
method = http.MethodPut
case "MethodPatch":
method = http.MethodPatch
case "MethodDelete":
method = http.MethodDelete
case "MethodConnect":
method = http.MethodConnect
case "MethodOptions":
method = http.MethodOptions
case "MethodTrace":
method = http.MethodTrace
}
}
} else if methodBasicLit, ok := methodArg.(*ast.BasicLit); ok {
method, _ = strconv.Unquote(methodBasicLit.Value)
}

return method
}
2 changes: 1 addition & 1 deletion openApiSync/testdata/src/api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func (a *API) InitUsers() {
a.BaseRoutes.Users.Handle("/ids", a.ApiSessionRequired(getUsersByIds)).Methods("POST") // want `Cannot find /api/v4/userzs/ids method: POST in OpenAPI 3 spec. \(maybe you meant: \[/api/v4/users/ids\]\)`
a.BaseRoutes.Users.Handle("/ids", a.ApiSessionRequired(getUsersByIds)).Methods(http.MethodPost) // want `Cannot find /api/v4/userzs/ids method: POST in OpenAPI 3 spec. \(maybe you meant: \[/api/v4/users/ids\]\)`
a.BaseRoutes.Groups.Handle("/{group_id:[A-Za-z0-9]+}/{syncable_type:teams|channelz}/{syncable_id:[A-Za-z0-9]+}/link", a.ApiSessionRequired(getUsersByIds)).Methods("POST") // want `Cannot find /api/v4/groups/{group_id}/channelz/{syncable_id}/link method: POST in OpenAPI 3 spec.`

}
Expand Down

0 comments on commit 5fc973b

Please sign in to comment.