package main import ( "github.com/abiosoft/ishell/v2" "github.com/adrg/xdg" jira "github.com/andygrunwald/go-jira/v2/cloud" prompt "github.com/elk-language/go-prompt" pstrings "github.com/elk-language/go-prompt/strings" "github.com/pkg/errors" "github.com/spf13/viper" "log" "os" "strings" ) var configPath string var shell *ishell.Shell var jiraClient *jira.Client var jiraUser *jira.User var promptRunner *prompt.Prompt var prefix = "> " func loadConfig() { err := viper.ReadInConfig() if err != nil { log.Fatal(err) } } func SaveConfig() { err := viper.WriteConfig() if err != nil { log.Fatal(err) } } func UpdatePrompt() { if HasIssue() { prefix = "issue " + GetIssueKey() } else if HasSprint() { prefix = "sprint " + viper.GetString("sprint.name") } else if HasBoard() { prefix = "board " + viper.GetString("board.name") } else if HasProject() { prefix = "project " + viper.GetString("project.key") } else { prefix = "(no project)" } prefix += "> " } func executor(in string) { command, args := GetCommand(in) if command == nil { println("Invalid command", in) return } command.Action(args) } func completer(d prompt.Document) ([]prompt.Suggest, pstrings.RuneNumber, pstrings.RuneNumber) { endIndex := d.CurrentRuneIndex() w := d.GetWordBeforeCursor() startIndex := endIndex - pstrings.RuneCount([]byte(w)) s := GetSuggestionsFor(d.TextBeforeCursor()) return prompt.FilterHasPrefix(s, w, true), startIndex, endIndex } func main() { // Open config file configPath, err := xdg.ConfigFile("jirashell/config.toml") if err != nil { log.Fatal(err) } viper.SetConfigFile(configPath) _, err = os.Stat(configPath) if err != nil && !errors.Is(err, os.ErrNotExist) { log.Fatal(err) } else if err == nil { loadConfig() } if !ensureLoggedIn() { os.Exit(0) } if len(os.Args) > 1 { executor(strings.Join(os.Args[1:], " ")) } else { UpdatePrompt() promptRunner = prompt.New( executor, prompt.WithCompleter(completer), prompt.WithTitle("jirashell"), prompt.WithPrefixCallback(func() string { return prefix }), ) promptRunner.Run() } } func ensureLoggedIn() bool { for { username := viper.GetString("username") host := viper.GetString("host") token := viper.GetString("token") if host != "" && token != "" && username != "" { err := login(host, username, token) if err != nil { println("Could not log in:", err) } else { SaveConfig() return true } } println() println("A host name is required.") host = prompt.Input(prompt.WithPrefix("Host: "), prompt.WithInitialText(host)) if host == "" { return false } viper.Set("host", host) println() println("A username is required.") username = prompt.Input(prompt.WithPrefix("Username: "), prompt.WithInitialText(username)) if username == "" { return false } viper.Set("username", username) println() println("A token is required.") token = prompt.Input(prompt.WithPrefix("Token: "), prompt.WithInitialText(token)) if token == "" { return false } viper.Set("token", token) } } func login(host, username, token string) error { var err error tp := jira.BasicAuthTransport{ Username: username, APIToken: token, } jiraClient, err = jira.NewClient(host, tp.Client()) if err != nil { return err } jiraUser, err = GetUserData() return err }