Skip to content

Commit

Permalink
add multitype and runtime validations
Browse files Browse the repository at this point in the history
  • Loading branch information
ori-shalom committed Jan 17, 2023
1 parent d33305a commit 9bb5c2d
Show file tree
Hide file tree
Showing 63 changed files with 1,924 additions and 715 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ test-coverage: $(COVERAGE_PROFILE_FILE)
$(COVERAGE_HTML_FILE): $(COVERAGE_PROFILE_FILE)
@go tool cover -html=$(COVERAGE_PROFILE_FILE) -o $(COVERAGE_HTML_FILE)

FILE ?= file0

.PHONY: show-coverage
show-coverage: $(COVERAGE_HTML_FILE)
$(eval ANCHOR:=$(shell cat $(COVERAGE_HTML_FILE) | grep -E '<option value=".*">.*</option>' | grep $(FILE) | sed -n 's/^.*value="\(.*\)".*$$/\1/p'))
@sed -E -i '' 's/select\("file[0-9]+"\);/select("$(ANCHOR)");/g' $(COVERAGE_HTML_FILE)
@open $(COVERAGE_HTML_FILE)


.PHONY: test
test:
@go test -race -failfast ./...
@go test -race ./...

.PHONY: clean-coverage
clean-coverage:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Cellotape - Beta - OpenAPI Router for Go

![](https://badgen.net/badge/coverage/25/green?icon=github)
![99.6%](https://badgen.net/badge/coverage/99.6%25/green?icon=github)

Cellotape requires Go 1.18 or above.

Expand Down
63 changes: 61 additions & 2 deletions examples/todo_list_app_example/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestGetAllTasks(t *testing.T) {
assert.JSONEq(t, `{
"results": [],
"page": 0,
"pageSize": 0,
"pageSize": 10,
"isLast": true
}`, string(response))
}
Expand All @@ -52,7 +52,7 @@ func TestCreateNewTaskAndGetIt(t *testing.T) {
req, err := http.NewRequest("POST", fmt.Sprintf("%s/tasks", ts.URL), request)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer secret")
//req.Header.Set("Content-Type", "application/json")
req.Header.Set("Content-Type", "application/json")
client := http.Client{}
resp, err := client.Do(req)
require.NoError(t, err)
Expand All @@ -77,6 +77,65 @@ func TestCreateNewTaskAndGetIt(t *testing.T) {
assert.JSONEq(t, taskJson, string(data))
}

func TestRequestQueryParamViolateSchemaValidations(t *testing.T) {
ts := initAPI(t)
defer ts.Close()
req, err := http.NewRequest("GET", fmt.Sprintf("%s/tasks?pageSize=30", ts.URL), nil)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer secret")
client := http.Client{}
resp, err := client.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
response, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t,
`invalid request query param. parameter "pageSize" in query has an error: number must be at most 20`,
string(response))
}

func TestRequestPathParamViolateSchemaValidations(t *testing.T) {
ts := initAPI(t)
defer ts.Close()
req, err := http.NewRequest("GET", fmt.Sprintf("%s/tasks/123", ts.URL), nil)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer secret")
client := http.Client{}
resp, err := client.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
response, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t,
`invalid request path param. parameter "id" in path has an error: minimum string length is 36`,
string(response))
}

func TestRequestBodyViolateSchemaValidations(t *testing.T) {
ts := initAPI(t)
defer ts.Close()
taskJson := `{
"summary": "code first approach",
"description": "add support for code first approach",
"status": "archived"
}`
request := bytes.NewBufferString(taskJson)

req, err := http.NewRequest("POST", fmt.Sprintf("%s/tasks", ts.URL), request)
require.NoError(t, err)
req.Header.Set("Authorization", "Bearer secret")
req.Header.Set("Content-Type", "application/json")
client := http.Client{}
resp, err := client.Do(req)
require.NoError(t, err)
assert.Equal(t, 400, resp.StatusCode)
response, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t,
`invalid request body. request body has an error: doesn't match schema #/components/schemas/Task: value "archived" is not one of the allowed values`,
string(response))
}

