From 43d0cb7ec8f03f2ea58de5fcd0ecd23ccd82e4ea Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:19:07 -0400 Subject: [PATCH 1/3] feat: delete history record --- cmd/ggh.go | 2 +- internal/history/fetch.go | 33 ++---------------- internal/history/save.go | 33 +++++++++++++++++- internal/interactive/display.go | 30 +++++++++++++++++ internal/interactive/select.go | 59 ++++++++++++++++++++++++++++++++- 5 files changed, 123 insertions(+), 34 deletions(-) diff --git a/cmd/ggh.go b/cmd/ggh.go index 31d06d0..5c89c52 100644 --- a/cmd/ggh.go +++ b/cmd/ggh.go @@ -17,7 +17,7 @@ func Main() { action, value := command.Which() switch action { case command.InteractiveHistory: - args = history.Interactive() + args = interactive.History() case command.InteractiveConfig: args = interactive.Config("") case command.InteractiveConfigWithSearch: diff --git a/internal/history/fetch.go b/internal/history/fetch.go index c7f467d..2c011ab 100644 --- a/internal/history/fetch.go +++ b/internal/history/fetch.go @@ -4,12 +4,9 @@ import ( "encoding/json" "fmt" "github.com/byawitz/ggh/internal/config" - "github.com/byawitz/ggh/internal/interactive" - "github.com/byawitz/ggh/internal/ssh" "github.com/byawitz/ggh/internal/theme" "github.com/charmbracelet/bubbles/table" "log" - "os" "time" ) @@ -36,32 +33,6 @@ func Fetch(file []byte) ([]SSHHistory, error) { return historyList, nil } -func Interactive() []string { - list, err := FetchWithDefaultFile() - - if err != nil { - log.Fatal(err) - } - - if len(list) == 0 { - fmt.Println("No history found.") - os.Exit(0) - } - - var rows []table.Row - currentTime := time.Now() - for _, history := range list { - rows = append(rows, table.Row{ - history.Connection.Host, - history.Connection.Port, - history.Connection.User, - history.Connection.Key, - fmt.Sprintf("%s", readableTime(currentTime.Sub(history.Date))), - }) - } - c := interactive.Select(rows, interactive.SelectHistory) - return ssh.GenerateCommandArgs(c) -} func Print() { list, err := FetchWithDefaultFile() @@ -82,14 +53,14 @@ func Print() { history.Connection.Port, history.Connection.User, history.Connection.Key, - fmt.Sprintf("%s", readableTime(currentTime.Sub(history.Date))), + fmt.Sprintf("%s", ReadableTime(currentTime.Sub(history.Date))), }) } fmt.Println(theme.PrintTable(rows, theme.PrintHistory)) } -func readableTime(d time.Duration) string { +func ReadableTime(d time.Duration) string { if d.Seconds() < 60 { return fmt.Sprintf("%d seconds ago", int(d.Seconds())) } diff --git a/internal/history/save.go b/internal/history/save.go index d4b3cfd..9fef49a 100644 --- a/internal/history/save.go +++ b/internal/history/save.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "github.com/byawitz/ggh/internal/config" + "github.com/charmbracelet/bubbles/table" "os" "slices" "strings" @@ -70,6 +71,33 @@ func AddHistory(c config.SSHConfig) { } } +func RemoveByIP(row table.Row) { + list, err := Fetch(getFile()) + + if err != nil { + fmt.Println("error getting ggh file") + return + } + + ip := row[0] + + saving := make([]SSHHistory, 0, len(list)-1) + + for _, item := range list { + if item.Connection.Host == ip { + continue + } + + saving = append(saving, item) + } + + err = saveFile(SSHHistory{}, saving) + if err != nil { + panic("error saving ggh file") + } + +} + func saveFile(n SSHHistory, l []SSHHistory) error { file := getFileLocation() fileContent := stringify(n, l) @@ -89,7 +117,10 @@ func stringify(n SSHHistory, l []SSHHistory) string { } } - history = append(history, n) + if n.Connection.Host != "" { + history = append(history, n) + } + history = append(history, l...) content, err := json.Marshal(history) diff --git a/internal/interactive/display.go b/internal/interactive/display.go index ba3042b..6240bff 100644 --- a/internal/interactive/display.go +++ b/internal/interactive/display.go @@ -3,9 +3,12 @@ package interactive import ( "fmt" "github.com/byawitz/ggh/internal/config" + "github.com/byawitz/ggh/internal/history" "github.com/byawitz/ggh/internal/ssh" "github.com/charmbracelet/bubbles/table" + "log" "os" + "time" ) func Config(value string) []string { @@ -28,3 +31,30 @@ func Config(value string) []string { c := Select(rows, SelectConfig) return ssh.GenerateCommandArgs(c) } + +func History() []string { + list, err := history.FetchWithDefaultFile() + + if err != nil { + log.Fatal(err) + } + + if len(list) == 0 { + fmt.Println("No history found.") + os.Exit(0) + } + + var rows []table.Row + currentTime := time.Now() + for _, historyItem := range list { + rows = append(rows, table.Row{ + historyItem.Connection.Host, + historyItem.Connection.Port, + historyItem.Connection.User, + historyItem.Connection.Key, + fmt.Sprintf("%s", history.ReadableTime(currentTime.Sub(historyItem.Date))), + }) + } + c := Select(rows, SelectHistory) + return ssh.GenerateCommandArgs(c) +} diff --git a/internal/interactive/select.go b/internal/interactive/select.go index efeef19..294955f 100644 --- a/internal/interactive/select.go +++ b/internal/interactive/select.go @@ -3,9 +3,12 @@ package interactive import ( "fmt" "github.com/byawitz/ggh/internal/config" + "github.com/byawitz/ggh/internal/history" "github.com/byawitz/ggh/internal/theme" "math" "os" + "slices" + "strings" "github.com/charmbracelet/bubbles/table" tea "github.com/charmbracelet/bubbletea" @@ -33,6 +36,14 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { + case "d": + history.RemoveByIP(m.table.SelectedRow()) + + rows := slices.Delete(m.table.Rows(), m.table.Cursor(), m.table.Cursor()+1) + m.table.SetRows(rows) + + m.table, cmd = m.table.Update("") // Overrides default `d` behavior + return m, cmd case "q", "ctrl+c", "esc": m.exit = true return m, tea.Quit @@ -67,7 +78,7 @@ func (m model) View() string { if m.choice.Host != "" || m.exit { return "" } - return theme.BaseStyle.Render(m.table.View()) + "\n " + m.table.HelpView() + "\n" + return theme.BaseStyle.Render(m.table.View()) + "\n " + m.HelpView() + "\n" } func Select(rows []table.Row, what Selecting) config.SSHConfig { @@ -123,3 +134,49 @@ func Select(rows []table.Row, what Selecting) config.SSHConfig { return config.SSHConfig{} } +func (m model) HelpView() string { + + km := table.DefaultKeyMap() + + var b strings.Builder + + b.WriteString(generateHelpBlock(km.LineUp.Help().Key, km.LineUp.Help().Desc, true)) + b.WriteString(generateHelpBlock(km.LineDown.Help().Key, km.LineDown.Help().Desc, true)) + + if m.what == SelectHistory { + b.WriteString(generateHelpBlock("d", "delete", true)) + } + + b.WriteString(generateHelpBlock("q/esc", "quit", false)) + + return b.String() +} + +func generateHelpBlock(key, desc string, withSep bool) string { + keyStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{ + Light: "#909090", + Dark: "#626262", + }) + + descStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{ + Light: "#B2B2B2", + Dark: "#4A4A4A", + }) + + sepStyle := lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{ + Light: "#DDDADA", + Dark: "#3C3C3C", + }) + + sep := sepStyle.Inline(true).Render(" • ") + + str := keyStyle.Inline(true).Render(key) + + " " + + descStyle.Inline(true).Render(desc) + + if withSep { + str += sep + } + + return str +} From 21ee33cfc3b1c03bdb00a321e72a5518d9ac148e Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 23 Sep 2024 20:22:28 -0400 Subject: [PATCH 2/3] feat: adding name for knowing connections --- internal/history/fetch.go | 14 ++++++++++++++ internal/history/save.go | 2 +- internal/interactive/display.go | 1 + internal/interactive/select.go | 20 ++++++-------------- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/internal/history/fetch.go b/internal/history/fetch.go index 2c011ab..44269f5 100644 --- a/internal/history/fetch.go +++ b/internal/history/fetch.go @@ -31,6 +31,20 @@ func Fetch(file []byte) ([]SSHHistory, error) { return nil, err } + search, err := config.ParseWithSearch("", config.GetConfigFile()) + + if err != nil { + return historyList, nil + } + + for i, history := range historyList { + for _, sshConfig := range search { + if sshConfig.Host == history.Connection.Host { + historyList[i].Connection.Name = sshConfig.Name + } + } + } + return historyList, nil } diff --git a/internal/history/save.go b/internal/history/save.go index 9fef49a..f31f3bf 100644 --- a/internal/history/save.go +++ b/internal/history/save.go @@ -79,7 +79,7 @@ func RemoveByIP(row table.Row) { return } - ip := row[0] + ip := row[1] saving := make([]SSHHistory, 0, len(list)-1) diff --git a/internal/interactive/display.go b/internal/interactive/display.go index 6240bff..e62899f 100644 --- a/internal/interactive/display.go +++ b/internal/interactive/display.go @@ -48,6 +48,7 @@ func History() []string { currentTime := time.Now() for _, historyItem := range list { rows = append(rows, table.Row{ + historyItem.Connection.Name, historyItem.Connection.Host, historyItem.Connection.Port, historyItem.Connection.User, diff --git a/internal/interactive/select.go b/internal/interactive/select.go index 294955f..2d95b70 100644 --- a/internal/interactive/select.go +++ b/internal/interactive/select.go @@ -57,20 +57,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } func setConfig(row table.Row, what Selecting) config.SSHConfig { - if what == SelectConfig { - return config.SSHConfig{ - Host: row[1], - Port: row[2], - User: row[3], - Key: row[4], - } - } - return config.SSHConfig{ - Host: row[0], - Port: row[1], - User: row[2], - Key: row[3], + Host: row[1], + Port: row[2], + User: row[3], + Key: row[4], } } @@ -95,8 +86,9 @@ func Select(rows []table.Row, what Selecting) config.SSHConfig { if what == SelectHistory { columns = append(columns, []table.Column{ + {Title: "Name", Width: 10}, {Title: "Host", Width: 15}, - {Title: "Port", Width: 10}, + {Title: "Port", Width: 4}, {Title: "User", Width: 10}, {Title: "Key", Width: 10}, {Title: "Last login", Width: 15}, From 57baac207d1a12d98cafb9858e9ad22c3cfef78f Mon Sep 17 00:00:00 2001 From: Binyamin Yawitz <316103+byawitz@users.noreply.github.com> Date: Mon, 23 Sep 2024 20:27:14 -0400 Subject: [PATCH 3/3] refactor: removing config not found error. There's no need to show the error as we can continue the command and let the user see the `ssh` original error. --- internal/history/save.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/history/save.go b/internal/history/save.go index f31f3bf..f0c19b9 100644 --- a/internal/history/save.go +++ b/internal/history/save.go @@ -15,7 +15,6 @@ func AddHistoryFromArgs(args []string) { if len(args) == 1 && !strings.Contains(args[0], "@") { localConfig, err := config.GetConfig(args[0]) if err != nil || localConfig.Name == "" { - fmt.Printf("couldn't fetch %s from config file, error:%v.\n", args[0], err) return }