Skip to content

Commit

Permalink
feat: switched to cobra for the cli parsing, added saving to a dotenv (
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff-roche authored Jul 28, 2022
1 parent ec2aa75 commit ede245b
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 54 deletions.
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,24 @@ The most common use case is for use with scripts that need context via environme

### Via direct command
```bash
$ biome -b my-biome ${COMMAND}
$ biome run -b my-biome ${COMMAND}
```

- `-b` is a required parameter that specifies the name of the biome you want to use
- In this case, the name of the biome is `my-biome`
- `${COMMAND}` specifies the command you want to run (ex: `env`, `ls -al`, ``, etc.)

> **NOTE** if you want to add command line flags to the command being run, you need to preface it with `--`
*Example*: `biome run -b my-biome -- ls -al`

### Via bash alias
A way that makes Biome a little more convenient is to alias your profiles via bash aliases and use them that way.

This configuration:
```bash
# ~/.bashrc
alias onstaging='biome -b staging-biome'
alias onprod='biome -b production-biome'
alias onstaging='biome run -b staging-biome'
alias onprod='biome run -b production-biome'
```

Allows the following command to be run on the command line:
Expand All @@ -86,10 +89,20 @@ Allows the following command to be run on the command line:
$ onstaging ./bin/ci/deploy-service.sh
```

### Exporting to a dotenv file
You can export the loaded environment variables to a dotenv file with the following command:
```bash
$ biome save -b my-biome -f my.env
```

> **NOTE**: If no input file is specified with `-f`, `./.env` will be used as the file path

> **NOTE**: AWS environment variables are not currently exported

## Future Plans
- Export loaded variables to a dotenv file
- Have goreleaser create a docker image and publish to ghcr
- Potentially switching to [cobra](https://github.com/spf13/cobra) for the cli
- :white_check_mark: Export loaded variables to a dotenv file
- :white_check_mark: Switch to [cobra](https://github.com/spf13/cobra) for the cli
- :white_check_mark: Allow CLI input to be a secret (for passwords)
- :white_check_mark: Allow inhereting from other biomes in the same file
- :white_check_mark: Allow setting an environment variable from stdin
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.16.6
github.com/joho/godotenv v1.4.0
github.com/meltwater/dragoman v1.2.2
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.7.1
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -25,8 +26,10 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.11.7 // indirect
github.com/aws/smithy-go v1.11.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kr/pretty v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.2.0 // indirect
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.6/go.mod h1:rP1rEOKAGZoXp4iGDxSXF
github.com/aws/smithy-go v1.10.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
Expand All @@ -48,6 +51,11 @@ github.com/meltwater/dragoman v1.2.2 h1:ZdpdB2vkm9grPjqvp9/6eZEmGubCQtVPuMUi4NDg
github.com/meltwater/dragoman v1.2.2/go.mod h1:waYPsylnXTj4F7xblDEeDEKqxNPZjkqcLYd/6DaUoOM=
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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
Expand All @@ -68,6 +76,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23 changes: 4 additions & 19 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
package main

import (
"flag"
"fmt"
"log"

"github.com/jeff-roche/biome/src/lib/cmdr"
"github.com/jeff-roche/biome/src/cmd"
"github.com/jeff-roche/biome/src/services"
)

var Version string

func main() {
var versionFlag bool
/*var versionFlag bool
flag.BoolVar(&versionFlag, "version", false, "Display the current version of this utility")
flag.BoolVar(&versionFlag, "v", false, "Display the current version of this utility")
Expand All @@ -36,21 +32,10 @@ func main() {
if len(cmds) < 1 {
log.Fatalln("No command provided")
}
}*/

// Setup the biome
biomeSvc := services.NewBiomeConfigurationService()

if err := biomeSvc.LoadBiomeFromDefaults(*biomeName); err != nil {
log.Fatalln(err)
}

if err := biomeSvc.ActivateBiome(); err != nil {
log.Fatalln(err)
}

// Execute order 66
if err := cmdr.Run(cmds[0], cmds[1:]...); err != nil {
log.Fatal(err)
}
cmd.Execute(biomeSvc)
}
46 changes: 46 additions & 0 deletions src/cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cmd

import (
"os"

"github.com/jeff-roche/biome/src/services"
"github.com/spf13/cobra"
)

var biomeService *services.BiomeConfigurationService

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "biome",
Short: "An environment configuration tool",
Long: `An environment variable configuration tool with capabilities such as:
- CLI input
- Configuration commands
- AWS environment configuration
- AWS Secrets Manager support
- Environment variable decryption`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(biomeSvc *services.BiomeConfigurationService) {
biomeService = biomeSvc

err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

// Cobra also supports local flags, which will only run
// when this action is called directly.
//rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
39 changes: 39 additions & 0 deletions src/cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cmd

import (
"log"

"github.com/jeff-roche/biome/src/lib/cmdr"
"github.com/spf13/cobra"
)

// runCmd represents the run command
var runCmd = &cobra.Command{
Use: "run -b <biome-name> [flags] [...cmd]",
Short: "Run any cli command in the provided biome",
Long: "Run any cli command in the provided biome",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
biomeName, _ := cmd.Flags().GetString("biome")

if err := biomeService.LoadBiomeFromDefaults(biomeName); err != nil {
log.Fatalln(err)
}

if err := biomeService.ActivateBiome(); err != nil {
log.Fatalln(err)
}

// Execute order 66
if err := cmdr.Run(args[0], args[1:]...); err != nil {
log.Fatal(err)
}
},
}

func init() {
rootCmd.AddCommand(runCmd)

runCmd.Flags().StringP("biome", "b", "", "the name of the biome to configure")
runCmd.MarkFlagRequired("biome")
}
43 changes: 43 additions & 0 deletions src/cmd/save.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cmd

import (
"fmt"
"log"

"github.com/spf13/cobra"
)

// saveCmd represents the save command
var saveCmd = &cobra.Command{
Use: "save",
Short: "Save the loaded environment variables to a dotenv (.env) file",
Long: `Save the loaded environment variables to a dotenv (.env) file
The default file is '.env' in the current directory`,
Run: func(cmd *cobra.Command, args []string) {
biomeName, _ := cmd.Flags().GetString("biome")
fileName, _ := cmd.Flags().GetString("file")
fmt.Println("LLAMA")
fmt.Println(biomeName)

if err := biomeService.LoadBiomeFromDefaults(biomeName); err != nil {
log.Fatalln(err)
}

if err := biomeService.ActivateBiome(); err != nil {
log.Fatalln(err)
}

// Execute order 66
if err := biomeService.SaveBiomeToFile(fileName); err != nil {
log.Fatal(err)
}
},
}

func init() {
rootCmd.AddCommand(saveCmd)

saveCmd.Flags().StringP("file", "f", ".env", "set the output file name")
saveCmd.Flags().StringP("biome", "b", "", "the name of the biome to configure")
saveCmd.MarkFlagRequired("biome")
}
4 changes: 2 additions & 2 deletions src/lib/setters/basic_setter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ func NewBasicEnvironmentSetter(key string, value interface{}) *BasicEnvironmentS
}
}

func (s BasicEnvironmentSetter) SetEnv() error {
return os.Setenv(s.Key, s.Value)
func (s BasicEnvironmentSetter) SetEnv() (string, error) {
return s.Value, os.Setenv(s.Key, s.Value)
}
3 changes: 2 additions & 1 deletion src/lib/setters/basic_setter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ func TestBasicSetter(t *testing.T) {
t.Run("should set the env", func(t *testing.T) {
testVal := "BAZ"
s := NewBasicEnvironmentSetter(testEnvKey, testVal)
err := s.SetEnv()
val, err := s.SetEnv()

assert.Nil(t, err)
assert.Equal(t, val, testVal)
assert.Equal(t, os.Getenv(testEnvKey), testVal)
})

Expand Down
4 changes: 2 additions & 2 deletions src/lib/setters/cli_setter.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ func NewCLIEnvironmentSetter(key string, rd io.Reader, isSecret bool) (*CLIEnvir
}, nil
}

func (s CLIEnvironmentSetter) SetEnv() error {
return os.Setenv(s.Key, s.Value)
func (s CLIEnvironmentSetter) SetEnv() (string, error) {
return s.Value, os.Setenv(s.Key, s.Value)
}

func getCliInput(rd io.Reader) (string, error) {
Expand Down
8 changes: 4 additions & 4 deletions src/lib/setters/dragoman_setter.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ func NewDragomanEnvironmentSetter(key string, val string) (*DragomanEnvironmentS
}, nil
}

func (s DragomanEnvironmentSetter) SetEnv() error {
func (s DragomanEnvironmentSetter) SetEnv() (string, error) {
dec, err := s.repo.Decrypt(s.Encrypted)
if err != nil {
return err
return "", err
}

if s.EnvKey == "" {
return fmt.Errorf("no environment key specified")
return "", fmt.Errorf("no environment key specified")
}

return os.Setenv(s.EnvKey, dec)
return dec, os.Setenv(s.EnvKey, dec)
}
Loading

0 comments on commit ede245b

Please sign in to comment.