Skip to content

Commit 3eb7e14

Browse files
committed
Import repo
Signed-off-by: Kyle McCullough <[email protected]>
0 parents  commit 3eb7e14

19 files changed

+1254
-0
lines changed

.github/workflows/check.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
on: pull_request
2+
name: Check Commit
3+
env:
4+
GOPRIVATE: github.com/OpsHelmInc/*
5+
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
6+
jobs:
7+
check_commit:
8+
name: Check Commit
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v3
12+
- name: golangci-lint
13+
uses: golangci/golangci-lint-action@v3
14+
with:
15+
version: 'latest'
16+
args: --timeout=5m

.github/workflows/ci.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: CI
2+
3+
on: [push]
4+
5+
jobs:
6+
test:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
fail-fast: false
10+
matrix:
11+
go: [ '1.21', '1.20' ]
12+
os: [ ubuntu-latest, macOS-latest, windows-latest ]
13+
name: ${{ matrix.os }} Go ${{ matrix.go }} Tests
14+
steps:
15+
- uses: actions/checkout@v2
16+
- name: Setup go
17+
uses: actions/setup-go@v2
18+
with:
19+
go-version: ${{ matrix.go }}
20+
- run: go test

.github/workflows/release.yml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
on:
2+
push:
3+
tags:
4+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
5+
6+
name: Upload Release Assets
7+
8+
jobs:
9+
build:
10+
name: Upload Release Assets
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
- name: Generate build files
16+
uses: thatisuday/go-cross-build@v1
17+
with:
18+
platforms: 'linux/amd64, linux/ppc64le, darwin/amd64, windows/amd64'
19+
package: 'cmd/godotenv'
20+
name: 'godotenv'
21+
compress: 'true'
22+
dest: 'dist'
23+
- name: Publish Binaries
24+
uses: svenstaro/upload-release-action@v2
25+
with:
26+
repo_token: ${{ secrets.GITHUB_TOKEN }}
27+
release_name: Release ${{ github.ref }}
28+
tag: ${{ github.ref }}
29+
file: dist/*
30+
file_glob: true
31+
overwrite: true
32+

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

.golangci.yaml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
linters:
2+
disable-all: false
3+
# https://golangci-lint.run/usage/linters/#enabled-by-default
4+
enable:
5+
- gofmt
6+
- bodyclose
7+
- errname
8+
- errorlint
9+
- exportloopref
10+
- goimports
11+
- goprintffuncname
12+
- gosec
13+
- misspell
14+
- nilerr
15+
- nilnil
16+
- predeclared
17+
- stylecheck
18+
- thelper
19+
- tparallel
20+
- unparam
21+
- whitespace
22+
- gochecknoglobals
23+
- staticcheck
24+
- govet
25+
- forcetypeassert
26+
- goconst
27+
- exhaustive
28+
linters-settings:
29+
gofmt:
30+
rewrite-rules:
31+
- pattern: 'interface{}'
32+
replacement: 'any'
33+
goimports:
34+
local-prefixes: github.com/OpsHelmInc

LICENCE

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Copyright (c) 2013 John Barton
2+
3+
MIT License
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
"Software"), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23+

README.md

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# GoDotEnv ![CI](https://github.com/OpsHelmInc/godotenv/workflows/CI/badge.svg)
2+
3+
A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file)
4+
5+
From the original Library:
6+
7+
> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.
8+
>
9+
> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped.
10+
11+
It can be used as a library (for loading in env for your own daemons etc) or as a bin command.
12+
13+
There is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows.
14+
15+
## Installation
16+
17+
As a library
18+
19+
```shell
20+
go get github.com/OpsHelmInc/godotenv
21+
```
22+
23+
or if you want to use it as a bin command
24+
```shell
25+
go get github.com/OpsHelmInc/godotenv/cmd/godotenv
26+
```
27+
28+
## Usage
29+
30+
Add your application configuration to your `.env` file in the root of your project:
31+
32+
```shell
33+
S3_BUCKET=YOURS3BUCKET
34+
SECRET_KEY=YOURSECRETKEYGOESHERE
35+
```
36+
37+
Then in your Go app you can do something like
38+
39+
```go
40+
package main
41+
42+
import (
43+
"github.com/OpsHelmInc/godotenv"
44+
"log"
45+
"os"
46+
)
47+
48+
func main() {
49+
err := godotenv.Load()
50+
if err != nil {
51+
log.Fatal("Error loading .env file")
52+
}
53+
54+
s3Bucket := os.Getenv("S3_BUCKET")
55+
secretKey := os.Getenv("SECRET_KEY")
56+
57+
// now do something with s3 or whatever
58+
}
59+
```
60+
61+
If you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import
62+
63+
```go
64+
import _ "github.com/OpsHelmInc/godotenv/autoload"
65+
```
66+
67+
While `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit
68+
69+
```go
70+
_ = godotenv.Load("somerandomfile")
71+
_ = godotenv.Load("filenumberone.env", "filenumbertwo.env")
72+
```
73+
74+
If you want to be really fancy with your env file you can do comments and exports (below is a valid env file)
75+
76+
```shell
77+
# I am a comment and that is OK
78+
SOME_VAR=someval
79+
FOO=BAR # comments at line end are OK too
80+
export BAR=BAZ
81+
```
82+
83+
Or finally you can do YAML(ish) style
84+
85+
```yaml
86+
FOO: bar
87+
BAR: baz
88+
```
89+
90+
as a final aside, if you don't want godotenv munging your env you can just get a map back instead
91+
92+
```go
93+
var myEnv map[string]string
94+
myEnv, err := godotenv.Read()
95+
96+
s3Bucket := myEnv["S3_BUCKET"]
97+
```
98+
99+
... or from an `io.Reader` instead of a local file
100+
101+
```go
102+
reader := getRemoteFile()
103+
myEnv, err := godotenv.Parse(reader)
104+
```
105+
106+
... or from a `string` if you so desire
107+
108+
```go
109+
content := getRemoteFileContent()
110+
myEnv, err := godotenv.Unmarshal(content)
111+
```
112+
113+
### Precedence & Conventions
114+
115+
Existing envs take precedence of envs that are loaded later.
116+
117+
The [convention](https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use)
118+
for managing multiple environments (i.e. development, test, production)
119+
is to create an env named `{YOURAPP}_ENV` and load envs in this order:
120+
121+
```go
122+
env := os.Getenv("FOO_ENV")
123+
if "" == env {
124+
env = "development"
125+
}
126+
127+
godotenv.Load(".env." + env + ".local")
128+
if "test" != env {
129+
godotenv.Load(".env.local")
130+
}
131+
godotenv.Load(".env." + env)
132+
godotenv.Load() // The Original .env
133+
```
134+
135+
If you need to, you can also use `godotenv.Overload()` to defy this convention
136+
and overwrite existing envs instead of only supplanting them. Use with caution.
137+
138+
### Command Mode
139+
140+
Assuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH`
141+
142+
```
143+
godotenv -f /some/path/to/.env some_command with some args
144+
```
145+
146+
If you don't specify `-f` it will fall back on the default of loading `.env` in `PWD`
147+
148+
### Writing Env Files
149+
150+
Godotenv can also write a map representing the environment to a correctly-formatted and escaped file
151+
152+
```go
153+
env, err := godotenv.Unmarshal("KEY=value")
154+
err := godotenv.Write(env, "./.env")
155+
```
156+
157+
... or to a string
158+
159+
```go
160+
env, err := godotenv.Unmarshal("KEY=value")
161+
content, err := godotenv.Marshal(env)
162+
```
163+
164+
## Contributing
165+
166+
Contributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases.
167+
168+
*code changes without tests will not be accepted*
169+
170+
1. Fork it
171+
2. Create your feature branch (`git checkout -b my-new-feature`)
172+
3. Commit your changes (`git commit -am 'Added some feature'`)
173+
4. Push to the branch (`git push origin my-new-feature`)
174+
5. Create new Pull Request
175+
176+
## Releases
177+
178+
Releases should follow [Semver](http://semver.org/) though the first couple of releases are `v1` and `v1.1`.
179+
180+
Use [annotated tags for all releases](https://github.com/OpsHelmInc/godotenv/issues/30). Example `git tag -a v1.2.1`
181+
182+
183+
## Who?
184+
185+
The original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](https://johnbarton.co/) based off the tests/fixtures in the original library.

autoload/autoload.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package autoload
2+
3+
/*
4+
You can just read the .env file on import just by doing
5+
6+
import _ "github.com/OpsHelmInc/godotenv/autoload"
7+
8+
And bob's your mother's brother
9+
*/
10+
11+
import (
12+
"log"
13+
14+
"github.com/OpsHelmInc/godotenv"
15+
)
16+
17+
func init() {
18+
if err := godotenv.Load(); err != nil {
19+
log.Printf("error loading environment file: %v", err)
20+
}
21+
}

