1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
package cmd
import (
"fmt"
"os"
"path/filepath"
"syscall"
)
// CmdExec is `direnv exec DIR <COMMAND> ...`
var CmdExec = &Cmd{
Name: "exec",
Desc: "Executes a command after loading the first .envrc or .env found in DIR",
Args: []string{"DIR", "COMMAND", "[...ARGS]"},
Action: actionWithConfig(cmdExecAction),
}
func cmdExecAction(env Env, args []string, config *Config) (err error) {
var (
newEnv Env
previousEnv Env
rcPath string
command string
)
if len(args) < 2 {
return fmt.Errorf("missing DIR and COMMAND arguments")
}
rcPath = filepath.Clean(args[1])
fi, err := os.Stat(rcPath)
if err != nil {
return
}
if fi.IsDir() {
if len(args) < 3 {
return fmt.Errorf("missing COMMAND argument")
}
command = args[2]
args = args[2:]
} else {
command = rcPath
rcPath = filepath.Dir(rcPath)
args = args[1:]
}
// Restore pristine environment if needed
if previousEnv, err = config.Revert(env); err != nil {
return
}
previousEnv.CleanContext()
// Load the rc
if toLoad := findEnvUp(rcPath, config.LoadDotenv); toLoad != "" {
if newEnv, err = config.EnvFromRC(toLoad, previousEnv); err != nil {
return
}
} else {
newEnv = previousEnv
}
var commandPath string
commandPath, err = lookPath(command, newEnv["PATH"])
if err != nil {
err = fmt.Errorf("command '%s' not found on PATH '%s'", command, newEnv["PATH"])
return
}
// #nosec G204
err = syscall.Exec(commandPath, args, newEnv.ToGoEnv())
return
}
|