Compare commits

..

No commits in common. "main" and "v1.0.1" have entirely different histories.
main ... v1.0.1

4 changed files with 12 additions and 90 deletions

View File

@ -1,69 +0,0 @@
# loadenv
Loads environment files before running a command without polluting your environment
## Source code
You can find the source code here: [git.milar.in](https://git.milar.in/milarin/loadenv)
## Installation
If you have Go installed, you can simply go install the program: `go install git.milar.in/milarin/loadenv@latest`
There are pre-compiled executables for various platforms on the [repository](https://git.milar.in/milarin/loadenv/releases).
## License
Distributed under the MIT License. See [LICENSE.md](https://git.milar.in/milarin/loadenv/src/branch/main/LICENSE.md)
## Usage
`loadenv` loads the environment file provided via `-f` into the environment and runs the command provided after the arguments.
If no file is provided, `.env` is used by default.
If no command is provided, `loadenv` prints all environment variables to stdout.
---
The variables will only be available to the given command. They will be deleted after the command exits.
`loadenv` can be useful when working with programs which heavily use environment variables.
```sh
$ cat .env
# production server configuration
DATABASE_HOST=prod-server.com
DATABASE_USER=milarin
DATABASE_PASS=my-super-secure-password
$ # show the 3 last added env variables
$ loadenv | tail -n 3
DATABASE_HOST=prod-server.com
DATABASE_USER=milarin
DATABASE_PASS=my-super-secure-password
$ cat dev.env
# development server configuration
DATABASE_HOST=dev-server.com
DATABASE_USER=milarin
DATABASE_PASS=my-super-secure-password
$ # load dev.env into environment and run the command env. show last 3 lines
$ loadenv -f dev.env env | tail -n 3
DATABASE_HOST=dev-server.com
DATABASE_USER=milarin
DATABASE_PASS=my-super-secure-password
```
environment variables in that file will be expanded:
```sh
$ env | grep USER # current value of $USER
USER=milarin
$ cat .env
# expand $USER reference
USERNAME=$USER
$ loadenv | tail -n 1
USERNAME=milarin
```

4
go.mod
View File

@ -1,5 +1,3 @@
module git.milar.in/milarin/loadenv module git.tordarus.net/Tordarus/loadenv
go 1.18 go 1.18
require git.milar.in/milarin/buildinfo v1.0.0

2
go.sum
View File

@ -1,2 +0,0 @@
git.milar.in/milarin/buildinfo v1.0.0 h1:tw98GupUYl/0a/3aPGuezhE4wseycOSsbcLp70hy60U=
git.milar.in/milarin/buildinfo v1.0.0/go.mod h1:arI9ZoENOgcZcanv25k9y4dKDUhPp0buJrlVerGruas=

27
main.go
View File

@ -8,8 +8,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"regexp" "regexp"
"git.milar.in/milarin/buildinfo"
) )
var ( var (
@ -17,18 +15,11 @@ var (
EnvVarRegex = regexp.MustCompile(`^(.*?)=(.*?)$`) EnvVarRegex = regexp.MustCompile(`^(.*?)=(.*?)$`)
EnvCommentRegex = regexp.MustCompile(`^[ \t]*#.*?$`) EnvCommentRegex = regexp.MustCompile(`^[ \t]*#.*?$`)
ShowVersion = flag.Bool("v", false, "show version and exit")
) )
func main() { func main() {
flag.Parse() flag.Parse()
if *ShowVersion {
buildinfo.Print(buildinfo.Options{})
return
}
envFile, err := os.Open(*EnvFilePath) envFile, err := os.Open(*EnvFilePath)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "could not open file '%s': %s\n", *EnvFilePath, err.(*os.PathError).Err) fmt.Fprintf(os.Stderr, "could not open file '%s': %s\n", *EnvFilePath, err.(*os.PathError).Err)
@ -36,18 +27,20 @@ func main() {
} }
defer envFile.Close() defer envFile.Close()
parseEnvFile(envFile) envVars := parseEnvFile(envFile)
args := flag.Args() args := flag.Args()
newEnv := append(os.Environ(), envVars...)
if len(args) == 0 { if len(args) == 0 {
for _, envVar := range os.Environ() { for _, envVar := range newEnv {
fmt.Println(envVar) fmt.Println(envVar)
} }
return return
} }
cmd := exec.Command(args[0], args[1:]...) cmd := exec.Command(args[0], args[1:]...)
cmd.Env = os.Environ() cmd.Env = newEnv
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
@ -63,19 +56,21 @@ func main() {
} }
} }
func parseEnvFile(r io.Reader) { func parseEnvFile(r io.Reader) []string {
env := make([]string, 0)
s := bufio.NewScanner(r) s := bufio.NewScanner(r)
l := 0 l := 0
for s.Scan() { for s.Scan() {
l++ l++
matches := EnvVarRegex.FindStringSubmatch(s.Text()) matches := EnvVarRegex.FindStringSubmatch(s.Text())
if len(matches) != 0 { if len(matches) != 0 {
key, value := matches[1], os.ExpandEnv(matches[2]) key, value := matches[1], os.ExpandEnv(matches[2])
os.Setenv(key, value) env = append(env, fmt.Sprintf("%s=%s", key, value))
} else if s.Text() != "" && !EnvCommentRegex.MatchString(s.Text()) { } else if !EnvCommentRegex.MatchString(s.Text()) {
panic(fmt.Sprintf("invalid env syntax on line %d", l)) panic(fmt.Sprintf("invalid env syntax on line %d", l))
} }
} }
return env
} }