diff --git a/goutil.go b/goutil.go index 62a3cc7..b436c41 100644 --- a/goutil.go +++ b/goutil.go @@ -3,11 +3,14 @@ package goutil import ( "bufio" "errors" + "flag" "fmt" "io/ioutil" "os" + "os/exec" "path" "path/filepath" + "runtime" "strings" ) @@ -23,6 +26,16 @@ func WriteFile(filename string, data string) error { return ioutil.WriteFile(filename, []byte(data), 0644) } +func AppendToFile(filename string, data string) error { + f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + return errors.New("AppendToFile " + filename + ": " + err.Error()) + } + defer f.Close() + _, err = f.WriteString(data) + return err +} + func ReadFile(filename string) (string, error) { data, err := ioutil.ReadFile(filename) return string(data), err @@ -98,3 +111,104 @@ func StrSlice(sl []string, start int, end int) []string { end = bound(end) return sl[start:end] } + +func OpenInDefaultApp(filename string, wait bool) error { + var cmd *exec.Cmd + switch goos := runtime.GOOS; goos { + case "windows": + cmd = exec.Command(filepath.Join(os.Getenv("SYSTEMROOT"), "System32", "rundll32.exe"), "url.dll,FileProtocolHandler", filename) + case "darwin": + cmd = exec.Command("open", filename) + default: + cmd = exec.Command("xdg-open", filename) + } + if wait { + return cmd.Run() + } else { + return cmd.Start() + } +} + +type CommandFunc func(args []string) error + +type CommandFlagsInit func(s *flag.FlagSet) + +type CommandInitExecFunc func() (CommandFlagsInit, CommandFunc) + +type Command struct { + cmd string + exec CommandFunc + desc string + flags *flag.FlagSet +} + +func NewCommandWithFlags(cmd string, f CommandInitExecFunc, desc string) Command { + flagsInit, exec := f() + var flags *flag.FlagSet + if flagsInit != nil { + flags = flag.NewFlagSet(cmd, flag.ExitOnError) + flagsInit(flags) + } + c := Command{cmd, exec, desc, flags} + return c +} + +func NewCommand(cmd string, f CommandFunc, desc string) Command { + return NewCommandWithFlags(cmd, func() (CommandFlagsInit, CommandFunc) { return nil, f }, desc) +} + +type commandCollection map[string]Command + +func UsageAndExit(cmds commandCollection) { + fmt.Println(os.Args[0]) + fmt.Println("Possible commands:") + for _, cmd := range cmds { + fmt.Println(" " + cmd.cmd) + fmt.Println(" \t" + cmd.desc) + } + fmt.Println() + fmt.Println("for detailed informationen type use 'help COMMAND'") + os.Exit(-1) +} + +func Execute(possibleCommands []Command) error { + commands := commandCollection{} + for _, c := range possibleCommands { + commands[c.cmd] = c + } + arglen := len(os.Args) + if arglen <= 1 { + UsageAndExit(commands) + } + cmdStr := os.Args[1] + if cmdStr == "help" { + if arglen == 2 { + UsageAndExit(commands) + } else { + cmd, ok := commands[os.Args[2]] + if !ok { + UsageAndExit(commands) + } else { + fmt.Println("Description of " + cmd.cmd + ":") + fmt.Println(" " + cmd.desc) + if cmd.flags != nil { + fmt.Println("Possible flags:") + cmd.flags.PrintDefaults() + } else { + fmt.Println("No flags") + } + return nil + } + } + } + cmd, ok := commands[cmdStr] + if !ok { + UsageAndExit(commands) + } + if cmd.flags != nil { + cmd.flags.Parse(os.Args[2:]) + return cmd.exec(cmd.flags.Args()) + } else { + return cmd.exec(os.Args[2:]) + } +}