Выполнен рефакторинг. Добавлен workflow.
This commit is contained in:
parent
f884b56a10
commit
a06ee87fba
38
.gitea/workflows/test.yaml
Normal file
38
.gitea/workflows/test.yaml
Normal file
@ -0,0 +1,38 @@
|
||||
name: test
|
||||
run-name: ${{ gitea.actor }} test MouseSoft Config
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: check-out
|
||||
uses: https://gitea.com/actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
|
||||
- name: set-up go
|
||||
uses: https://gitea.com/actions/setup-go@v3
|
||||
with:
|
||||
go-version: ">=1.22"
|
||||
|
||||
- name: set-up dependencies
|
||||
run: |
|
||||
go install github.com/kisielk/errcheck@latest
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
go install github.com/sashamelentyev/usestdlibvars@latest
|
||||
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
|
||||
make vendor
|
||||
|
||||
- name: lint
|
||||
run: make lint
|
||||
|
||||
# - name: golangci-lint
|
||||
# uses: https://github.com/golangci/golangci-lint-action@v6
|
||||
# with:
|
||||
# version: v1.60
|
||||
|
||||
- name: test
|
||||
id: build
|
||||
run: make test
|
314
.golangci.yaml
Normal file
314
.golangci.yaml
Normal file
@ -0,0 +1,314 @@
|
||||
# This file contains all available configuration options
|
||||
# with their default values (in comments).
|
||||
#
|
||||
# This file is not a configuration example,
|
||||
# it contains the exhaustive configuration with explanations of the options.
|
||||
|
||||
linters:
|
||||
# Disable all linters.
|
||||
# Default: false
|
||||
disable-all: true
|
||||
# Enable specific linter
|
||||
# https://golangci-lint.run/usage/linters/#enabled-by-default
|
||||
enable:
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- canonicalheader
|
||||
- containedctx
|
||||
- contextcheck
|
||||
- copyloopvar
|
||||
- cyclop
|
||||
- decorder
|
||||
- dogsled
|
||||
- dupl
|
||||
- dupword
|
||||
- durationcheck
|
||||
- err113
|
||||
- errcheck
|
||||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
- exhaustive
|
||||
- fatcontext
|
||||
- forcetypeassert
|
||||
- funlen
|
||||
- gci
|
||||
- ginkgolinter
|
||||
- gocheckcompilerdirectives
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gochecksumtype
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- godox
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goheader
|
||||
- goimports
|
||||
- gomoddirectives
|
||||
- gomodguard
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- gosmopolitan
|
||||
- govet
|
||||
- grouper
|
||||
- importas
|
||||
- inamedparam
|
||||
- ineffassign
|
||||
- interfacebloat
|
||||
- intrange
|
||||
- ireturn
|
||||
- lll
|
||||
- loggercheck
|
||||
- maintidx
|
||||
- makezero
|
||||
- mirror
|
||||
- misspell
|
||||
- mnd
|
||||
- musttag
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- nilnil
|
||||
- nlreturn
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nonamedreturns
|
||||
- nosprintfhostport
|
||||
- paralleltest
|
||||
- perfsprint
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
- protogetter
|
||||
- reassign
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- sloglint
|
||||
- spancheck
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- stylecheck
|
||||
- tagalign
|
||||
- tagliatelle
|
||||
- tenv
|
||||
- testableexamples
|
||||
- testifylint
|
||||
- testpackage
|
||||
- thelper
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- varnamelen
|
||||
- wastedassign
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
- wsl
|
||||
- zerologlint
|
||||
|
||||
# Enable all available linters.
|
||||
# Default: false
|
||||
enable-all: false
|
||||
|
||||
# Enable only fast linters from enabled linters set (first run won't be fast)
|
||||
# Default: false
|
||||
fast: true
|
||||
|
||||
# All available settings of specific linters.
|
||||
linters-settings:
|
||||
cyclop:
|
||||
# The maximal code complexity to report.
|
||||
# Default: 10
|
||||
max-complexity: 20
|
||||
# Should ignore tests.
|
||||
# Default: false
|
||||
skip-tests: true
|
||||
|
||||
funlen:
|
||||
# Checks the number of lines in a function.
|
||||
# If lower than 0, disable the check.
|
||||
# Default: 60
|
||||
lines: 80
|
||||
# Checks the number of statements in a function.
|
||||
# If lower than 0, disable the check.
|
||||
# Default: 40
|
||||
statements: 50
|
||||
# Ignore comments when counting lines.
|
||||
# Default false
|
||||
ignore-comments: true
|
||||
|
||||
gocognit:
|
||||
# Minimal code complexity to report.
|
||||
# Default: 30 (but we recommend 10-20)
|
||||
min-complexity: 20
|
||||
|
||||
gocyclo:
|
||||
# Minimal code complexity to report.
|
||||
# Default: 30 (but we recommend 10-20)
|
||||
min-complexity: 20
|
||||
|
||||
godot:
|
||||
# Comments to be checked: `declarations`, `toplevel`, or `all`.
|
||||
# Default: declarations
|
||||
scope: all
|
||||
# List of regexps for excluding particular comment lines from check.
|
||||
# Default: []
|
||||
exclude:
|
||||
# Exclude todo and fixme comments.
|
||||
- "^fixme:"
|
||||
- "^todo:"
|
||||
# Check that each sentence ends with a period.
|
||||
# Default: true
|
||||
period: false
|
||||
# Check that each sentence starts with a capital letter.
|
||||
# Default: false
|
||||
capital: true
|
||||
|
||||
goimports:
|
||||
local-prefixes: git.mousesoft.ru/ms/config
|
||||
|
||||
gosec:
|
||||
excludes:
|
||||
- G115
|
||||
|
||||
revive:
|
||||
rules:
|
||||
- name: unexported-return
|
||||
disabled: true
|
||||
|
||||
# output configuration options
|
||||
output:
|
||||
# The formats used to render issues.
|
||||
# Formats:
|
||||
# - `colored-line-number`
|
||||
# - `line-number`
|
||||
# - `json`
|
||||
# - `colored-tab`
|
||||
# - `tab`
|
||||
# - `html`
|
||||
# - `checkstyle`
|
||||
# - `code-climate`
|
||||
# - `junit-xml`
|
||||
# - `junit-xml-extended`
|
||||
# - `github-actions`
|
||||
# - `teamcity`
|
||||
# - `sarif`
|
||||
# Output path can be either `stdout`, `stderr` or path to the file to write to.
|
||||
#
|
||||
# For the CLI flag (`--out-format`), multiple formats can be specified by separating them by comma.
|
||||
# The output can be specified for each of them by separating format name and path by colon symbol.
|
||||
# Example: "--out-format=checkstyle:report.xml,json:stdout,colored-line-number"
|
||||
# The CLI flag (`--out-format`) override the configuration file.
|
||||
#
|
||||
# Default:
|
||||
# formats:
|
||||
# - format: colored-line-number
|
||||
# path: stdout
|
||||
formats:
|
||||
# - format: json
|
||||
# path: stderr
|
||||
# - format: checkstyle
|
||||
# path: report.xml
|
||||
- format: colored-line-number
|
||||
|
||||
# Print lines of code with issue.
|
||||
# Default: true
|
||||
print-issued-lines: false
|
||||
|
||||
# Print linter name in the end of issue text.
|
||||
# Default: true
|
||||
print-linter-name: true
|
||||
|
||||
# Make issues output unique by line.
|
||||
# Default: true
|
||||
uniq-by-line: false
|
||||
|
||||
# Add a prefix to the output file references.
|
||||
# Default: ""
|
||||
path-prefix: ""
|
||||
|
||||
# Sort results by the order defined in `sort-order`.
|
||||
# Default: false
|
||||
sort-results: true
|
||||
|
||||
# Order to use when sorting results.
|
||||
# Require `sort-results` to `true`.
|
||||
# Possible values: `file`, `linter`, and `severity`.
|
||||
#
|
||||
# If the severity values are inside the following list, they are ordered in this order:
|
||||
# 1. error
|
||||
# 2. warning
|
||||
# 3. high
|
||||
# 4. medium
|
||||
# 5. low
|
||||
# Either they are sorted alphabetically.
|
||||
#
|
||||
# Default: ["file"]
|
||||
sort-order:
|
||||
- linter
|
||||
- severity
|
||||
- file # filepath, line, and column.
|
||||
|
||||
# Show statistics per linter.
|
||||
# Default: false
|
||||
show-stats: true
|
||||
|
||||
# Options for analysis running.
|
||||
run:
|
||||
# Timeout for analysis, e.g. 30s, 5m.
|
||||
# Default: 1m
|
||||
timeout: 5m
|
||||
|
||||
# Exit code when at least one issue was found.
|
||||
# Default: 1
|
||||
issues-exit-code: 2
|
||||
|
||||
# Include test files or not.
|
||||
# Default: true
|
||||
tests: false
|
||||
|
||||
# List of build tags, all linters use it.
|
||||
# Default: []
|
||||
build-tags:
|
||||
- mytag
|
||||
|
||||
# If set, we pass it to "go list -mod={option}". From "go help modules":
|
||||
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||
# not need updates, such as in a continuous integration and testing system.
|
||||
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||
# directory holds the correct copies of dependencies and ignores
|
||||
# the dependency descriptions in go.mod.
|
||||
#
|
||||
# Allowed values: readonly|vendor|mod
|
||||
# Default: ""
|
||||
modules-download-mode: readonly
|
||||
|
||||
# Allow multiple parallel golangci-lint instances running.
|
||||
# If false, golangci-lint acquires file lock on start.
|
||||
# Default: false
|
||||
allow-parallel-runners: true
|
||||
|
||||
# Allow multiple golangci-lint instances running, but serialize them around a lock.
|
||||
# If false, golangci-lint exits with an error if it fails to acquire file lock on start.
|
||||
# Default: false
|
||||
allow-serial-runners: true
|
||||
|
||||
# Define the Go version limit.
|
||||
# Mainly related to generics support since go1.18.
|
||||
# Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.17
|
||||
go: "1.22"
|
||||
|
||||
# Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
|
||||
# If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota.
|
||||
# Default: the number of logical CPUs in the machine
|
||||
concurrency: 4
|
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@ -1,8 +1,16 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"errcheck",
|
||||
"eschao",
|
||||
"gitea",
|
||||
"golangci",
|
||||
"gopkg",
|
||||
"honnef",
|
||||
"kisielk",
|
||||
"sashamelentyev",
|
||||
"staticcheck",
|
||||
"stretchr",
|
||||
"struct"
|
||||
"struct",
|
||||
"usestdlibvars"
|
||||
]
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cli
|
||||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
@ -22,8 +22,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"git.mousesoft.ru/ms/config/utils"
|
||||
)
|
||||
|
||||
// anyValue wraps a reflect.Value object and implements flag.Value interface
|
||||
@ -70,25 +68,25 @@ func (av *anyValue) Set(v string) error {
|
||||
case reflect.String:
|
||||
av.any.SetString(v)
|
||||
case reflect.Float32:
|
||||
return utils.SetValueWithFloatX(av.any, v, 32)
|
||||
return SetValueWithFloatX(av.any, v, 32)
|
||||
case reflect.Float64:
|
||||
return utils.SetValueWithFloatX(av.any, v, 64)
|
||||
return SetValueWithFloatX(av.any, v, 64)
|
||||
case reflect.Int8:
|
||||
return utils.SetValueWithIntX(av.any, v, 8)
|
||||
return SetValueWithIntX(av.any, v, 8)
|
||||
case reflect.Int16:
|
||||
return utils.SetValueWithIntX(av.any, v, 16)
|
||||
return SetValueWithIntX(av.any, v, 16)
|
||||
case reflect.Int, reflect.Int32:
|
||||
return utils.SetValueWithIntX(av.any, v, 32)
|
||||
return SetValueWithIntX(av.any, v, 32)
|
||||
case reflect.Int64:
|
||||
return utils.SetValueWithIntX(av.any, v, 64)
|
||||
return SetValueWithIntX(av.any, v, 64)
|
||||
case reflect.Uint8:
|
||||
return utils.SetValueWithUintX(av.any, v, 8)
|
||||
return SetValueWithUintX(av.any, v, 8)
|
||||
case reflect.Uint16:
|
||||
return utils.SetValueWithUintX(av.any, v, 16)
|
||||
return SetValueWithUintX(av.any, v, 16)
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
return utils.SetValueWithUintX(av.any, v, 32)
|
||||
return SetValueWithUintX(av.any, v, 32)
|
||||
case reflect.Uint64:
|
||||
return utils.SetValueWithUintX(av.any, v, 64)
|
||||
return SetValueWithUintX(av.any, v, 64)
|
||||
default:
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
@ -116,7 +114,7 @@ func (sv *sliceValue) Set(v string) error {
|
||||
if sp == "" {
|
||||
sp = ":"
|
||||
}
|
||||
return utils.SetValueWithSlice(sv.value, v, sp)
|
||||
return SetValueWithSlice(sv.value, v, sp)
|
||||
}
|
||||
|
||||
// errorHandling is a global flag.ErrorHandling
|
||||
@ -137,9 +135,9 @@ type Command struct {
|
||||
SubCommands map[string]*Command // sub-commands
|
||||
}
|
||||
|
||||
// New creates a command with given name, the command will use default
|
||||
// NewCLI creates a command with given name, the command will use default
|
||||
// ErrorHandling: flag.ExitOnError and default usage function: flag.Usage
|
||||
func New(name string) *Command {
|
||||
func NewCLI(name string) *Command {
|
||||
cmd := Command{
|
||||
Name: name,
|
||||
FlagSet: flag.NewFlagSet(name, errorHandling),
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package cli
|
||||
package config
|
||||
|
||||
import (
|
||||
"flag"
|
||||
@ -27,7 +27,7 @@ import (
|
||||
func TestServiceCommand(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
serviceConfig := test.ServiceConfig{}
|
||||
cmd := New("Service")
|
||||
cmd := NewCLI("Service")
|
||||
err := cmd.Init(&serviceConfig)
|
||||
if err != nil {
|
||||
t.Errorf("Can't init service command. %s", err.Error())
|
||||
@ -65,7 +65,7 @@ func TestServiceCommand(t *testing.T) {
|
||||
func TestLoginSubCommand(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
|
||||
cmd := New("Service")
|
||||
cmd := NewCLI("Service")
|
||||
assert.NoError(cmd.Init(&serviceConfig))
|
||||
|
||||
// assert login sub command
|
||||
@ -78,7 +78,7 @@ func TestLoginSubCommand(t *testing.T) {
|
||||
func TestLoginCommandWithValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
loginConfig := test.LoginConfig{}
|
||||
cmd := New("Login")
|
||||
cmd := NewCLI("Login")
|
||||
assert.NoError(cmd.Init(&loginConfig), "Can't init login command")
|
||||
|
||||
username := "test-user"
|
||||
@ -92,7 +92,7 @@ func TestLoginCommandWithValues(t *testing.T) {
|
||||
func TestServiceCommandWithValues(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
|
||||
cmd := New("Service")
|
||||
cmd := NewCLI("Service")
|
||||
assert.NoError(cmd.Init(&serviceConfig))
|
||||
|
||||
serviceHost := "service-hostname"
|
||||
@ -227,7 +227,7 @@ func TestVariousTypeCommand(t *testing.T) {
|
||||
func TestCommandWithSlices(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
conf := test.SlicesConfig{}
|
||||
cmd := New("Slice")
|
||||
cmd := NewCLI("Slice")
|
||||
assert.NoError(cmd.Init(&conf), "Can't init slice command")
|
||||
|
||||
paths := "/var:/home:/log"
|
35
config.go
35
config.go
@ -23,9 +23,6 @@ import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
||||
"git.mousesoft.ru/ms/config/cli"
|
||||
"git.mousesoft.ru/ms/config/env"
|
||||
"git.mousesoft.ru/ms/config/utils"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -89,35 +86,35 @@ func parseValue(v reflect.Value) error {
|
||||
kind := valueOfField.Kind()
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
err = utils.SetValueWithBool(valueOfField, defValue)
|
||||
err = SetValueWithBool(valueOfField, defValue)
|
||||
case reflect.String:
|
||||
valueOfField.SetString(defValue)
|
||||
case reflect.Int8:
|
||||
err = utils.SetValueWithIntX(valueOfField, defValue, 8)
|
||||
err = SetValueWithIntX(valueOfField, defValue, 8)
|
||||
case reflect.Int16:
|
||||
err = utils.SetValueWithIntX(valueOfField, defValue, 16)
|
||||
err = SetValueWithIntX(valueOfField, defValue, 16)
|
||||
case reflect.Int, reflect.Int32:
|
||||
err = utils.SetValueWithIntX(valueOfField, defValue, 32)
|
||||
err = SetValueWithIntX(valueOfField, defValue, 32)
|
||||
case reflect.Int64:
|
||||
err = utils.SetValueWithIntX(valueOfField, defValue, 64)
|
||||
err = SetValueWithIntX(valueOfField, defValue, 64)
|
||||
case reflect.Uint8:
|
||||
err = utils.SetValueWithUintX(valueOfField, defValue, 8)
|
||||
err = SetValueWithUintX(valueOfField, defValue, 8)
|
||||
case reflect.Uint16:
|
||||
err = utils.SetValueWithUintX(valueOfField, defValue, 16)
|
||||
err = SetValueWithUintX(valueOfField, defValue, 16)
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
err = utils.SetValueWithUintX(valueOfField, defValue, 32)
|
||||
err = SetValueWithUintX(valueOfField, defValue, 32)
|
||||
case reflect.Uint64:
|
||||
err = utils.SetValueWithUintX(valueOfField, defValue, 64)
|
||||
err = SetValueWithUintX(valueOfField, defValue, 64)
|
||||
case reflect.Float32:
|
||||
err = utils.SetValueWithFloatX(valueOfField, defValue, 32)
|
||||
err = SetValueWithFloatX(valueOfField, defValue, 32)
|
||||
case reflect.Float64:
|
||||
err = utils.SetValueWithFloatX(valueOfField, defValue, 64)
|
||||
err = SetValueWithFloatX(valueOfField, defValue, 64)
|
||||
case reflect.Slice:
|
||||
sp, ok := structOfField.Tag.Lookup("separator")
|
||||
if !ok {
|
||||
sp = ":"
|
||||
}
|
||||
err = utils.SetValueWithSlice(valueOfField, defValue, sp)
|
||||
err = SetValueWithSlice(valueOfField, defValue, sp)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
@ -127,15 +124,9 @@ func parseValue(v reflect.Value) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ParseEnv parses given structure interface and set it with corresponding
|
||||
// environment values
|
||||
func ParseEnv(i interface{}) error {
|
||||
return env.ParseWith(i, "")
|
||||
}
|
||||
|
||||
// ParseCli parses given structure interface and set it with command line input
|
||||
func ParseCli(i interface{}) error {
|
||||
cli := cli.New(os.Args[0])
|
||||
cli := NewCLI(os.Args[0])
|
||||
if err := cli.Init(i); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -26,21 +26,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
LOGIN_USER = "test-login-user"
|
||||
LOGIN_PASSWORD = "test-login-passwd"
|
||||
SERVICE_HOST = "test-service-host"
|
||||
SERVICE_PORT = 8080
|
||||
SERVICE_LOG_PATH = "/var/log/service"
|
||||
SERVICE_LOG_LEVEL = "debug"
|
||||
DB_HOST = "test-db-host"
|
||||
DB_PORT = 9090
|
||||
DB_USER = "test-db-user"
|
||||
DB_PASSWORD = "test-db-password"
|
||||
DB_LOG_PATH = "/var/log/db"
|
||||
DB_LOG_LEVEL = "error"
|
||||
)
|
||||
|
||||
func TestDefaultValueConfig(t *testing.T) {
|
||||
conf := test.DefValueConfig{}
|
||||
assert := assert.New(t)
|
||||
@ -60,29 +45,41 @@ func TestDefaultValueConfig(t *testing.T) {
|
||||
func TestEnvConfig(t *testing.T) {
|
||||
dbLogPrefix := "LOG_"
|
||||
|
||||
os.Setenv("HOST", DB_HOST)
|
||||
os.Setenv("PORT", strconv.Itoa(DB_PORT))
|
||||
os.Setenv("USER", DB_USER)
|
||||
os.Setenv("PASSWORD", DB_PASSWORD)
|
||||
os.Setenv(dbLogPrefix+"PATH", DB_LOG_PATH)
|
||||
os.Setenv(dbLogPrefix+"LEVEL", DB_LOG_LEVEL)
|
||||
var err error
|
||||
|
||||
defer os.Unsetenv("HOST")
|
||||
defer os.Unsetenv("PORT")
|
||||
defer os.Unsetenv("USER")
|
||||
defer os.Unsetenv("PASSWORD")
|
||||
defer os.Unsetenv(dbLogPrefix + "PATH")
|
||||
defer os.Unsetenv(dbLogPrefix + "LEVEL")
|
||||
err = os.Setenv("HOST", DB_HOST)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv("PORT", strconv.Itoa(DB_PORT))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv("USER", DB_USER)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv("PASSWORD", DB_PASSWORD)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbLogPrefix+"PATH", DB_LOG_PATH)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbLogPrefix+"LEVEL", DB_LOG_LEVEL)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv("HOST") }()
|
||||
defer func() { _ = os.Unsetenv("PORT") }()
|
||||
defer func() { _ = os.Unsetenv("USER") }()
|
||||
defer func() { _ = os.Unsetenv("PASSWORD") }()
|
||||
defer func() { _ = os.Unsetenv(dbLogPrefix + "PATH") }()
|
||||
defer func() { _ = os.Unsetenv(dbLogPrefix + "LEVEL") }()
|
||||
|
||||
conf := test.DBConfig{}
|
||||
assert := assert.New(t)
|
||||
assert.NoError(ParseEnv(&conf))
|
||||
assert.Equal(DB_HOST, conf.Host)
|
||||
assert.Equal(DB_PORT, conf.Port)
|
||||
assert.Equal(DB_USER, conf.User)
|
||||
assert.Equal(DB_PASSWORD, conf.Password)
|
||||
assert.Equal(DB_LOG_PATH, conf.Log.Path)
|
||||
assert.Equal(DB_LOG_LEVEL, conf.Log.Level)
|
||||
assert.NoError(t, ParseEnv(&conf))
|
||||
assert.Equal(t, DB_HOST, conf.Host)
|
||||
assert.Equal(t, DB_PORT, conf.Port)
|
||||
assert.Equal(t, DB_USER, conf.User)
|
||||
assert.Equal(t, DB_PASSWORD, conf.Password)
|
||||
assert.Equal(t, DB_LOG_PATH, conf.Log.Path)
|
||||
assert.Equal(t, DB_LOG_LEVEL, conf.Log.Level)
|
||||
}
|
||||
|
||||
func TestJSONConfigFile(t *testing.T) {
|
||||
|
@ -13,20 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package env
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
|
||||
"git.mousesoft.ru/ms/config/utils"
|
||||
)
|
||||
|
||||
// Parse parses given structure interface, extracts environment definitions
|
||||
// from its tag and sets structure with defined environment variables
|
||||
func Parse(i interface{}) error {
|
||||
return ParseWith(i, "")
|
||||
func ParseEnv(i interface{}) error {
|
||||
return ParseEnvWith(i, "")
|
||||
}
|
||||
|
||||
// ParseWith parses with given structure interface and environment name prefix
|
||||
@ -43,7 +41,7 @@ func Parse(i interface{}) error {
|
||||
//
|
||||
// The Server.DB.Host will be mapped to environment variable: DB_HOST which is
|
||||
// concatenated from DB tag in Server struct and Host tag in Database struct
|
||||
func ParseWith(i interface{}, prefix string) error {
|
||||
func ParseEnvWith(i interface{}, prefix string) error {
|
||||
ptrRef := reflect.ValueOf(i)
|
||||
|
||||
if ptrRef.IsNil() || ptrRef.Kind() != reflect.Ptr {
|
||||
@ -57,11 +55,11 @@ func ParseWith(i interface{}, prefix string) error {
|
||||
valueOfStruct.Kind().String())
|
||||
}
|
||||
|
||||
return parseValue(valueOfStruct, prefix)
|
||||
return parseValueEnv(valueOfStruct, prefix)
|
||||
}
|
||||
|
||||
// parseValue parses a reflect.Value object
|
||||
func parseValue(v reflect.Value, prefix string) error {
|
||||
func parseValueEnv(v reflect.Value, prefix string) error {
|
||||
typeOfStruct := v.Type()
|
||||
var err error
|
||||
for i := 0; i < v.NumField() && err == nil; i++ {
|
||||
@ -72,27 +70,27 @@ func parseValue(v reflect.Value, prefix string) error {
|
||||
// recursively unmarshal if value is ptr type
|
||||
if kindOfField == reflect.Ptr {
|
||||
if !valueOfField.IsNil() && valueOfField.CanSet() {
|
||||
err = ParseWith(valueOfField.Interface(),
|
||||
err = ParseEnvWith(valueOfField.Interface(),
|
||||
prefix+structOfField.Tag.Get("env"))
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if kindOfField == reflect.Struct {
|
||||
err = parseValue(valueOfField, prefix+structOfField.Tag.Get("env"))
|
||||
err = parseValueEnv(valueOfField, prefix+structOfField.Tag.Get("env"))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = setFieldValue(valueOfField, structOfField, prefix)
|
||||
err = setFieldValueEnv(valueOfField, structOfField, prefix)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// setFieldValue sets a reflect.Value with environment value
|
||||
func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error {
|
||||
func setFieldValueEnv(v reflect.Value, f reflect.StructField, prefix string) error {
|
||||
envName := f.Tag.Get("env")
|
||||
if envName == "" {
|
||||
return nil
|
||||
@ -111,36 +109,36 @@ func setFieldValue(v reflect.Value, f reflect.StructField, prefix string) error
|
||||
kind := v.Kind()
|
||||
switch kind {
|
||||
case reflect.Bool:
|
||||
err = utils.SetValueWithBool(v, envValue)
|
||||
err = SetValueWithBool(v, envValue)
|
||||
case reflect.String:
|
||||
v.SetString(envValue)
|
||||
case reflect.Int8:
|
||||
err = utils.SetValueWithIntX(v, envValue, 8)
|
||||
err = SetValueWithIntX(v, envValue, 8)
|
||||
case reflect.Int16:
|
||||
err = utils.SetValueWithIntX(v, envValue, 16)
|
||||
err = SetValueWithIntX(v, envValue, 16)
|
||||
case reflect.Int, reflect.Int32:
|
||||
err = utils.SetValueWithIntX(v, envValue, 32)
|
||||
err = SetValueWithIntX(v, envValue, 32)
|
||||
case reflect.Int64:
|
||||
err = utils.SetValueWithIntX(v, envValue, 64)
|
||||
err = SetValueWithIntX(v, envValue, 64)
|
||||
case reflect.Uint8:
|
||||
err = utils.SetValueWithUintX(v, envValue, 8)
|
||||
err = SetValueWithUintX(v, envValue, 8)
|
||||
case reflect.Uint16:
|
||||
err = utils.SetValueWithUintX(v, envValue, 16)
|
||||
err = SetValueWithUintX(v, envValue, 16)
|
||||
case reflect.Uint, reflect.Uint32:
|
||||
err = utils.SetValueWithUintX(v, envValue, 32)
|
||||
err = SetValueWithUintX(v, envValue, 32)
|
||||
case reflect.Uint64:
|
||||
err = utils.SetValueWithUintX(v, envValue, 64)
|
||||
err = SetValueWithUintX(v, envValue, 64)
|
||||
case reflect.Float32:
|
||||
err = utils.SetValueWithFloatX(v, envValue, 32)
|
||||
err = SetValueWithFloatX(v, envValue, 32)
|
||||
case reflect.Float64:
|
||||
err = utils.SetValueWithFloatX(v, envValue, 64)
|
||||
err = SetValueWithFloatX(v, envValue, 64)
|
||||
|
||||
case reflect.Slice:
|
||||
sp, ok := f.Tag.Lookup("separator")
|
||||
if !ok {
|
||||
sp = ":"
|
||||
}
|
||||
err = utils.SetValueWithSlice(v, envValue, sp)
|
||||
err = SetValueWithSlice(v, envValue, sp)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
274
env/env_test.go
vendored
274
env/env_test.go
vendored
@ -1,274 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 eschao <esc.chao@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package env
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"git.mousesoft.ru/ms/config/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
LOGIN_USER = "test-login-user"
|
||||
LOGIN_PASSWORD = "test-login-passwd"
|
||||
SERVICE_HOST = "test-service-host"
|
||||
SERVICE_PORT = 8080
|
||||
SERVICE_LOG_PATH = "/var/log/service"
|
||||
SERVICE_LOG_LEVEL = "debug"
|
||||
DB_HOST = "test-db-host"
|
||||
DB_PORT = 9090
|
||||
DB_USER = "test-db-user"
|
||||
DB_PASSWORD = "test-db-password"
|
||||
DB_LOG_PATH = "/var/log/db"
|
||||
DB_LOG_LEVEL = "error"
|
||||
)
|
||||
|
||||
func TestLoginConfigEnv(t *testing.T) {
|
||||
os.Setenv("USER", LOGIN_USER)
|
||||
os.Setenv("PASSWORD", LOGIN_PASSWORD)
|
||||
defer os.Unsetenv("USER")
|
||||
defer os.Unsetenv("PASSWORD")
|
||||
|
||||
assert := assert.New(t)
|
||||
loginConfig := test.LoginConfig{}
|
||||
assert.NoError(Parse(&loginConfig))
|
||||
|
||||
assert.Equal(LOGIN_USER, loginConfig.User)
|
||||
assert.Equal(LOGIN_PASSWORD, loginConfig.Password)
|
||||
}
|
||||
|
||||
func TestLoginConfigEnvWithPrefix(t *testing.T) {
|
||||
os.Setenv("DB_USER", LOGIN_USER)
|
||||
os.Setenv("DB_PASSWORD", LOGIN_PASSWORD)
|
||||
defer os.Unsetenv("DB_USER")
|
||||
defer os.Unsetenv("DB_PASSWORD")
|
||||
|
||||
assert := assert.New(t)
|
||||
loginConfig := test.LoginConfig{}
|
||||
assert.NoError(ParseWith(&loginConfig, "DB_"))
|
||||
assert.Equal(LOGIN_USER, loginConfig.User)
|
||||
assert.Equal(LOGIN_PASSWORD, loginConfig.Password)
|
||||
}
|
||||
|
||||
func TestServiceConfigEnv(t *testing.T) {
|
||||
servicePrefix := "CONFIG_TEST_SERVICE_"
|
||||
serviceLogPrefix := servicePrefix + "LOG_"
|
||||
dbPrefix := servicePrefix + "DB_"
|
||||
dbLogPrefix := dbPrefix + "LOG_"
|
||||
|
||||
os.Setenv(servicePrefix+"HOST", SERVICE_HOST)
|
||||
os.Setenv(servicePrefix+"PORT", strconv.Itoa(SERVICE_PORT))
|
||||
os.Setenv(serviceLogPrefix+"PATH", SERVICE_LOG_PATH)
|
||||
os.Setenv(serviceLogPrefix+"LEVEL", SERVICE_LOG_LEVEL)
|
||||
os.Setenv(dbPrefix+"HOST", DB_HOST)
|
||||
os.Setenv(dbPrefix+"PORT", strconv.Itoa(DB_PORT))
|
||||
os.Setenv(dbPrefix+"USER", DB_USER)
|
||||
os.Setenv(dbPrefix+"PASSWORD", DB_PASSWORD)
|
||||
os.Setenv(dbLogPrefix+"PATH", DB_LOG_PATH)
|
||||
os.Setenv(dbLogPrefix+"LEVEL", DB_LOG_LEVEL)
|
||||
|
||||
defer os.Unsetenv(servicePrefix + "HOST")
|
||||
defer os.Unsetenv(servicePrefix + "PORT")
|
||||
defer os.Unsetenv(serviceLogPrefix + "PATH")
|
||||
defer os.Unsetenv(serviceLogPrefix + "LEVEL")
|
||||
defer os.Unsetenv(dbPrefix + "HOST")
|
||||
defer os.Unsetenv(dbPrefix + "PORT")
|
||||
defer os.Unsetenv(dbPrefix + "USER")
|
||||
defer os.Unsetenv(dbPrefix + "PASSWORD")
|
||||
defer os.Unsetenv(dbLogPrefix + "PATH")
|
||||
defer os.Unsetenv(dbLogPrefix + "LEVEL")
|
||||
|
||||
assert := assert.New(t)
|
||||
serviceConfig := test.ServiceConfig{}
|
||||
assert.NoError(Parse(&serviceConfig))
|
||||
assert.Equal(SERVICE_HOST, serviceConfig.Host)
|
||||
assert.Equal(SERVICE_PORT, serviceConfig.Port)
|
||||
assert.Equal(SERVICE_LOG_PATH, serviceConfig.Log.Path)
|
||||
assert.Equal(SERVICE_LOG_LEVEL, serviceConfig.Log.Level)
|
||||
assert.Equal(DB_HOST, serviceConfig.DBConfig.Host)
|
||||
assert.Equal(DB_PORT, serviceConfig.DBConfig.Port)
|
||||
assert.Equal(DB_USER, serviceConfig.DBConfig.User)
|
||||
assert.Equal(DB_PASSWORD, serviceConfig.DBConfig.Password)
|
||||
assert.Equal(DB_LOG_PATH, serviceConfig.DBConfig.Log.Path)
|
||||
assert.Equal(DB_LOG_LEVEL, serviceConfig.DBConfig.Log.Level)
|
||||
}
|
||||
|
||||
func TestServiceLoginConfigEnv(t *testing.T) {
|
||||
serviceLoginPrefix := "CONFIG_TEST_SERVICE_LOGIN_"
|
||||
os.Setenv(serviceLoginPrefix+"USER", LOGIN_USER)
|
||||
os.Setenv(serviceLoginPrefix+"PASSWORD", LOGIN_PASSWORD)
|
||||
defer os.Unsetenv(serviceLoginPrefix + "USER")
|
||||
defer os.Unsetenv(serviceLoginPrefix + "PASSWORD")
|
||||
|
||||
assert := assert.New(t)
|
||||
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
|
||||
assert.NoError(Parse(&serviceConfig))
|
||||
assert.Equal(LOGIN_USER, serviceConfig.Login.User)
|
||||
assert.Equal(LOGIN_PASSWORD, serviceConfig.Login.Password)
|
||||
}
|
||||
|
||||
func TestTypesConfigEnv(t *testing.T) {
|
||||
typesPrefix := "CONFIG_TEST_"
|
||||
os.Setenv(typesPrefix+"BOOL", "true")
|
||||
os.Setenv(typesPrefix+"STR", "test-string")
|
||||
os.Setenv(typesPrefix+"INT8", "100")
|
||||
os.Setenv(typesPrefix+"INT16", "1000")
|
||||
os.Setenv(typesPrefix+"INT", "10000")
|
||||
os.Setenv(typesPrefix+"INT32", "100000")
|
||||
os.Setenv(typesPrefix+"INT64", "1000000")
|
||||
os.Setenv(typesPrefix+"UINT8", "200")
|
||||
os.Setenv(typesPrefix+"UINT16", "2000")
|
||||
os.Setenv(typesPrefix+"UINT", "20000")
|
||||
os.Setenv(typesPrefix+"UINT32", "200000")
|
||||
os.Setenv(typesPrefix+"UINT64", "2000000")
|
||||
os.Setenv(typesPrefix+"FLOAT32", "1.234")
|
||||
os.Setenv(typesPrefix+"FLOAT64", "2222.33333")
|
||||
|
||||
defer os.Unsetenv(typesPrefix + "BOOL")
|
||||
defer os.Unsetenv(typesPrefix + "STR")
|
||||
defer os.Unsetenv(typesPrefix + "INT8")
|
||||
defer os.Unsetenv(typesPrefix + "INT16")
|
||||
defer os.Unsetenv(typesPrefix + "INT")
|
||||
defer os.Unsetenv(typesPrefix + "INT32")
|
||||
defer os.Unsetenv(typesPrefix + "INT64")
|
||||
defer os.Unsetenv(typesPrefix + "UINT8")
|
||||
defer os.Unsetenv(typesPrefix + "UINT16")
|
||||
defer os.Unsetenv(typesPrefix + "UINT")
|
||||
defer os.Unsetenv(typesPrefix + "UINT32")
|
||||
defer os.Unsetenv(typesPrefix + "UINT64")
|
||||
defer os.Unsetenv(typesPrefix + "FLOAT32")
|
||||
defer os.Unsetenv(typesPrefix + "FLOAT64")
|
||||
|
||||
assert := assert.New(t)
|
||||
typesConfig := test.TypesConfig{}
|
||||
assert.NoError(Parse(&typesConfig))
|
||||
assert.Equal(true, typesConfig.BoolValue)
|
||||
assert.Equal("test-string", typesConfig.StrValue)
|
||||
assert.Equal(int8(100), typesConfig.Int8Value)
|
||||
assert.Equal(int16(1000), typesConfig.Int16Value)
|
||||
assert.Equal(10000, typesConfig.IntValue)
|
||||
assert.Equal(int32(100000), typesConfig.Int32Value)
|
||||
assert.Equal(int64(1000000), typesConfig.Int64Value)
|
||||
assert.Equal(uint8(200), typesConfig.Uint8Value)
|
||||
assert.Equal(uint16(2000), typesConfig.Uint16Value)
|
||||
assert.Equal(uint(20000), typesConfig.UintValue)
|
||||
assert.Equal(uint32(200000), typesConfig.Uint32Value)
|
||||
assert.Equal(uint64(2000000), typesConfig.Uint64Value)
|
||||
assert.Equal(float32(1.234), typesConfig.Float32Value)
|
||||
assert.Equal(float64(2222.33333), typesConfig.Float64Value)
|
||||
}
|
||||
|
||||
func TestTypesConfigWithErrorEnv(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
typesConfig := test.TypesConfig{}
|
||||
typesPrefix := "CONFIG_TEST_"
|
||||
os.Setenv(typesPrefix+"BOOL", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "BOOL")
|
||||
|
||||
os.Setenv(typesPrefix+"INT8", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "INT8")
|
||||
|
||||
os.Setenv(typesPrefix+"INT16", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "INT16")
|
||||
|
||||
os.Setenv(typesPrefix+"INT", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "INT")
|
||||
|
||||
os.Setenv(typesPrefix+"INT32", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "INT32")
|
||||
|
||||
os.Setenv(typesPrefix+"INT64", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "INT64")
|
||||
|
||||
os.Setenv(typesPrefix+"UINT8", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "UINT8")
|
||||
|
||||
os.Setenv(typesPrefix+"UINT16", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "UINT16")
|
||||
|
||||
os.Setenv(typesPrefix+"UINT", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "UINT")
|
||||
|
||||
os.Setenv(typesPrefix+"UINT32", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "UINT32")
|
||||
|
||||
os.Setenv(typesPrefix+"UINT64", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "UINT64")
|
||||
|
||||
os.Setenv(typesPrefix+"FLOAT32", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "FLOAT32")
|
||||
|
||||
os.Setenv(typesPrefix+"FLOAT64", "xxx")
|
||||
assert.Error(Parse(&typesConfig))
|
||||
os.Unsetenv(typesPrefix + "FLOAT64")
|
||||
|
||||
defer os.Unsetenv(typesPrefix + "BOOL")
|
||||
defer os.Unsetenv(typesPrefix + "INT8")
|
||||
defer os.Unsetenv(typesPrefix + "INT16")
|
||||
defer os.Unsetenv(typesPrefix + "INT")
|
||||
defer os.Unsetenv(typesPrefix + "INT32")
|
||||
defer os.Unsetenv(typesPrefix + "INT64")
|
||||
defer os.Unsetenv(typesPrefix + "UINT8")
|
||||
defer os.Unsetenv(typesPrefix + "UINT16")
|
||||
defer os.Unsetenv(typesPrefix + "UINT")
|
||||
defer os.Unsetenv(typesPrefix + "UINT32")
|
||||
defer os.Unsetenv(typesPrefix + "UINT64")
|
||||
defer os.Unsetenv(typesPrefix + "FLOAT32")
|
||||
defer os.Unsetenv(typesPrefix + "FLOAT64")
|
||||
}
|
||||
|
||||
func TestSlicesConfigEnv(t *testing.T) {
|
||||
prefix := "CONFIG_TEST_SLICES_"
|
||||
os.Setenv(prefix+"PATHS", "/var:/usr:/home")
|
||||
os.Setenv(prefix+"DEBUG", "/root;/log;/opt")
|
||||
os.Setenv(prefix+"VALUES", "1,2,4,5")
|
||||
|
||||
defer os.Unsetenv(prefix + "PATHS")
|
||||
defer os.Unsetenv(prefix + "DEBUG")
|
||||
defer os.Unsetenv(prefix + "VALUES")
|
||||
|
||||
assert := assert.New(t)
|
||||
conf := test.SlicesConfig{}
|
||||
assert.NoError(Parse(&conf))
|
||||
assert.Equal(3, len(conf.Paths))
|
||||
assert.Equal("/var", conf.Paths[0])
|
||||
assert.Equal("/usr", conf.Paths[1])
|
||||
assert.Equal("/home", conf.Paths[2])
|
||||
assert.Equal(3, len(conf.Debugs))
|
||||
assert.Equal("/root", conf.Debugs[0])
|
||||
assert.Equal("/log", conf.Debugs[1])
|
||||
assert.Equal("/opt", conf.Debugs[2])
|
||||
assert.Equal(4, len(conf.Values))
|
||||
assert.Equal(1, conf.Values[0])
|
||||
assert.Equal(2, conf.Values[1])
|
||||
assert.Equal(4, conf.Values[2])
|
||||
assert.Equal(5, conf.Values[3])
|
||||
}
|
401
env_test.go
Normal file
401
env_test.go
Normal file
@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Copyright (C) 2017 eschao <esc.chao@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"git.mousesoft.ru/ms/config/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const (
|
||||
LOGIN_USER = "test-login-user"
|
||||
LOGIN_PASSWORD = "test-login-passwd"
|
||||
SERVICE_HOST = "test-service-host"
|
||||
SERVICE_PORT = 8080
|
||||
SERVICE_LOG_PATH = "/var/log/service"
|
||||
SERVICE_LOG_LEVEL = "debug"
|
||||
DB_HOST = "test-db-host"
|
||||
DB_PORT = 9090
|
||||
DB_USER = "test-db-user"
|
||||
DB_PASSWORD = "test-db-password"
|
||||
DB_LOG_PATH = "/var/log/db"
|
||||
DB_LOG_LEVEL = "error"
|
||||
)
|
||||
|
||||
func TestLoginConfigEnv(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = os.Setenv("USER", LOGIN_USER)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv("PASSWORD", LOGIN_PASSWORD)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv("USER") }()
|
||||
defer func() { _ = os.Unsetenv("PASSWORD") }()
|
||||
|
||||
loginConfig := test.LoginConfig{}
|
||||
assert.NoError(t, ParseEnv(&loginConfig))
|
||||
|
||||
assert.Equal(t, LOGIN_USER, loginConfig.User)
|
||||
assert.Equal(t, LOGIN_PASSWORD, loginConfig.Password)
|
||||
}
|
||||
|
||||
func TestLoginConfigEnvWithPrefix(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = os.Setenv("DB_USER", LOGIN_USER)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv("DB_PASSWORD", LOGIN_PASSWORD)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv("DB_USER") }()
|
||||
defer func() { _ = os.Unsetenv("DB_PASSWORD") }()
|
||||
|
||||
loginConfig := test.LoginConfig{}
|
||||
assert.NoError(t, ParseEnvWith(&loginConfig, "DB_"))
|
||||
assert.Equal(t, LOGIN_USER, loginConfig.User)
|
||||
assert.Equal(t, LOGIN_PASSWORD, loginConfig.Password)
|
||||
}
|
||||
|
||||
func TestServiceConfigEnv(t *testing.T) {
|
||||
servicePrefix := "CONFIG_TEST_SERVICE_"
|
||||
serviceLogPrefix := servicePrefix + "LOG_"
|
||||
dbPrefix := servicePrefix + "DB_"
|
||||
dbLogPrefix := dbPrefix + "LOG_"
|
||||
|
||||
err := os.Setenv(servicePrefix+"HOST", SERVICE_HOST)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(servicePrefix+"PORT", strconv.Itoa(SERVICE_PORT))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(serviceLogPrefix+"PATH", SERVICE_LOG_PATH)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(serviceLogPrefix+"LEVEL", SERVICE_LOG_LEVEL)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbPrefix+"HOST", DB_HOST)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbPrefix+"PORT", strconv.Itoa(DB_PORT))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbPrefix+"USER", DB_USER)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbPrefix+"PASSWORD", DB_PASSWORD)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbLogPrefix+"PATH", DB_LOG_PATH)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(dbLogPrefix+"LEVEL", DB_LOG_LEVEL)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv(servicePrefix + "HOST") }()
|
||||
defer func() { _ = os.Unsetenv(servicePrefix + "PORT") }()
|
||||
defer func() { _ = os.Unsetenv(serviceLogPrefix + "PATH") }()
|
||||
defer func() { _ = os.Unsetenv(serviceLogPrefix + "LEVEL") }()
|
||||
defer func() { _ = os.Unsetenv(dbPrefix + "HOST") }()
|
||||
defer func() { _ = os.Unsetenv(dbPrefix + "PORT") }()
|
||||
defer func() { _ = os.Unsetenv(dbPrefix + "USER") }()
|
||||
defer func() { _ = os.Unsetenv(dbPrefix + "PASSWORD") }()
|
||||
defer func() { _ = os.Unsetenv(dbLogPrefix + "PATH") }()
|
||||
defer func() { _ = os.Unsetenv(dbLogPrefix + "LEVEL") }()
|
||||
|
||||
serviceConfig := test.ServiceConfig{}
|
||||
assert.NoError(t, ParseEnv(&serviceConfig))
|
||||
assert.Equal(t, SERVICE_HOST, serviceConfig.Host)
|
||||
assert.Equal(t, SERVICE_PORT, serviceConfig.Port)
|
||||
assert.Equal(t, SERVICE_LOG_PATH, serviceConfig.Log.Path)
|
||||
assert.Equal(t, SERVICE_LOG_LEVEL, serviceConfig.Log.Level)
|
||||
assert.Equal(t, DB_HOST, serviceConfig.DBConfig.Host)
|
||||
assert.Equal(t, DB_PORT, serviceConfig.DBConfig.Port)
|
||||
assert.Equal(t, DB_USER, serviceConfig.DBConfig.User)
|
||||
assert.Equal(t, DB_PASSWORD, serviceConfig.DBConfig.Password)
|
||||
assert.Equal(t, DB_LOG_PATH, serviceConfig.DBConfig.Log.Path)
|
||||
assert.Equal(t, DB_LOG_LEVEL, serviceConfig.DBConfig.Log.Level)
|
||||
}
|
||||
|
||||
func TestServiceLoginConfigEnv(t *testing.T) {
|
||||
var err error
|
||||
|
||||
serviceLoginPrefix := "CONFIG_TEST_SERVICE_LOGIN_"
|
||||
|
||||
err = os.Setenv(serviceLoginPrefix+"USER", LOGIN_USER)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(serviceLoginPrefix+"PASSWORD", LOGIN_PASSWORD)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv(serviceLoginPrefix + "USER") }()
|
||||
defer func() { _ = os.Unsetenv(serviceLoginPrefix + "PASSWORD") }()
|
||||
|
||||
serviceConfig := test.ServiceConfig{Login: &test.LoginConfig{}}
|
||||
assert.NoError(t, ParseEnv(&serviceConfig))
|
||||
assert.Equal(t, LOGIN_USER, serviceConfig.Login.User)
|
||||
assert.Equal(t, LOGIN_PASSWORD, serviceConfig.Login.Password)
|
||||
}
|
||||
|
||||
func TestTypesConfigEnv(t *testing.T) {
|
||||
var err error
|
||||
|
||||
typesPrefix := "CONFIG_TEST_"
|
||||
|
||||
err = os.Setenv(typesPrefix+"BOOL", "true")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"STR", "test-string")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT8", "100")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT16", "1000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT", "10000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT32", "100000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT64", "1000000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT8", "200")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT16", "2000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT", "20000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT32", "200000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT64", "2000000")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"FLOAT32", "1.234")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"FLOAT64", "2222.33333")
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "BOOL") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "STR") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT8") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT16") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT64") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT8") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT16") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT64") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "FLOAT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "FLOAT64") }()
|
||||
|
||||
typesConfig := test.TypesConfig{}
|
||||
|
||||
err = ParseEnv(&typesConfig)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.True(t, typesConfig.BoolValue)
|
||||
assert.Equal(t, "test-string", typesConfig.StrValue)
|
||||
assert.Equal(t, int8(100), typesConfig.Int8Value)
|
||||
assert.Equal(t, int16(1000), typesConfig.Int16Value)
|
||||
assert.Equal(t, 10000, typesConfig.IntValue)
|
||||
assert.Equal(t, int32(100000), typesConfig.Int32Value)
|
||||
assert.Equal(t, int64(1000000), typesConfig.Int64Value)
|
||||
assert.Equal(t, uint8(200), typesConfig.Uint8Value)
|
||||
assert.Equal(t, uint16(2000), typesConfig.Uint16Value)
|
||||
assert.Equal(t, uint(20000), typesConfig.UintValue)
|
||||
assert.Equal(t, uint32(200000), typesConfig.Uint32Value)
|
||||
assert.Equal(t, uint64(2000000), typesConfig.Uint64Value)
|
||||
assert.Equal(t, float32(1.234), typesConfig.Float32Value)
|
||||
assert.Equal(t, float64(2222.33333), typesConfig.Float64Value)
|
||||
}
|
||||
|
||||
func TestTypesConfigWithErrorEnv(t *testing.T) {
|
||||
var err error
|
||||
|
||||
typesConfig := test.TypesConfig{}
|
||||
typesPrefix := "CONFIG_TEST_"
|
||||
|
||||
err = os.Setenv(typesPrefix+"BOOL", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "BOOL")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT8", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "INT8")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT16", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "INT16")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "INT")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT32", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "INT32")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"INT64", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "INT64")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT8", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "UINT8")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT16", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "UINT16")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "UINT")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT32", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "UINT32")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"UINT64", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "UINT64")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"FLOAT32", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "FLOAT32")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(typesPrefix+"FLOAT64", "xxx")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Error(t, ParseEnv(&typesConfig))
|
||||
|
||||
err = os.Unsetenv(typesPrefix + "FLOAT64")
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "BOOL") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT8") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT16") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "INT64") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT8") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT16") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "UINT64") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "FLOAT32") }()
|
||||
defer func() { _ = os.Unsetenv(typesPrefix + "FLOAT64") }()
|
||||
}
|
||||
|
||||
func TestSlicesConfigEnv(t *testing.T) {
|
||||
var err error
|
||||
|
||||
prefix := "CONFIG_TEST_SLICES_"
|
||||
|
||||
err = os.Setenv(prefix+"PATHS", "/var:/usr:/home")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(prefix+"DEBUG", "/root;/log;/opt")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = os.Setenv(prefix+"VALUES", "1,2,4,5")
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() { _ = os.Unsetenv(prefix + "PATHS") }()
|
||||
defer func() { _ = os.Unsetenv(prefix + "DEBUG") }()
|
||||
defer func() { _ = os.Unsetenv(prefix + "VALUES") }()
|
||||
|
||||
conf := test.SlicesConfig{}
|
||||
assert.NoError(t, ParseEnv(&conf))
|
||||
assert.Equal(t, 3, len(conf.Paths))
|
||||
assert.Equal(t, "/var", conf.Paths[0])
|
||||
assert.Equal(t, "/usr", conf.Paths[1])
|
||||
assert.Equal(t, "/home", conf.Paths[2])
|
||||
assert.Equal(t, 3, len(conf.Debugs))
|
||||
assert.Equal(t, "/root", conf.Debugs[0])
|
||||
assert.Equal(t, "/log", conf.Debugs[1])
|
||||
assert.Equal(t, "/opt", conf.Debugs[2])
|
||||
assert.Equal(t, 4, len(conf.Values))
|
||||
assert.Equal(t, 1, conf.Values[0])
|
||||
assert.Equal(t, 2, conf.Values[1])
|
||||
assert.Equal(t, 4, conf.Values[2])
|
||||
assert.Equal(t, 5, conf.Values[3])
|
||||
}
|
110
makefile
Normal file
110
makefile
Normal file
@ -0,0 +1,110 @@
|
||||
# chess-record makefile
|
||||
# =====================
|
||||
|
||||
SHELL := /usr/bin/env bash
|
||||
|
||||
PROJECT_ID := config
|
||||
PROJECT_NAME ?= MouseSoft Config
|
||||
BIN_SUFFIX :=
|
||||
|
||||
TMPDIR ?= $(CURDIR)/tmp
|
||||
OUTDIR ?= $(CURDIR)/out
|
||||
BINDIR ?= $(OUTDIR)/bin
|
||||
|
||||
VERSION ?= $(strip $(shell ./scripts/version.sh))
|
||||
VERSION_NUMBER := $(strip $(shell ./scripts/version.sh number))
|
||||
|
||||
BUILD_ARCH ?= $(shell go env GOARCH)
|
||||
BUILD_OS ?= $(shell go env GOOS)
|
||||
|
||||
GOCMD := go
|
||||
GOTEST := $(GOCMD) test
|
||||
GOVET := $(GOCMD) vet
|
||||
ECHO_CMD := echo -e
|
||||
|
||||
GREEN := $(shell tput -Txterm setaf 2)
|
||||
YELLOW := $(shell tput -Txterm setaf 3)
|
||||
WHITE := $(shell tput -Txterm setaf 7)
|
||||
CYAN := $(shell tput -Txterm setaf 6)
|
||||
RESET := $(shell tput -Txterm sgr0)
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
version: ## Version of the project to be built
|
||||
@echo $(VERSION)
|
||||
.PHONY:version
|
||||
|
||||
version-number: ## Version number of the project to be built
|
||||
@echo $(VERSION_NUMBER)
|
||||
.PHONY:version-number
|
||||
|
||||
## Build
|
||||
|
||||
all: clean vendor test ## Build binary
|
||||
.PHONY:all
|
||||
|
||||
vendor: ## Copy of all packages needed to support builds and tests in the vendor directory
|
||||
$(GOCMD) mod vendor
|
||||
@$(ECHO_CMD) "Vendor\t\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:vendor
|
||||
|
||||
clean: ## Remove build related files
|
||||
@rm -fr $(TMPDIR)
|
||||
@rm -fr $(OUTDIR)
|
||||
@$(ECHO_CMD) "Clean\t\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:clean
|
||||
|
||||
## Test
|
||||
|
||||
test: ## Run the tests of the project
|
||||
ifeq ($(EXPORT_RESULT), true)
|
||||
@mkdir -p $(OUTDIR)
|
||||
$(eval OUTPUT_OPTIONS = | go-junit-report -set-exit-code > $(OUTDIR)/junit-report.xml)
|
||||
endif
|
||||
$(GOTEST) -v $(GO_OPT) ./... $(OUTPUT_OPTIONS)
|
||||
@$(ECHO_CMD) "Test\t\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:test
|
||||
|
||||
coverage: ## Run the tests of the project and export the coverage report.
|
||||
@mkdir -p out
|
||||
$(GOTEST) -cover -covermode=count -coverprofile=$(OUTDIR)/profile.cov ./...
|
||||
$(GOCMD) tool cover -func $(OUTDIR)/profile.cov
|
||||
ifeq ($(EXPORT_RESULT), true)
|
||||
ifeq ($(COVERAGE_FORMAT), html)
|
||||
gocov convert $(OUTDIR)/profile.cov | gocov-html > $(OUTDIR)/coverage.html
|
||||
else
|
||||
gocov convert $(OUTDIR)/profile.cov | gocov-xml > $(OUTDIR)/coverage.xml
|
||||
endif
|
||||
endif
|
||||
@$(ECHO_CMD) "Coverage\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:coverage
|
||||
|
||||
## Lint
|
||||
|
||||
lint: ## Run all available linters.
|
||||
go vet ./...
|
||||
errcheck ./...
|
||||
staticcheck ./...
|
||||
usestdlibvars ./...
|
||||
shadow ./...
|
||||
@$(ECHO_CMD) "Lint\t\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:lint
|
||||
|
||||
golangci-lint: ## Run golangci-lint linter
|
||||
@golangci-lint run
|
||||
@$(ECHO_CMD) "GolangCI Lint\t${GREEN}[OK]${RESET}"
|
||||
.PHONY:golangci-lint
|
||||
|
||||
## Help
|
||||
|
||||
help: ## Show this help.
|
||||
@$(ECHO_CMD) ''
|
||||
@$(ECHO_CMD) 'Usage:'
|
||||
@$(ECHO_CMD) ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
|
||||
@$(ECHO_CMD) ''
|
||||
@$(ECHO_CMD) 'Targets:'
|
||||
@awk 'BEGIN {FS = ":.*?## "} { \
|
||||
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
|
||||
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
|
||||
}' $(MAKEFILE_LIST)
|
||||
.PHONY:help
|
20
scripts/changes.awk
Normal file
20
scripts/changes.awk
Normal file
@ -0,0 +1,20 @@
|
||||
# Get changes of given version number.
|
||||
{
|
||||
while (index($0, "## [" version "]") <= 0) {
|
||||
if (getline <= 0) {
|
||||
exit
|
||||
}
|
||||
}
|
||||
if (getline <= 0 ) {
|
||||
exit
|
||||
}
|
||||
if (getline <= 0 ) {
|
||||
exit
|
||||
}
|
||||
while (index($0, "## [") <= 0) {
|
||||
print $0
|
||||
if (getline <= 0) {
|
||||
exit
|
||||
}
|
||||
}
|
||||
}
|
22
scripts/version.sh
Executable file
22
scripts/version.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
if [ -z ${TAG_NAME+x} ]; then
|
||||
if [ -z ${BRANCH_NAME+x} ]; then
|
||||
BRANCH_NAME=$(echo $(git branch --show-current) || \
|
||||
echo $(git name-rev --name-only HEAD))
|
||||
fi
|
||||
GIT_VERSION=$(echo ${BRANCH_NAME} | grep -q 'release/' \
|
||||
&& echo ${BRANCH_NAME} | sed -e 's|release/|v|' -e 's/$/-RC/' || \
|
||||
echo $(git describe --always --tags --dirty 2>/dev/null) || echo v0)
|
||||
else
|
||||
GIT_VERSION=${TAG_NAME}
|
||||
fi
|
||||
|
||||
if [ -z ${VERSION+x} ]; then
|
||||
VERSION=$(echo ${GIT_VERSION} | sed -e 's|^origin/||')
|
||||
fi
|
||||
|
||||
if [ -z $1 ]; then
|
||||
echo "${VERSION}"
|
||||
else
|
||||
echo ${VERSION} | sed -e 's/^v//'
|
||||
fi
|
@ -5,4 +5,3 @@ dbPassword: test-db-password
|
||||
log:
|
||||
path: /var/log/db
|
||||
level: error
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package utils
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -97,7 +97,7 @@ func SetValueWithSlice(v reflect.Value, slice string, separator string) error {
|
||||
case reflect.Float64:
|
||||
err = SetValueWithFloatX(ele, data[i], 64)
|
||||
default:
|
||||
return fmt.Errorf("Can't support type: %s", kind.String())
|
||||
return fmt.Errorf("unsupported type: %s", kind.String())
|
||||
}
|
||||
|
||||
if err != nil {
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package utils
|
||||
package config
|
||||
|
||||
import (
|
||||
"reflect"
|
Loading…
Reference in New Issue
Block a user