Skip to content

Commit 08e0253

Browse files
committed
port over go-template code
1 parent d868d58 commit 08e0253

16 files changed

+592
-0
lines changed

.dockerignore

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# misc
2+
.git
3+
.gitmodules
4+
LICENSE
5+
release
6+
files
7+
scripts
8+
.travis.yml
9+
go-defi
10+
bin
11+
testing
12+
13+
# regexs
14+
**/*.yaml
15+
**/*.yml
16+
**/*.db
17+
**/*.log
18+
**/*.profile
19+
**/*.md
20+
**/*.conf
21+
**/*.png
22+
**/*.txt
23+
**/*.conf
24+
**/*.csv
25+
**/Makefile

.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
# misc
3+
config.yaml
4+
*.log
5+
release
6+
files
7+
go-defi
8+
9+
# regex
10+
**/*.db

Dockerfile

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM golang:1.15-alpine3.12 AS build-env
2+
RUN apk add build-base linux-headers
3+
ARG VERSION
4+
ENV BUILD_HOME=/BUILD
5+
RUN mkdir -p ${BUILD_HOME}
6+
WORKDIR ${BUILD_HOME}
7+
8+
ADD . ${BUILD_HOME}
9+
RUN go mod download
10+
RUN go build -o /bin/go-defi \
11+
--tags "json1" \
12+
-ldflags "-X main.Version=$VERSION"
13+
14+
FROM alpine:3.12
15+
COPY --from=build-env /bin/go-defi /bin/go-defi
16+
ENTRYPOINT ["/bin/go-defi", "--config.path", "/config.yaml" ]

Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
GIT_VERSION=`git describe --tags`
2+
3+
# NOTE: if you dont want to use the sqlite database you can remove the json1 tag
4+
.PHONY: cli
5+
cli:
6+
go build --tags "json1" -ldflags "-X main.Version=$(GIT_VERSION)" .
7+
8+
.PHONY: docker
9+
docker:
10+
docker build --build-arg VERSION=$(GIT_VERSION) -t bonedaddy/go-defi:$(GIT_VERSION) .
11+
docker image tag bonedaddy/go-defi:$(GIT_VERSION) bonedaddy/go-defi:latest
12+
13+
14+
.PHONY: release
15+
release:
16+
./scripts/release.sh
17+
18+
.PHONY: tests
19+
tests:
20+
go test --tags "json1" -count 1 -cover ./...

cli/cli.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package cli
2+
3+
import (
4+
"github.com/urfave/cli/v2"
5+
)
6+
7+
func New(name, usage, version string) *cli.App {
8+
app := cli.NewApp()
9+
app.Name = name
10+
app.Usage = usage
11+
app.Version = version
12+
app.Commands = cli.Commands{configCommand()}
13+
app.Flags = []cli.Flag{
14+
&cli.StringFlag{
15+
Name: "config.path",
16+
Aliases: []string{"cfg"},
17+
Usage: "path to the configuration file",
18+
Value: "config.yaml",
19+
},
20+
}
21+
return app
22+
}

cli/config_command.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package cli
2+
3+
import (
4+
"github.com/bonedaddy/go-defi/config"
5+
"github.com/urfave/cli/v2"
6+
)
7+
8+
func configCommand() *cli.Command {
9+
return &cli.Command{
10+
Name: "configuration",
11+
Aliases: []string{"config", "cfg"},
12+
Usage: "configuration management command group",
13+
Subcommands: cli.Commands{
14+
&cli.Command{
15+
Name: "generate",
16+
Aliases: []string{"gen"},
17+
Action: func(c *cli.Context) error {
18+
return config.NewConfig(c.String("config.path"))
19+
},
20+
},
21+
},
22+
}
23+
}

cli/doc.go

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package cli provides a base cli package
2+
package cli

config/config.go

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright (c) 2021 Alexandre Trottier (bonedaddy). All rights reserved.
2+
// Use of this source code is governed by the Apache 2.0 License that can be found in
3+
// the LICENSE file.
4+
5+
package config
6+
7+
import (
8+
"io/ioutil"
9+
"os"
10+
11+
"github.com/vrischmann/envconfig"
12+
"go.bobheadxi.dev/zapx/zapx"
13+
"go.uber.org/zap"
14+
"gopkg.in/yaml.v2"
15+
)
16+
17+
// Config provides the base configuration type
18+
type Config struct {
19+
Database `yaml:"database" envconfig:"optional"`
20+
Blockchain `yaml:"blockchain" envconfig:"optional"`
21+
Logger `yaml:"logger"`
22+
}
23+
24+
// Blockchain provides configuration for connection to a blockchain rpc provider
25+
type Blockchain struct {
26+
// APIKey provides an API key to be used for authenticaiton with an rpc provider
27+
APIKey string `yaml:"api_key" envconfig:"optional"`
28+
// ProvderType indicates the type of rpc provider
29+
// current values are: infura, direct
30+
// when direct is provided we connected directly via the RPC parameter
31+
ProviderType string `yaml:"provider_type"`
32+
// Network indicates the network type
33+
// current values are: mainnet, kovan, rinkeby, ropsten
34+
Network string `yaml:"network"`
35+
// RPC is the JSON-RPC provider url used when directly connecting to a node
36+
RPC string `yaml:"rpc" envconfig:"optional"`
37+
// Websockets when set to true will attempt to use websockets connection negotiation
38+
Websockets bool `yaml:"websockets" envconfig:"optional"`
39+
}
40+
41+
// Database provides configuration over our database connection
42+
type Database struct {
43+
// Type specifies the database type to be used
44+
// currently supports: sqlite, postgres
45+
// when using sqlite type all other options except DBName and DBPath are ignore
46+
Type string `yaml:"type"`
47+
// Host specifies the database host address
48+
Host string `yaml:"host" envconfig:"optional"`
49+
// Port specifies the port the database is exposed on
50+
Port string `yaml:"port" envconfig:"optional"`
51+
// User specifies the username to use for authentication
52+
User string `yaml:"user" envconfig:"optional"`
53+
// Pass specifies the password to use for authentication
54+
Pass string `yaml:"pass" envconfig:"optional"`
55+
// DBName specifies the name of the database
56+
DBName string `yaml:"db_name"`
57+
// DBPath specifies the path to the database file (only applicable to sqlite)
58+
DBPath string `yaml:"db_path" envconfig:"optional"`
59+
// SSLModeDisable specifies whether or not to disable ssl connection layer security
60+
SSLModeDisable bool `yaml:"ssl_mode_disable" envconfig:"optional"`
61+
}
62+
63+
// Logger provides configuration over zap logger
64+
type Logger struct {
65+
// Path to store the configuration file
66+
Path string `yaml:"path" envconfig:"default=go-defi.log"`
67+
// Debug enables displaying of debug logs
68+
Debug bool `yaml:"debug" envconfig:"optional"`
69+
// Dev enables foramtting of logs to be more human readable
70+
Dev bool `yaml:"dev" envconfig:"optional"`
71+
// FileOnly disables stdout logging and will only display log output in `Path`
72+
FileOnly bool `yaml:"file_only" envconfig:"optional"`
73+
// Fields provides optional fields to use for logging metadata
74+
Fields map[string]interface{} `yaml:"fields" envconfig:"optional"`
75+
}
76+
77+
var (
78+
// ExampleConfig is primarily used to provide a template for generating the config file
79+
ExampleConfig = &Config{
80+
Database: Database{
81+
Type: "sqlite",
82+
Host: "localhost",
83+
Port: "5432",
84+
User: "postgres",
85+
Pass: "password123",
86+
DBName: "go-defi",
87+
DBPath: "",
88+
SSLModeDisable: false,
89+
},
90+
Blockchain: Blockchain{
91+
APIKey: "CHANGEME",
92+
ProviderType: "infura",
93+
Network: "mainnet",
94+
RPC: "http://localhost:8545",
95+
Websockets: true,
96+
},
97+
Logger: Logger{
98+
Path: "go-defi.log",
99+
Debug: true,
100+
Dev: true,
101+
},
102+
}
103+
)
104+
105+
// NewConfig generates a new config and stores at path
106+
func NewConfig(path string) error {
107+
data, err := yaml.Marshal(ExampleConfig)
108+
if err != nil {
109+
return err
110+
}
111+
return ioutil.WriteFile(path, data, os.ModePerm)
112+
}
113+
114+
// LoadConfig loads the configuration at path
115+
// however if loading from path fails, we attempt to load
116+
// from environment variabels
117+
func LoadConfig(path string) (cfg *Config, err error) {
118+
func() {
119+
var r []byte
120+
r, err = ioutil.ReadFile(path)
121+
if err != nil {
122+
return
123+
}
124+
var _cfg Config
125+
if err := yaml.Unmarshal(r, &cfg); err != nil {
126+
return
127+
}
128+
cfg = &_cfg
129+
}()
130+
if err != nil {
131+
cfg = &Config{}
132+
err = envconfig.Init(cfg)
133+
return
134+
}
135+
return
136+
}
137+
138+
// ZapLogger parses the Logger configuration struct and returns a zap logger instance
139+
func (c *Config) ZapLogger() (*zap.Logger, error) {
140+
var opts []zapx.Option
141+
if c.Logger.Debug {
142+
opts = append(opts, zapx.WithDebug(true))
143+
}
144+
if c.Logger.FileOnly {
145+
opts = append(opts, zapx.OnlyToFile())
146+
}
147+
if c.Logger.Fields != nil {
148+
opts = append(opts, zapx.WithFields(c.Logger.Fields))
149+
}
150+
return zapx.New(
151+
c.Logger.Path,
152+
c.Logger.Dev,
153+
opts...,
154+
)
155+
}

config/config_test.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package config
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestConfigFile(t *testing.T) {
11+
t.Cleanup(func() {
12+
os.Remove("test-config.yml")
13+
os.Remove("go-defi.log")
14+
})
15+
err := NewConfig("test-config.yml")
16+
require.NoError(t, err)
17+
cfg, err := LoadConfig("test-config.yml")
18+
require.NoError(t, err)
19+
logger, err := cfg.ZapLogger()
20+
require.NoError(t, err)
21+
logger.Info("hello")
22+
logger.Sync()
23+
}
24+
25+
func TestConfigEnv(t *testing.T) {
26+
t.Cleanup(func() {
27+
os.Remove("go-defi.log")
28+
})
29+
cfg, err := LoadConfig("not-a-real-config.yml")
30+
require.NoError(t, err)
31+
logger, err := cfg.ZapLogger()
32+
require.NoError(t, err)
33+
logger.Info("hello")
34+
logger.Sync()
35+
}

config/doc.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2021 Alexandre Trottier (bonedaddy). All rights reserved.
2+
// Use of this source code is governed by the Apache 2.0 License that can be found in
3+
// the LICENSE file.
4+
5+
/* Package config provides a flexible configuration management type, allowing for the usage of YAML files or environment variables.
6+
For details on how the environment variable based configuration works please see https://github.com/vrischmann/envconfig#how-does-it-work however a basic example is included below
7+
```
8+
var conf struct {
9+
Name string
10+
Shard struct {
11+
Host string
12+
Port int
13+
}
14+
}
15+
```
16+
The above struct will check for the following keys:
17+
* NAME or name
18+
* SHARD_HOST, or shard_host
19+
* SHARD_PORT, or shard_port
20+
21+
*/
22+
package config

database/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# TESTFLAGS="-v -cover" make test
2+
.PHONY: test
3+
test:
4+
go test --tags "json1" $(TESTFLAGS) ./...

0 commit comments

Comments
 (0)