Skip to content

[env] Add --env and --env-file flags #1353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/servers/apache/devbox.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"packages": {
"apacheHttpd@latest": {
"last_modified": "2023-05-01T16:53:22Z",
"plugin_version": "0.0.2",
"resolved": "github:NixOS/nixpkgs/8670e496ffd093b60e74e7fa53526aa5920d09eb#apacheHttpd",
"version": "2.4.57"
}
}
}
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ require (
gopkg.in/yaml.v3 v3.0.1
)

require github.com/joho/godotenv v1.5.1

require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
Expand Down
48 changes: 48 additions & 0 deletions internal/boxcli/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 Jetpack Technologies Inc and contributors. All rights reserved.
// Use of this source code is governed by the license in the LICENSE file.

package boxcli

import (
"path/filepath"

"github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

// to be composed into xyzCmdFlags structs
type envFlag struct {
env map[string]string
envFile string
}

func (f *envFlag) register(cmd *cobra.Command) {
cmd.PersistentFlags().StringToStringVarP(
&f.env, "env", "e", nil, "environment variables to set in the devbox environment",
)
cmd.PersistentFlags().StringVar(
&f.envFile, "env-file", "", "path to a file containing environment variables to set in the devbox environment",
)
}

func (f *envFlag) Env(path string) (map[string]string, error) {
envs := map[string]string{}
var err error
if f.envFile != "" {
envPath := f.envFile
if !filepath.IsAbs(envPath) {
envPath = filepath.Join(path, envPath)
}
envs, err = godotenv.Read(envPath)
if err != nil {
return nil, errors.WithStack(err)
}
}

for k, v := range f.env {
envs[k] = v
}

return envs, nil
}
7 changes: 7 additions & 0 deletions internal/boxcli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
)

type runCmdFlags struct {
envFlag
config configFlags
pure bool
listScripts bool
Expand All @@ -43,6 +44,7 @@ func runCmd() *cobra.Command {
},
}

flags.envFlag.register(command)
flags.config.register(command)
command.Flags().BoolVar(
&flags.pure, "pure", false, "If this flag is specified, devbox runs the script in an isolated environment inheriting almost no variables from the current environment. A few variables, in particular HOME, USER and DISPLAY, are retained.")
Expand Down Expand Up @@ -90,11 +92,16 @@ func runScriptCmd(cmd *cobra.Command, args []string, flags runCmdFlags) error {
debug.Log("script: %s", script)
debug.Log("script args: %v", scriptArgs)

env, err := flags.Env(path)
if err != nil {
return err
}
// Check the directory exists.
box, err := devbox.Open(&devopt.Opts{
Dir: path,
Writer: cmd.ErrOrStderr(),
Pure: flags.pure,
Env: env,
})
if err != nil {
return redact.Errorf("error reading devbox.json: %w", err)
Expand Down
22 changes: 22 additions & 0 deletions internal/boxcli/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
)

type servicesCmdFlags struct {
envFlag
config configFlags
}

Expand Down Expand Up @@ -92,6 +93,7 @@ func servicesCmd() *cobra.Command {
},
}

flags.envFlag.register(servicesCommand)
flags.config.registerPersistent(servicesCommand)
serviceUpFlags.register(upCommand)
serviceStopFlags.register(stopCommand)
Expand All @@ -116,8 +118,13 @@ func listServices(cmd *cobra.Command, flags servicesCmdFlags) error {
}

