Skip to content
This repository has been archived by the owner on Oct 12, 2023. It is now read-only.

Commit

Permalink
added connStrings and examples for all
Browse files Browse the repository at this point in the history
  • Loading branch information
tchaudhry91 committed Sep 5, 2019
1 parent b4ee4d0 commit 44ae992
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ run:

linters-settings:
errcheck:
ignore: fmt:.*,github.com/go-kit/kit/log:.*,github.com/boltdb/bolt:.*,github.com/tchaudhry91/spinme/spin:^Slash.*
ignore: fmt:.*,github.com/go-kit/kit/log:.*,github.com/boltdb/bolt:.*,github.com/tchaudhry91/spinme/spin:^Slash.*,go.mongodb.org/mongo-driver/mongo:^Disconnect.*
58 changes: 50 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,60 @@
A simple wrapper around Docker to quickly run "spin" up supporting containers such as databases for development.
SpinMe can be invoked via the CLI binary or used as a library straight from your Go code.

## Library

The primary goal of this library is to eliminate the need to externally spin up testing databases (esp while running tests on a CI system).
You can create live docker containers straight from your go test files, making `go test` independent. This allows you to test against real databases, without having to mock anything.

See examples for Postgres/MySQL/Mongo/Redis in the [GoDoc](https://godoc.org/github.com/tchaudhry91/spinme/spin)

Sample Usage:
```
package main
import (
"context"
"database/sql"
"fmt"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/tchaudhry91/spinme/spin"
)
func main() {
out, err := spin.MySQL(context.Background(), nil)
if err != nil {
fmt.Println(err)
return
}
defer spin.SlashID(context.Background(), out.ID)
// Give mysql a minute to boot-up, sadly there is no "ready" check yet
time.Sleep(1 * time.Minute)
connStr, err := spin.MySQLConnString(out)
if err != nil {
fmt.Println(err)
return
}
db, err := sql.Open("mysql", connStr)
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Println(err)
return
}
}
```

## CLI

Use this for daily use to start/stop/view your containers.

Usage:
### CLI Usage:
```
spinme -h
SpinMe is a wrapper around docker to run common applications.
Expand Down Expand Up @@ -48,13 +97,6 @@ The password wherever needed is set to `password`. Once the container is up, you
e.g `--env PG_PASSWORD=1231`


## Library

This is a very early release, the eventual goal is to be able to use this system with CIs, to allow stuff like `go test` to create containers for databases on the fly and clean them up.

[GoDoc](https://godoc.org/github.com/tchaudhry91/spinme/spin)


## Contributing

Contributions are very welcome. Please see create an issue!
Expand Down
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,26 @@ require (
github.com/docker/docker v0.7.3-0.20190731001754-589f1dad8dad
github.com/docker/go-connections v0.4.0
github.com/docker/go-units v0.4.0 // indirect
github.com/go-redis/redis v6.15.5+incompatible
github.com/go-sql-driver/mysql v1.4.1
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/protobuf v1.3.1 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/gorilla/mux v1.7.3 // indirect
github.com/lib/pq v1.2.0
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/onsi/ginkgo v1.10.1 // indirect
github.com/onsi/gomega v1.7.0 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/pkg/errors v0.8.1
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.3.0 // indirect
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
github.com/xdg/stringprep v1.0.0 // indirect
go.mongodb.org/mongo-driver v1.1.0
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
google.golang.org/grpc v1.22.1 // indirect
Expand Down
29 changes: 29 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-redis/redis v6.15.5+incompatible h1:pLky8I0rgiblWfa8C1EV7fPEUv0aH6vKRaYHc/YRHVk=
github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
Expand All @@ -37,12 +41,16 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
Expand All @@ -59,6 +67,11 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
Expand Down Expand Up @@ -91,16 +104,27 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.mongodb.org/mongo-driver v1.1.0 h1:aeOqSrhl9eDRAap/3T5pCfMBEBxZ0vuXBP+RMtp2KX8=
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA=
Expand All @@ -118,6 +142,11 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
Expand Down
29 changes: 27 additions & 2 deletions spin/databases.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ func Mongo(ctx context.Context, c *SpinConfig) (SpinOut, error) {
return o, err
}

// MongoConnString returns the connection string from the spun mongo container
func MongoConnString(out SpinOut) (connStr string, err error) {
var hostEp string
var ok bool

// Grab the host endpoint mapping for the container
if hostEp, ok = out.Endpoints["27017/tcp"]; !ok {
return "", errors.New("Failed to find proper port binding")
}
connStr = fmt.Sprintf("mongodb://%s:%s@%s", LookupEnv("MONGO_INITDB_ROOT_USERNAME", out.Env), LookupEnv("MONGO_INITDB_ROOT_PASSWORD", out.Env), hostEp)
return connStr, nil
}

// MySQL spins a MySQL container with the given settings. Nil config uses defaults
func MySQL(ctx context.Context, c *SpinConfig) (SpinOut, error) {
if c == nil {
Expand Down Expand Up @@ -72,7 +85,7 @@ func MySQLConnString(out SpinOut) (connStr string, err error) {
if hostEp, ok = out.Endpoints["3306/tcp"]; !ok {
return "", errors.New("Failed to find proper port binding")
}
connStr = fmt.Sprintf("root:%s@tcp(%s)/%s", lookupEnv("MYSQL_ROOT_PASSWORD", out.Env), hostEp, lookupEnv("MYSQL_DATABASE", out.Env))
connStr = fmt.Sprintf("root:%s@tcp(%s)/%s", LookupEnv("MYSQL_ROOT_PASSWORD", out.Env), hostEp, LookupEnv("MYSQL_DATABASE", out.Env))
return connStr, nil
}

Expand Down Expand Up @@ -115,7 +128,7 @@ func PostgresConnString(out SpinOut) (connStr string, err error) {
}
// pq needs an independent port, not the entire endpoint
ep := strings.Split(hostEp, ":")
connStr = fmt.Sprintf("user=postgres password=%s dbname=%s port=%s sslmode=disable", lookupEnv("POSTGRES_PASSWORD", out.Env), lookupEnv("POSTGRES_DB", out.Env), ep[len(ep)-1])
connStr = fmt.Sprintf("user=postgres password=%s dbname=%s port=%s sslmode=disable", LookupEnv("POSTGRES_PASSWORD", out.Env), LookupEnv("POSTGRES_DB", out.Env), ep[len(ep)-1])
return connStr, nil
}

Expand All @@ -140,3 +153,15 @@ func Redis(ctx context.Context, c *SpinConfig) (SpinOut, error) {
o.Service = "redis"
return o, err
}

// RedisConnString returns the address of the redis container
func RedisConnString(out SpinOut) (connString string, err error) {
var hostEp string
var ok bool

// Grab the host endpoint mapping for the container
if hostEp, ok = out.Endpoints["6379/tcp"]; !ok {
return "", errors.New("Failed to find proper port binding")
}
return hostEp, nil
}
66 changes: 66 additions & 0 deletions spin/databases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (

_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"

"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"

"github.com/go-redis/redis"
)

func ExamplePostgres() {
Expand Down Expand Up @@ -69,3 +74,64 @@ func ExampleMySQL() {
fmt.Println("Connected!")
//Output: Connected!
}

func ExampleMongo() {
out, err := spin.Mongo(context.Background(), nil)
if err != nil {
fmt.Println(err)
return
}
defer spin.SlashID(context.Background(), out.ID)
// Give mongo a few seconds to boot-up, sadly there is no "ready" check yet
time.Sleep(10 * time.Second)
connStr, err := spin.MongoConnString(out)
if err != nil {
fmt.Println(err)
return
}
client, err := mongo.NewClient(options.Client().ApplyURI(connStr))
if err != nil {
fmt.Println(err)
return
}
err = client.Connect(context.Background())
if err != nil {
fmt.Println(err)
return
}
defer client.Disconnect(context.Background())
err = client.Ping(context.Background(), nil)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Connected!")
// Output: Connected!
}

func ExampleRedis() {
out, err := spin.Redis(context.Background(), nil)
if err != nil {
fmt.Println(err)
return
}
defer spin.SlashID(context.Background(), out.ID)
// Give redis a few seconds to boot-up, sadly there is no "ready" check yet
time.Sleep(10 * time.Second)
connStr, err := spin.RedisConnString(out)
if err != nil {
fmt.Println(err)
return
}

client := redis.NewClient(&redis.Options{
Addr: connStr,
})
pong, err := client.Ping().Result()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(pong)
// Output: PONG
}
4 changes: 2 additions & 2 deletions spin/spin.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ func buildName(svc string) string {
return fmt.Sprintf("spinme-%s-%d", svc, time.Now().Unix())
}

// lookupEnv returns the value (blank for not found) in the containers environment
func lookupEnv(key string, env []string) string {
// LookupEnv returns the value (blank for not found) in the containers environment
func LookupEnv(key string, env []string) string {
for _, e := range env {
esplit := strings.Split(e, "=")
if len(esplit) < 2 {
Expand Down

0 comments on commit 44ae992

Please sign in to comment.