Skip to content

Commit 02c35b4

Browse files
authored
Pass in the app env (#23)
* add more args to linter * pass env data from app to a handler
1 parent 2ce1dc0 commit 02c35b4

File tree

9 files changed

+262
-20
lines changed

9 files changed

+262
-20
lines changed

.github/workflows/golangci-lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ jobs:
2020
uses: golangci/golangci-lint-action@v2
2121
with:
2222
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
23-
version: v1.29
23+
version: latest
2424

2525
# Optional: working directory, useful for monorepos
2626
# working-directory: somedir
2727

2828
# Optional: golangci-lint command line arguments.
29-
# args: --issues-exit-code=0
29+
# args: -E gosec -E megacheck -E govet -E goconst -E lll -E gocritic -E gocyclo -E godox -E dupl -E depguard
3030

3131
# Optional: show only new issues if it's a pull request. The default value is `false`.
3232
# only-new-issues: true

.golangci.yml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# This file contains all available configuration options
2+
# with their default values.
3+
4+
# options for analysis running
5+
run:
6+
# default concurrency is a available CPU number
7+
concurrency: 4
8+
9+
# timeout for analysis, e.g. 30s, 5m, default is 1m
10+
timeout: 1m
11+
12+
# exit code when at least one issue was found, default is 1
13+
issues-exit-code: 1
14+
15+
# include test files or not, default is true
16+
tests: true
17+
18+
# list of build tags, all linters use it. Default is empty list.
19+
build-tags:
20+
21+
22+
# which dirs to skip: issues from them won't be reported;
23+
# can use regexp here: generated.*, regexp is applied on full path;
24+
# default value is empty list, but default dirs are skipped independently
25+
# from this option's value (see skip-dirs-use-default).
26+
# "/" will be replaced by current OS file path separator to properly work
27+
# on Windows.
28+
skip-dirs:
29+
30+
31+
# default is true. Enables skipping of directories:
32+
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
33+
skip-dirs-use-default: true
34+
35+
# which files to skip: they will be analyzed, but issues from them
36+
# won't be reported. Default value is empty list, but there is
37+
# no need to include all autogenerated files, we confidently recognize
38+
# autogenerated files. If it's not please let us know.
39+
# "/" will be replaced by current OS file path separator to properly work
40+
# on Windows.
41+
skip-files:
42+
43+
44+
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
45+
# If invoked with -mod=readonly, the go command is disallowed from the implicit
46+
# automatic updating of go.mod described above. Instead, it fails when any changes
47+
# to go.mod are needed. This setting is most useful to check that go.mod does
48+
# not need updates, such as in a continuous integration and testing system.
49+
# If invoked with -mod=vendor, the go command assumes that the vendor
50+
# directory holds the correct copies of dependencies and ignores
51+
# the dependency descriptions in go.mod.
52+
modules-download-mode: readonly
53+
54+
# Allow multiple parallel golangci-lint instances running.
55+
# If false (default) - golangci-lint acquires file lock on start.
56+
allow-parallel-runners: false
57+
58+
59+
# output configuration options
60+
output:
61+
# colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
62+
# default is "colored-line-number"
63+
format: colored-line-number
64+
65+
# print lines of code with issue, default is true
66+
print-issued-lines: true
67+
68+
# print linter name in the end of issue text, default is true
69+
print-linter-name: true
70+
71+
# make issues output unique by line, default is true
72+
uniq-by-line: true
73+
74+
# add a prefix to the output file references; default is no prefix
75+
path-prefix: ""
76+
77+
# sorts results by: filepath, line and column
78+
sort-results: true
79+
80+
linters:
81+
enable:
82+
- gosec
83+
- megacheck
84+
- govet
85+
- goconst
86+
- importas
87+
- lll
88+
- gocritic
89+
- gocyclo
90+
- godox
91+
- gci
92+
- dupl
93+
- cyclop
94+
- depguard
95+
presets:
96+
- bugs
97+
- unused
98+
disable:
99+
- scopelint
100+
fast: false
101+

apihandler.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ import (
1414
"github.com/gorilla/mux"
1515
)
1616

17-
func apiHandler(hf Handler, api HTTPService, path, method string, ll logger.LogLevel, env *sync.Map) http.Handler {
17+
func apiHandler(hf Handler,
18+
api HTTPService,
19+
path, method string,
20+
ll logger.LogLevel,
21+
envs []*sync.Map,
22+
) http.Handler {
1823
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
1924
rl := &responseLogger{w: w, status: http.StatusOK}
2025
w = httpsnoop.Wrap(w, httpsnoop.Hooks{
@@ -26,10 +31,14 @@ func apiHandler(hf Handler, api HTTPService, path, method string, ll logger.LogL
2631
},
2732
})
2833
ctx := NewServerContext(r.Context(), ll, w, r)
29-
env.Range(func(key, value interface{}) bool {
30-
ctx.Set(fmt.Sprint(key), value)
31-
return true
32-
})
34+
35+
for _, each := range envs {
36+
env := each
37+
env.Range(func(key, value interface{}) bool {
38+
ctx.Set(fmt.Sprint(key), value)
39+
return true
40+
})
41+
}
3342
t := time.Now()
3443

3544
defer func() {

app.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import (
44
"fmt"
55
"net/http"
66
"strconv"
7+
"sync"
78
"time"
89

910
"github.com/galentuo/goframe/logger"
1011
)
1112

12-
var (
13-
cl *logger.CoreLogger
14-
)
13+
var cl *logger.CoreLogger
1514

1615
func init() {
1716
cl = logger.NewCoreLogger()
@@ -22,15 +21,26 @@ type app struct {
2221
name string
2322
config Config
2423
mux Router
24+
env *sync.Map
2525
}
2626

27-
func (a *app) Name() string { return a.name }
27+
// Name returns the name of the app
28+
func (a *app) Name() string { return a.name }
29+
30+
// LogLevel returns the log level of the app
2831
func (a *app) LogLevel() logger.LogLevel { return a.ll }
2932

33+
// CustomCoreLogger is used to replace the core logger with a custom one
34+
// if required
3035
func (a *app) CustomCoreLogger(clIn *logger.CoreLogger) {
3136
cl = clIn
3237
}
3338

39+
// SetInCtx is used to set data into ctx
40+
func (a *app) SetInCtx(key string, value interface{}) {
41+
a.env.Store(key, value)
42+
}
43+
3444
// Config returns the config reader.
3545
// Config values can be fetched by keys eg. "server.host".
3646
// In production configs can be stored as env vars.
@@ -62,19 +72,23 @@ func NewApp(name string, strictSlash bool, cr Config) *app {
6272
name: name,
6373
config: cr,
6474
mux: NewRouter(strictSlash),
75+
env: &sync.Map{},
6576
}
6677

6778
ll := logger.LogLevelFromStr(a.config.GetString("log.level"))
6879
a.ll = ll
6980
return &a
7081
}
7182

72-
func (a *app) Register(_svc Service) {
83+
// Register registers the service to the app.
84+
// A service must be registered to the app for it to run.
85+
func (a *app) Register(svcIn Service) {
7386
var (
7487
api HTTPService
7588
bg BackgroundService
7689
)
77-
switch svc := _svc.(type) {
90+
91+
switch svc := svcIn.(type) {
7892
case HTTPService:
7993
api = svc
8094
case BackgroundService:
@@ -86,7 +100,12 @@ func (a *app) Register(_svc Service) {
86100
if api != nil {
87101
for path, routes := range api.routes() {
88102
for _, endpoint := range routes {
89-
a.mux.Handle(endpoint.Method(), api.prefix()+path, apiHandler(endpoint.Handler(), api, path, endpoint.Method(), a.LogLevel(), api.getCtxData()))
103+
a.mux.Handle(endpoint.Method(), api.prefix()+path,
104+
apiHandler(endpoint.Handler(), api, path,
105+
endpoint.Method(), a.LogLevel(),
106+
[]*sync.Map{a.env, api.getCtxData()},
107+
),
108+
)
90109
}
91110
}
92111
for _, each := range api.getChildren() {

default_context.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ func NewContext(ctx context.Context, ll logger.LogLevel) *defaultContext {
8383

8484
// NewServerContext is used to get an instance of the default implementation
8585
// of goframe.ServerContext
86-
func NewServerContext(ctx context.Context, ll logger.LogLevel, res http.ResponseWriter, req *http.Request) *defaultServerContext {
86+
func NewServerContext(ctx context.Context,
87+
ll logger.LogLevel,
88+
res http.ResponseWriter,
89+
req *http.Request,
90+
) *defaultServerContext {
8791
llh := req.Header.Get("X-Request-LogLevel")
8892
if llh == "debug" {
8993
ll = logger.LogLevelDebug

default_response_writer.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package goframe
22

33
import (
44
"encoding/json"
5+
"errors"
56
"fmt"
67
"net/http"
78
)
@@ -51,10 +52,11 @@ func (drw *defaultResponseWriter) ErrorJSON(err error) error {
5152
}
5253
httpCode := int(500)
5354

54-
if ie, ok := err.(*goframeError); ok {
55-
httpCode = ie.HttpCode()
56-
responseJson.ErrorCode = ie.ErrCode()
57-
responseJson.Message = ie.Message()
55+
gfErr := goframeError{}
56+
if ok := errors.As(err, &gfErr); ok {
57+
httpCode = gfErr.HttpCode()
58+
responseJson.ErrorCode = gfErr.ErrCode()
59+
responseJson.Message = gfErr.Message()
5860
} else {
5961
responseJson.ErrorCode = "dev"
6062
responseJson.Message = err.Error()

default_services.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ type service struct {
1010
env *sync.Map
1111
}
1212

13+
// Name returns the name of the service
1314
func (ds *service) Name() string {
1415
return ds.name
1516
}
1617

18+
// SetInCtx is used to set data into ctx
1719
func (ds *service) SetInCtx(key string, value interface{}) {
1820
ds.env.Store(key, value)
1921
}

golangci.yml

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## This file contains all available configuration options
2+
## with their default values.
3+
#
4+
## options for analysis running
5+
#run:
6+
# # default concurrency is a available CPU number
7+
# concurrency: 4
8+
#
9+
# # timeout for analysis, e.g. 30s, 5m, default is 1m
10+
# timeout: 1m
11+
#
12+
# # exit code when at least one issue was found, default is 1
13+
# issues-exit-code: 1
14+
#
15+
# # include test files or not, default is true
16+
# tests: true
17+
#
18+
# # list of build tags, all linters use it. Default is empty list.
19+
# build-tags:
20+
#
21+
#
22+
# # which dirs to skip: issues from them won't be reported;
23+
# # can use regexp here: generated.*, regexp is applied on full path;
24+
# # default value is empty list, but default dirs are skipped independently
25+
# # from this option's value (see skip-dirs-use-default).
26+
# # "/" will be replaced by current OS file path separator to properly work
27+
# # on Windows.
28+
# skip-dirs:
29+
#
30+
#
31+
# # default is true. Enables skipping of directories:
32+
# # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
33+
# skip-dirs-use-default: true
34+
#
35+
# # which files to skip: they will be analyzed, but issues from them
36+
# # won't be reported. Default value is empty list, but there is
37+
# # no need to include all autogenerated files, we confidently recognize
38+
# # autogenerated files. If it's not please let us know.
39+
# # "/" will be replaced by current OS file path separator to properly work
40+
# # on Windows.
41+
# skip-files:
42+
#
43+
#
44+
# # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
45+
# # If invoked with -mod=readonly, the go command is disallowed from the implicit
46+
# # automatic updating of go.mod described above. Instead, it fails when any changes
47+
# # to go.mod are needed. This setting is most useful to check that go.mod does
48+
# # not need updates, such as in a continuous integration and testing system.
49+
# # If invoked with -mod=vendor, the go command assumes that the vendor
50+
# # directory holds the correct copies of dependencies and ignores
51+
# # the dependency descriptions in go.mod.
52+
# modules-download-mode: mod
53+
#
54+
# # Allow multiple parallel golangci-lint instances running.
55+
# # If false (default) - golangci-lint acquires file lock on start.
56+
# allow-parallel-runners: false
57+
#
58+
#
59+
## output configuration options
60+
#output:
61+
# # colored-line-number|line-number|json|tab|checkstyle|code-climate|junit-xml|github-actions
62+
# # default is "colored-line-number"
63+
# format: colored-line-number
64+
#
65+
# # print lines of code with issue, default is true
66+
# print-issued-lines: true
67+
#
68+
# # print linter name in the end of issue text, default is true
69+
# print-linter-name: true
70+
#
71+
# # make issues output unique by line, default is true
72+
# uniq-by-line: true
73+
#
74+
# # add a prefix to the output file references; default is no prefix
75+
# path-prefix: ""
76+
#
77+
# # sorts results by: filepath, line and column
78+
# sort-results: true
79+
#
80+
#linters:
81+
# enable:
82+
# - gosec
83+
# - megacheck
84+
# - govet
85+
# - goconst
86+
# - importas
87+
# - lll
88+
# - gocritic
89+
# - gocyclo
90+
# - godox
91+
# - gci
92+
# - dupl
93+
# - cyclop
94+
# - depguard
95+
# presets:
96+
# - bugs
97+
# - unused
98+
# disable:
99+
# - scopelint
100+
# fast: false
101+
#

0 commit comments

Comments
 (0)