diff --git a/cmd/install.go b/cmd/install.go index 81018e1..5c6b111 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -29,7 +29,7 @@ func newInstallCmd() *installCmd { Short: "Installs the specified project", SilenceUsage: true, SilenceErrors: true, - Args: cobra.ExactArgs(2), + Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { //TODO implement --force(-f) flag for install // to override the binary if exists @@ -42,8 +42,18 @@ func newInstallCmd() *installCmd { //have to calculate it each time. Afterwards, bin users can change this //path by editing bin's config file or maybe introdice the `bin config` command - //TODO validate path is valid - path := args[1] + var path string + if len(args) > 1 { + path = args[1] + } else if len(config.Get().DefaultPath) > 0 { + path = config.Get().DefaultPath + } else { + var err error + path, err = os.Getwd() + if err != nil { + return err + } + } //TODO check if binary already exists in config // and triger the update process if that's the case diff --git a/cmd/root.go b/cmd/root.go index 6abd159..8dbe6ab 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,6 +6,7 @@ import ( "github.com/apex/log" "github.com/apex/log/handlers/cli" "github.com/fatih/color" + "github.com/marcosnils/bin/pkg/config" "github.com/spf13/cobra" ) @@ -64,6 +65,12 @@ func newRootCmd(version string, exit func(int)) *rootCmd { log.SetLevel(log.DebugLevel) log.Debug("debug logs enabled") } + + //check and load config after handlers are configured + err := config.CheckAndLoad() + if err != nil { + log.Fatalf("Error loading config file %v", err) + } }, } diff --git a/main.go b/main.go index c05cc74..eea8041 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,6 @@ import ( "os" "github.com/marcosnils/bin/cmd" - "github.com/marcosnils/bin/pkg/config" ) // nolint: gochecknoglobals @@ -39,10 +38,3 @@ func buildVersion(version, commit, date, builtBy string) string { } return result } - -func init() { - err := config.CheckAndLoad() - if err != nil { - fmt.Printf("Error loading config file %v", err) - } -} diff --git a/pkg/config/config.go b/pkg/config/config.go index 08645af..c5e213f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -7,12 +7,16 @@ import ( "os/user" "path/filepath" "runtime" + "strings" + + "github.com/apex/log" ) var cfg config type config struct { - Bins map[string]*Binary `json:"bins"` + DefaultPath string `json:"default_path"` + Bins map[string]*Binary `json:"bins"` } type Binary struct { @@ -34,6 +38,10 @@ func CheckAndLoad() error { err = json.NewDecoder(f).Decode(&cfg) + if len(cfg.DefaultPath) == 0 { + cfg.DefaultPath = getDefaultPath() + } + log.Debugf("Download path set to %s", cfg.DefaultPath) // ignore if file is empty if err != nil && err != io.EOF { return err @@ -45,6 +53,28 @@ func CheckAndLoad() error { } +//getDefaultPath reads the user's PATH variable +//and returns the first directory that's writable by the current +//user in the system +func getDefaultPath() string { + penv := os.Getenv("PATH") + log.Debugf("User PATH is [%s]", penv) + for _, p := range strings.Split(penv, ":") { + log.Debugf("Checking path %s", p) + + fi, _ := os.Stat(p) + // If it's a dir and has the write bit set + if fi.IsDir() && !(fi.Mode().Perm()&(1<<(uint(7))) == 0) { + log.Debugf("%s seems to be a dir and writable, using it.", p) + return p + } + + } + + return "" + +} + func Get() *config { return &cfg }