cmd/godotenv/cmd.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"log"
7+
"strings"
8+
9+
"github.com/OpsHelmInc/godotenv"
10+
)
11+
12+
func main() {
13+
var showHelp bool
14+
flag.BoolVar(&showHelp, "h", false, "show help")
15+
var rawEnvFilenames string
16+
flag.StringVar(&rawEnvFilenames, "f", "", "comma separated paths to .env files")
17+
18+
flag.Parse()
19+
20+
usage := `
21+
Run a process with an env setup from a .env file
22+
23+
godotenv [-f ENV_FILE_PATHS] COMMAND_ARGS
24+
25+
ENV_FILE_PATHS: comma separated paths to .env files
26+
COMMAND_ARGS: command and args you want to run
27+
28+
example
29+
godotenv -f /path/to/something/.env,/another/path/.env fortune
30+
`
31+
// if no args or -h flag
32+
// print usage and return
33+
args := flag.Args()
34+
if showHelp || len(args) == 0 {
35+
fmt.Println(usage)
36+
return
37+
}
38+
39+
// load env
40+
var envFilenames []string
41+
if rawEnvFilenames != "" {
42+
envFilenames = strings.Split(rawEnvFilenames, ",")
43+
}
44+
45+
// take rest of args and "exec" them
46+
cmd := args[0]
47+
cmdArgs := args[1:]
48+
49+
err := godotenv.Exec(envFilenames, cmd, cmdArgs)
50+
if err != nil {
51+
log.Fatal(err)
52+
}
53+
}

fixtures/equals.env

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export OPTION_A='postgres://localhost:5432/database?sslmode=disable'
2+

0 commit comments

Comments
 (0)