func startServices(cmd *cobra.Command, services []string, flags servicesCmdFlags) error {
env, err := flags.Env(flags.config.path)
if err != nil {
return err
}
box, err := devbox.Open(&devopt.Opts{
Dir: flags.config.path,
Env: env,
Writer: cmd.ErrOrStderr(),
})
if err != nil {
Expand All @@ -133,8 +140,13 @@ func stopServices(
servicesFlags servicesCmdFlags,
flags serviceStopFlags,
) error {
env, err := servicesFlags.Env(servicesFlags.config.path)
if err != nil {
return err
}
box, err := devbox.Open(&devopt.Opts{
Dir: servicesFlags.config.path,
Env: env,
Writer: cmd.ErrOrStderr(),
})
if err != nil {
Expand All @@ -151,8 +163,13 @@ func restartServices(
services []string,
flags servicesCmdFlags,
) error {
env, err := flags.Env(flags.config.path)
if err != nil {
return err
}
box, err := devbox.Open(&devopt.Opts{
Dir: flags.config.path,
Env: env,
Writer: cmd.ErrOrStderr(),
})
if err != nil {
Expand All @@ -168,8 +185,13 @@ func startProcessManager(
servicesFlags servicesCmdFlags,
flags serviceUpFlags,
) error {
env, err := servicesFlags.Env(servicesFlags.config.path)
if err != nil {
return err
}
box, err := devbox.Open(&devopt.Opts{
Dir: servicesFlags.config.path,
Env: env,
CustomProcessComposeFile: flags.processComposeFile,
Writer: cmd.ErrOrStderr(),
})
Expand Down
7 changes: 7 additions & 0 deletions internal/boxcli/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
)

type shellCmdFlags struct {
envFlag
config configFlags
printEnv bool
pure bool
Expand All @@ -42,13 +43,19 @@ func shellCmd() *cobra.Command {
&flags.pure, "pure", false, "If this flag is specified, devbox creates an isolated shell inheriting almost no variables from the current environment. A few variables, in particular HOME, USER and DISPLAY, are retained.")

flags.config.register(command)
flags.envFlag.register(command)
return command
}

func runShellCmd(cmd *cobra.Command, flags shellCmdFlags) error {
env, err := flags.Env(flags.config.path)
if err != nil {
return err
}
// Check the directory exists.
box, err := devbox.Open(&devopt.Opts{
Dir: flags.config.path,
Env: env,
Pure: flags.pure,
Writer: cmd.ErrOrStderr(),
})
Expand Down
7 changes: 7 additions & 0 deletions internal/boxcli/shellenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

type shellEnvCmdFlags struct {
envFlag
config configFlags
runInitHook bool
install bool
Expand Down Expand Up @@ -45,17 +46,23 @@ func shellEnvCmd() *cobra.Command {
&flags.pure, "pure", false, "If this flag is specified, devbox creates an isolated environment inheriting almost no variables from the current environment. A few variables, in particular HOME, USER and DISPLAY, are retained.")

flags.config.register(command)
flags.envFlag.register(command)

command.AddCommand(shellEnvOnlyPathWithoutWrappersCmd())

return command
}

func shellEnvFunc(cmd *cobra.Command, flags shellEnvCmdFlags) (string, error) {
env, err := flags.Env(flags.config.path)
if err != nil {
return "", err
}
box, err := devbox.Open(&devopt.Opts{
Dir: flags.config.path,
Writer: cmd.ErrOrStderr(),
Pure: flags.pure,
Env: env,
})
if err != nil {
return "", err
Expand Down
6 changes: 6 additions & 0 deletions internal/impl/devbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const (

type Devbox struct {
cfg *devconfig.Config
env map[string]string
lockfile *lock.File
nix nix.Nixer
projectDir string
Expand Down Expand Up @@ -84,6 +85,7 @@ func Open(opts *devopt.Opts) (*Devbox, error) {

box := &Devbox{
cfg: cfg,
env: opts.Env,
nix: &nix.Nix{},
projectDir: projectDir,
pluginManager: plugin.NewManager(),
Expand Down Expand Up @@ -881,6 +883,10 @@ func (d *Devbox) computeNixEnv(ctx context.Context, usePrintDevEnvCache bool) (m
env["XDG_DATA_DIRS"] = JoinPathLists(env["XDG_DATA_DIRS"], os.Getenv("XDG_DATA_DIRS"))
}

for k, v := range d.env {
env[k] = v
}

return env, d.addHashToEnv(env)
}

Expand Down
1 change: 1 addition & 0 deletions internal/impl/devopt/devboxopts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
type Opts struct {
AllowInsecureAdds bool
Dir string
Env map[string]string
Pure bool
IgnoreWarnings bool
CustomProcessComposeFile string
Expand Down