1package main 2 3import ( 4 "fmt" 5 "strings" 6 "time" 7) 8 9type actionSimple func(env Env, args []string) error 10 11func (fn actionSimple) Call(env Env, args []string, config *Config) error { 12 return fn(env, args) 13} 14 15type actionWithConfig func(env Env, args []string, config *Config) error 16 17func (fn actionWithConfig) Call(env Env, args []string, config *Config) error { 18 var err error 19 if config == nil { 20 config, err = LoadConfig(env) 21 if err != nil { 22 return err 23 } 24 } 25 26 return fn(env, args, config) 27} 28 29type action interface { 30 Call(env Env, args []string, config *Config) error 31} 32 33// Cmd represents a direnv sub-command 34type Cmd struct { 35 Name string 36 Desc string 37 Args []string 38 Aliases []string 39 Private bool 40 Action action 41} 42 43// CmdList contains the list of all direnv sub-commands 44var CmdList []*Cmd 45 46func init() { 47 CmdList = []*Cmd{ 48 CmdAllow, 49 CmdApplyDump, 50 CmdShowDump, 51 CmdDeny, 52 CmdDotEnv, 53 CmdDump, 54 CmdEdit, 55 CmdExec, 56 CmdExport, 57 CmdFetchURL, 58 CmdHelp, 59 CmdHook, 60 CmdPrune, 61 CmdReload, 62 CmdStatus, 63 CmdStdlib, 64 CmdVersion, 65 CmdWatch, 66 CmdWatchDir, 67 CmdWatchList, 68 CmdCurrent, 69 } 70} 71 72func cmdWithWarnTimeout(fn action) action { 73 return actionWithConfig(func(env Env, args []string, config *Config) (err error) { 74 done := make(chan bool, 1) 75 go func() { 76 select { 77 case <-done: 78 return 79 case <-time.After(config.WarnTimeout): 80 logError("(%v) is taking a while to execute. Use CTRL-C to give up.", args) 81 } 82 }() 83 84 err = fn.Call(env, args, config) 85 done <- true 86 return err 87 }) 88} 89 90// CommandsDispatch is called by the main() function to dispatch to a sub-command 91func CommandsDispatch(env Env, args []string) error { 92 var command *Cmd 93 var commandName string 94 var commandPrefix string 95 var commandArgs []string 96 97 if len(args) < 2 { 98 commandName = "help" 99 commandPrefix = args[0] 100 commandArgs = []string{} 101 } else { 102 commandName = args[1] 103 commandPrefix = strings.Join(args[0:2], " ") 104 commandArgs = append([]string{commandPrefix}, args[2:]...) 105 } 106 107 for _, cmd := range CmdList { 108 if cmd.Name == commandName { 109 command = cmd 110 break 111 } 112 if cmd.Aliases != nil { 113 for _, alias := range cmd.Aliases { 114 if alias == commandName { 115 command = cmd 116 } 117 } 118 } 119 } 120 121 if command == nil { 122 return fmt.Errorf("command \"%s\" not found", commandPrefix) 123 } 124 125 return command.Action.Call(env, commandArgs, nil) 126} 127