-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d84b83b
Showing
22 changed files
with
1,784 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.idea |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// Generates a README.md from the README.tpl and provides some template helpers. | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"go/ast" | ||
"go/parser" | ||
"go/token" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
"text/template" | ||
"unicode" | ||
"unicode/utf8" | ||
) | ||
|
||
func main() { | ||
if err := run(); err != nil { | ||
println(err.Error()) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func run() error { | ||
const tplName = "README.tpl" | ||
tplVal, err := ioutil.ReadFile(tplName) | ||
if err != nil { | ||
return fmt.Errorf("can't read a file %q: %w", tplName, err) | ||
} | ||
|
||
tpl := template.New("readme").Funcs(template.FuncMap{ | ||
"quote_go_func": func(fileName, funcName string) (string, error) { | ||
fileVal, err := ioutil.ReadFile(fileName) | ||
if err != nil { | ||
return "", fmt.Errorf("can't read a file %q: %w", fileName, err) | ||
} | ||
|
||
fileValS := string(fileVal) | ||
f, err := parser.ParseFile(token.NewFileSet(), fileName, fileValS, 0) | ||
if err != nil { | ||
return "", fmt.Errorf("can't parse a file %q: %w", fileName, err) | ||
} | ||
found := false | ||
var functionBody string | ||
ast.Inspect(f, func(node ast.Node) bool { | ||
if found { | ||
return false | ||
} | ||
fDecl, ok := node.(*ast.FuncDecl) | ||
if ok && fDecl.Name.Name == funcName && fDecl.Body != nil { | ||
found = true | ||
functionBody = fileValS[fDecl.Pos()-1 : fDecl.End()] | ||
return false | ||
} | ||
|
||
return true | ||
}) | ||
|
||
if !found { | ||
return "", fmt.Errorf("can't read a file %q: %w", fileName, err) | ||
} | ||
|
||
return resetIndents(functionBody), nil | ||
}, | ||
"quote_go_func_body": func(fileName, funcName string) (string, error) { | ||
fileVal, err := ioutil.ReadFile(fileName) | ||
if err != nil { | ||
return "", fmt.Errorf("can't read a file %q: %w", fileName, err) | ||
} | ||
|
||
fileValS := string(fileVal) | ||
f, err := parser.ParseFile(token.NewFileSet(), fileName, fileValS, 0) | ||
if err != nil { | ||
return "", fmt.Errorf("can't parse a file %q: %w", fileName, err) | ||
} | ||
found := false | ||
var functionBody string | ||
ast.Inspect(f, func(node ast.Node) bool { | ||
if found { | ||
return false | ||
} | ||
fDecl, ok := node.(*ast.FuncDecl) | ||
if ok && fDecl.Name.Name == funcName && fDecl.Body != nil { | ||
found = true | ||
functionBody = fileValS[fDecl.Body.Pos() : fDecl.Body.End()-2] | ||
return false | ||
} | ||
|
||
return true | ||
}) | ||
|
||
if !found { | ||
return "", fmt.Errorf("can't read a file %q: %w", fileName, err) | ||
} | ||
return resetIndents(functionBody), nil | ||
}, | ||
"quote_file": func(fileName string) (string, error) { | ||
fileVal, err := ioutil.ReadFile(fileName) | ||
if err != nil { | ||
return "", fmt.Errorf("can't read a file %q: %w", fileName, err) | ||
} | ||
|
||
return strings.TrimRight(string(fileVal), "\n"), nil | ||
}, | ||
"indent": indent, | ||
}) | ||
|
||
if tpl, err = tpl.Parse(string(tplVal)); err != nil { | ||
return fmt.Errorf("can't parse a template: %w", err) | ||
} | ||
|
||
const resFileName = "README.md" | ||
resFile, err := os.Create(resFileName) | ||
if err != nil { | ||
return fmt.Errorf("can't create a result file %q: %w", resFileName, err) | ||
} | ||
|
||
if err = tpl.Execute(resFile, nil); err != nil { | ||
return fmt.Errorf("can't execute template: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resetIndents(s string) string { | ||
minCountOfLeadingSpaces := -1 | ||
lines := strings.Split(strings.Trim(s, "\n"), "\n") | ||
for _, line := range lines { | ||
trimmed := strings.TrimLeftFunc(line, unicode.IsSpace) | ||
if utf8.RuneCountInString(trimmed) == 0 { | ||
continue | ||
} | ||
countOfLeadingSpaces := utf8.RuneCountInString(line) - utf8.RuneCountInString(trimmed) | ||
if countOfLeadingSpaces < minCountOfLeadingSpaces || minCountOfLeadingSpaces == -1 { | ||
minCountOfLeadingSpaces = countOfLeadingSpaces | ||
} | ||
} | ||
if minCountOfLeadingSpaces == 0 { | ||
return s | ||
} | ||
res := "" | ||
for i, line := range lines { | ||
if i != 0 { | ||
res += "\n" | ||
} | ||
if utf8.RuneCountInString(line) == 0 { | ||
continue | ||
} | ||
res += string([]rune(line)[minCountOfLeadingSpaces:]) | ||
} | ||
return res | ||
} | ||
|
||
func indent(spaces int, v string) string { | ||
pad := strings.Repeat(" ", spaces) | ||
return pad + strings.Replace(v, "\n", "\n"+pad, -1) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module github.com/vivid-money/article-golang-di | ||
|
||
go 1.13 | ||
|
||
require ( | ||
github.com/google/wire v0.4.0 | ||
go.uber.org/dig v1.10.0 | ||
go.uber.org/fx v1.13.1 | ||
go.uber.org/multierr v1.6.0 | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||
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/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | ||
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= | ||
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= | ||
github.com/google/wire v0.4.0 h1:kXcsA/rIGzJImVqPdhfnr6q0xsS9gU0515q1EPpJ9fE= | ||
github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= | ||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | ||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | ||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
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.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= | ||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= | ||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= | ||
go.uber.org/dig v1.10.0 h1:yLmDDj9/zuDjv3gz8GQGviXMs9TfysIUMUilCpgzUJY= | ||
go.uber.org/dig v1.10.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw= | ||
go.uber.org/fx v1.13.1 h1:CFNTr1oin5OJ0VCZ8EycL3wzF29Jz2g0xe55RFsf2a4= | ||
go.uber.org/fx v1.13.1/go.mod h1:bREWhavnedxpJeTq9pQT53BbvwhUv7TcpsOqcH4a+3w= | ||
go.uber.org/goleak v0.10.0 h1:G3eWbSNIskeRqtsN/1uI5B+eP73y3JUuBsv9AZjehb4= | ||
go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= | ||
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= | ||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= | ||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= | ||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= | ||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= | ||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= | ||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508 h1:0FYNp0PF9kFm/ZUrvcJiQ12IUJJG7iAc6Cu01wbKrbU= | ||
golang.org/x/tools v0.0.0-20191114200427-caa0b0f7d508/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= | ||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package components | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
) | ||
|
||
// Fake db connection. | ||
type DBConn struct { | ||
logger Logger | ||
once sync.Once | ||
} | ||
|
||
func NewDBConn(logger Logger) *DBConn { | ||
logger.Print("New DBConn") | ||
return &DBConn{ | ||
logger: logger, | ||
} | ||
} | ||
|
||
func (h *DBConn) Connect(ctx context.Context) error { | ||
h.logger.Print("Connecting DBConn") | ||
defer h.logger.Print("Connected DBConn") | ||
go func() { // эмулируем остановку соединения по отмене контекста | ||
<-ctx.Done() | ||
_ = h.Stop(context.Background()) | ||
}() | ||
return nil | ||
} | ||
|
||
func (h *DBConn) Stop(_ context.Context) error { | ||
h.once.Do(func() { | ||
h.logger.Print("Stop DBConn") | ||
defer h.logger.Print("Stopped DBConn") | ||
}) | ||
return nil | ||
} | ||
|
||
func (h *DBConn) Query(_ string) (string, error) { | ||
return "Fake result", nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package components | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
) | ||
|
||
// Простенький хелпер, чтобы не писать один и тот же код несколько раз. | ||
func AwaitSignal(ctx context.Context) { | ||
sig := make(chan os.Signal, 1) | ||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) | ||
select { | ||
case <-ctx.Done(): | ||
case <-sig: | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package components | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
type HTTPServer struct { | ||
httpSrv *http.Server | ||
conn *DBConn | ||
logger Logger | ||
} | ||
|
||
func NewHTTPServer(logger Logger, conn *DBConn) *HTTPServer { | ||
logger.Print("New HTTPServer") | ||
mux := http.NewServeMux() | ||
|
||
s := &HTTPServer{ | ||
conn: conn, | ||
logger: logger, | ||
} | ||
mux.HandleFunc("/get", func(writer http.ResponseWriter, _ *http.Request) { | ||
res, err := conn.Query("SELECT * FROM something") | ||
if err != nil { | ||
writer.WriteHeader(http.StatusInternalServerError) | ||
return | ||
} | ||
_, _ = writer.Write([]byte(res)) | ||
}) | ||
s.httpSrv = &http.Server{ | ||
Addr: ":3000", | ||
Handler: mux, | ||
} | ||
|
||
return s | ||
} | ||
|
||
func (s *HTTPServer) Serve(ctx context.Context) error { | ||
s.logger.Print("Serving HTTPServer") | ||
defer s.logger.Print("Finished serving HTTPServer") | ||
go func() { // вызываем остановку по отмене контекста, так как net/http не умеет работать с контекстами | ||
<-ctx.Done() | ||
_ = s.Stop(context.Background()) | ||
}() | ||
if err := s.httpSrv.ListenAndServe(); err != nil { | ||
return fmt.Errorf("http listen: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (s *HTTPServer) Stop(ctx context.Context) error { | ||
s.logger.Print("Stop HTTPServer") | ||
defer s.logger.Print("Stopped HTTPServer") | ||
if err := s.httpSrv.Shutdown(ctx); err != nil { | ||
return fmt.Errorf("http shutdown: %w", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package components | ||
|
||
type Logger interface { | ||
Print(v ...interface{}) | ||
Printf(format string, v ...interface{}) | ||
Fatal(v ...interface{}) | ||
Fatalf(format string, v ...interface{}) | ||
Panic(v ...interface{}) | ||
Panicf(format string, v ...interface{}) | ||
} |
Oops, something went wrong.