func initAPI(t *testing.T) *httptest.Server {
spec, err := router.NewSpecFromData(specData)
require.NoError(t, err)
Expand Down
3 changes: 2 additions & 1 deletion examples/todo_list_app_example/middlewares/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (

"github.com/piiano/cellotape/examples/todo_list_app_example/models"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

const token = "secret"

var authHeader = fmt.Sprintf("Bearer %s", token)

var AuthMiddleware = r.NewHandler(func(c *r.Context, req r.Request[r.Nil, r.Nil, r.Nil]) (r.Response[authResponses], error) {
var AuthMiddleware = r.NewHandler(func(c *r.Context, req r.Request[utils.Nil, utils.Nil, utils.Nil]) (r.Response[authResponses], error) {
if req.Headers.Get("Authorization") != authHeader {
return r.SendJSON(authResponses{Unauthorized: models.HttpError{
Error: "Unauthorized",
Expand Down
8 changes: 4 additions & 4 deletions examples/todo_list_app_example/middlewares/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ import (
r "github.com/piiano/cellotape/router"
)

var LoggerMiddleware = r.NewHandler(loggerHandler)
var LoggerMiddleware = r.RawHandler(loggerHandler)

func loggerHandler(c *r.Context, request r.Request[r.Nil, r.Nil, r.Nil]) (r.Response[any], error) {
func loggerHandler(c *r.Context) error {
start := time.Now()
response, err := c.Next()
duration := time.Since(start)
if err != nil {
log.Printf("[ERROR] error occurred: %s. - %s - [%s] %s\n", err.Error(), duration, c.Request.Method, c.Request.URL.Path)
return r.Response[any]{}, nil
return err
}
log.Printf("[INFO] (status %d | %d bytes | %s) - [%s] %s\n", response.Status, len(response.Body), duration, c.Request.Method, c.Request.URL.Path)
return r.Response[any]{}, nil
return nil
}
3 changes: 2 additions & 1 deletion examples/todo_list_app_example/middlewares/powered_by.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package middlewares

import (
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

var PoweredByMiddleware = r.NewHandler(poweredByHandler)

func poweredByHandler(c *r.Context, _ r.Request[r.Nil, r.Nil, r.Nil]) (r.Response[any], error) {
func poweredByHandler(c *r.Context, _ r.Request[utils.Nil, utils.Nil, utils.Nil]) (r.Response[any], error) {
c.Writer.Header().Add("X-Powered-By", "Piiano OpenAPI Router")
_, err := c.Next()
return r.Response[any]{}, err
Expand Down
2 changes: 2 additions & 0 deletions examples/todo_list_app_example/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ components:
Id:
type: string
format: uuid
minLength: 36
maxLength: 36
nullable: false
Identifiable:
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
m "github.com/piiano/cellotape/examples/todo_list_app_example/models"
"github.com/piiano/cellotape/examples/todo_list_app_example/services"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

func createNewTaskOperation(tasks services.TasksService) r.Handler {
return r.NewHandler(func(c *r.Context, request r.Request[m.Task, r.Nil, r.Nil]) (r.Response[createNewTaskResponses], error) {
return r.NewHandler(func(c *r.Context, request r.Request[m.Task, utils.Nil, utils.Nil]) (r.Response[createNewTaskResponses], error) {
id := tasks.CreateTask(request.Body)
return r.SendOKJSON(createNewTaskResponses{OK: m.Identifiable{ID: id}}), nil
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
m "github.com/piiano/cellotape/examples/todo_list_app_example/models"
"github.com/piiano/cellotape/examples/todo_list_app_example/services"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

func deleteTaskByIDOperation(tasks services.TasksService) r.Handler {
return r.NewHandler(func(_ *r.Context, request r.Request[r.Nil, idPathParam, r.Nil]) (r.Response[deleteTaskByIDResponses], error) {
return r.NewHandler(func(_ *r.Context, request r.Request[utils.Nil, idPathParam, utils.Nil]) (r.Response[deleteTaskByIDResponses], error) {
id, err := uuid.Parse(request.PathParams.ID)
if err != nil {
return r.SendJSON(deleteTaskByIDResponses{
Expand All @@ -35,7 +36,7 @@ func deleteTaskByIDOperation(tasks services.TasksService) r.Handler {
}

type deleteTaskByIDResponses struct {
NoContent r.Nil `status:"204"`
NoContent utils.Nil `status:"204"`
BadRequest m.HttpError `status:"400"`
Gone m.HttpError `status:"410"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
m "github.com/piiano/cellotape/examples/todo_list_app_example/models"
"github.com/piiano/cellotape/examples/todo_list_app_example/services"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

func getTaskByIDOperation(tasks services.TasksService) r.Handler {
return r.NewHandler(func(_ *r.Context, request r.Request[r.Nil, idPathParam, r.Nil]) (r.Response[getTaskByIDResponses], error) {
return r.NewHandler(func(_ *r.Context, request r.Request[utils.Nil, idPathParam, utils.Nil]) (r.Response[getTaskByIDResponses], error) {
id, err := uuid.Parse(request.PathParams.ID)
if err != nil {
return r.SendJSON(getTaskByIDResponses{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import (
m "github.com/piiano/cellotape/examples/todo_list_app_example/models"
"github.com/piiano/cellotape/examples/todo_list_app_example/services"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

func getTasksPageOperation(tasks services.TasksService) r.Handler {
return r.NewHandler(func(_ *r.Context, request r.Request[r.Nil, r.Nil, paginationQueryParams]) (r.Response[getTasksPageResponses], error) {
return r.NewHandler(func(_ *r.Context, request r.Request[utils.Nil, utils.Nil, paginationQueryParams]) (r.Response[getTasksPageResponses], error) {
tasksPage := tasks.GetTasksPage(request.QueryParams.Page, request.QueryParams.PageSize)
return r.SendOKJSON(getTasksPageResponses{OK: tasksPage}, http.Header{"Cache-Control": {"max-age=10"}}), nil
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import (
m "github.com/piiano/cellotape/examples/todo_list_app_example/models"
"github.com/piiano/cellotape/examples/todo_list_app_example/services"
r "github.com/piiano/cellotape/router"
"github.com/piiano/cellotape/router/utils"
)

func updateTaskByIDOperation(tasks services.TasksService) r.Handler {
return r.NewHandler(func(_ *r.Context, request r.Request[m.Task, idPathParam, r.Nil]) (r.Response[updateTaskByIDResponses], error) {
return r.NewHandler(func(_ *r.Context, request r.Request[m.Task, idPathParam, utils.Nil]) (r.Response[updateTaskByIDResponses], error) {
id, err := uuid.Parse(request.PathParams.ID)
if err != nil {
return r.SendJSON(updateTaskByIDResponses{
Expand All @@ -35,7 +36,7 @@ func updateTaskByIDOperation(tasks services.TasksService) r.Handler {
}

type updateTaskByIDResponses struct {
NoContent r.Nil `status:"204"`
NoContent utils.Nil `status:"204"`
BadRequest m.HttpError `status:"400"`
NotFound m.HttpError `status:"404"`
}
12 changes: 5 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@ module github.com/piiano/cellotape

go 1.18

retract (
v1.0.0 // Published accidentally.
v2.0.0 // Published accidentally.
)
retract v1.0.0 // Published accidentally.

require (
github.com/getkin/kin-openapi v0.94.0
github.com/getkin/kin-openapi v0.112.0
github.com/gin-gonic/gin v1.7.7
github.com/google/uuid v1.3.0
github.com/invopop/jsonschema v0.4.0
github.com/julienschmidt/httprouter v1.3.0
github.com/stretchr/testify v1.7.1
github.com/stretchr/testify v1.8.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/swag v0.19.5 // indirect
github.com/go-playground/locales v0.14.0 // indirect
Expand All @@ -27,12 +23,14 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/invopop/yaml v0.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
Expand Down
20 changes: 13 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getkin/kin-openapi v0.94.0 h1:bAxg2vxgnHHHoeefVdmGbR+oxtJlcv5HsJJa3qmAHuo=
github.com/getkin/kin-openapi v0.94.0/go.mod h1:LWZfzOd7PRy8GJ1dJ6mCU6tNdSfOwRac1BUPam4aw6Q=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/getkin/kin-openapi v0.112.0 h1:lnLXx3bAG53EJVI4E/w0N8i1Y/vUZUEsnrXkgnfn7/Y=
github.com/getkin/kin-openapi v0.112.0/go.mod h1:QtwUNt0PAAgIIBEvFWYfB7dfngxtAaqCX1zYHMZDeK8=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
Expand Down Expand Up @@ -34,11 +32,14 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/invopop/jsonschema v0.4.0 h1:Yuy/unfgCnfV5Wl7H0HgFufp/rlurqPOOuacqyByrws=
github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
Expand Down Expand Up @@ -68,21 +69,26 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
Expand Down Expand Up @@ -125,10 +131,10 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 1 addition & 1 deletion options.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{

"$schema": "./options-schema.json"
}
Loading

0 comments on commit 9bb5c2d

Please sign in to comment.