diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000..c42e65d --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,29 @@ +name: lint +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: +jobs: + golangci: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2.3.0 + with: + # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. + version: v1.32.2 + + # Optional: golangci-lint command line arguments. + # args: ./the-only-dir-to-analyze/... + + # Required: the token is used for fetching a list of releases of golangci-lint. + # The secret `GITHUB_TOKEN` is automatically created by GitHub, + # no need to create it manually. + # https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#about-the-github_token-secret + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..d151fc9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: test +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: +env: + GO111MODULE: "on" +jobs: + test: + strategy: + matrix: + go-version: [ 1.13.x, 1.14.x, 1.15.x ] + runs-on: ubuntu-latest + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v2 + - name: Restore vendor + uses: actions/cache@v1 + with: + path: vendor + key: ${{ runner.os }}-go-vendor-${{ hashFiles('**/go.mod') }} + - name: Populate dependencies + if: matrix.go-version == '1.15.x' # Use latest Go to populate vendor. + run: '(test -d vendor && echo vendor found) || go mod vendor' + - name: Test + run: make test-unit + - name: Upload code coverage + if: matrix.go-version == '1.15.x' + uses: codecov/codecov-action@v1 + with: + file: ./unit.coverprofile + flags: unittests diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e0269f7 --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +GOLANGCI_LINT_VERSION := "v1.32.2" + +# The head of Makefile determines location of dev-go to include standard targets. +GO ?= go +export GO111MODULE = on + +ifneq "$(GOFLAGS)" "" + $(info GOFLAGS: ${GOFLAGS}) +endif + +ifneq "$(wildcard ./vendor )" "" + $(info Using vendor) + modVendor = -mod=vendor + ifeq (,$(findstring -mod,$(GOFLAGS))) + export GOFLAGS := ${GOFLAGS} ${modVendor} + endif + ifneq "$(wildcard ./vendor/github.com/bool64/dev)" "" + DEVGO_PATH := ./vendor/github.com/bool64/dev + endif +endif + +ifeq ($(DEVGO_PATH),) + DEVGO_PATH := $(shell GO111MODULE=on $(GO) list ${modVendor} -f '{{.Dir}}' -m github.com/bool64/dev) + ifeq ($(DEVGO_PATH),) + $(info Module github.com/bool64/dev not found, downloading.) + DEVGO_PATH := $(shell export GO111MODULE=on && $(GO) mod tidy && $(GO) list -f '{{.Dir}}' -m github.com/bool64/dev) + endif +endif + +-include $(DEVGO_PATH)/makefiles/main.mk +-include $(DEVGO_PATH)/makefiles/test-unit.mk +-include $(DEVGO_PATH)/makefiles/lint.mk +-include $(DEVGO_PATH)/makefiles/github-actions.mk + +## Run tests +test: test-unit + + diff --git a/dev_test.go b/dev_test.go new file mode 100644 index 0000000..3433e05 --- /dev/null +++ b/dev_test.go @@ -0,0 +1,3 @@ +package shared_test + +import _ "github.com/bool64/dev" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..3860071 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/bool64/shared + +go 1.11 + +require ( + github.com/bool64/dev v0.1.10 + github.com/stretchr/testify v1.6.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3ffc010 --- /dev/null +++ b/go.sum @@ -0,0 +1,13 @@ +github.com/bool64/dev v0.1.10 h1:4L6eLD+qo1QgWDy+Y7OhJxi/gLwOAuV1rd07noMc3dU= +github.com/bool64/dev v0.1.10/go.mod h1:pn52JC52uSgpazChx9CeXyG+S3sW2V36HHoLNBbscdg= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vars.go b/vars.go new file mode 100644 index 0000000..12da751 --- /dev/null +++ b/vars.go @@ -0,0 +1,70 @@ +// Package shared provides space to share variables. +package shared + +import ( + "strings" + "sync" +) + +// Vars keeps values of named variables. +type Vars struct { + // VarPrefix determines which cell values should be collected as vars and replaced with values in usages. + // Default is '$', e.g. $id1 would be treated as variable. + VarPrefix string + + mu sync.Mutex + vars map[string]interface{} +} + +// Reset removes all variables. +func (v *Vars) Reset() { + v.mu.Lock() + defer v.mu.Unlock() + + v.vars = make(map[string]interface{}) +} + +// IsVar checks if string looks like a variable name. +func (v *Vars) IsVar(s string) bool { + varPrefix := v.VarPrefix + if varPrefix == "" { + varPrefix = "$" + } + + return strings.HasPrefix(s, varPrefix) +} + +// Get returns variable value if is exists. +func (v *Vars) Get(s string) (interface{}, bool) { + v.mu.Lock() + defer v.mu.Unlock() + + val, found := v.vars[s] + + return val, found +} + +// Set sets variable by name. +func (v *Vars) Set(key string, val interface{}) { + v.mu.Lock() + defer v.mu.Unlock() + + if v.vars == nil { + v.vars = make(map[string]interface{}) + } + + v.vars[key] = val +} + +// GetAll returns all variables with values. +func (v *Vars) GetAll() map[string]interface{} { + v.mu.Lock() + defer v.mu.Unlock() + + res := make(map[string]interface{}, len(v.vars)) + for k, val := range v.vars { + res[k] = val + } + + return res +} diff --git a/vars_test.go b/vars_test.go new file mode 100644 index 0000000..41135e6 --- /dev/null +++ b/vars_test.go @@ -0,0 +1,24 @@ +package shared_test + +import ( + "testing" + + "github.com/bool64/shared" + "github.com/stretchr/testify/assert" +) + +func TestVars_GetAll(t *testing.T) { + v := shared.Vars{} + + v.Set("k", "v") + val, found := v.Get("k") + assert.True(t, found) + assert.Equal(t, "v", val) + + assert.Equal(t, map[string]interface{}{"k": "v"}, v.GetAll()) + assert.True(t, v.IsVar("$var")) + assert.False(t, v.IsVar("var")) + + v.Reset() + assert.Equal(t, map[string]interface{}{}, v.GetAll()) +}