From 8881e08ca8c6dde6d861ac7d738562e2e745ddf8 Mon Sep 17 00:00:00 2001 From: aryan <85390033+theredditbandit@users.noreply.github.com> Date: Wed, 22 May 2024 14:51:27 +0530 Subject: [PATCH] `pman ls` and `pman i` both sort output by last edited time. (#42) * bug: get rid of incorrect dynamic versioning implementation * feat: pman ls and pman i both now show results sorted by lastedited time * fix ci suggestions --- cmd/root.go | 6 ++---- pkg/ui/interactiveTable.go | 33 +++++++++++++++++++++++++-------- pkg/ui/statusTable.go | 37 +++++++++++++++++++++++++++++-------- pkg/utils/utils.go | 22 ++++++---------------- pkg/utils/utils_test.go | 8 ++++---- 5 files changed, 66 insertions(+), 40 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index b29c4f1..0ad7888 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,8 +4,6 @@ import ( "errors" "github.com/spf13/cobra" - - "github.com/theredditbandit/pman/pkg/utils" ) const ( @@ -13,7 +11,7 @@ const ( ProjectPathBucket = "projectPaths" ProjectAliasBucket = "projectAliases" ConfigBucket = "config" - version = "1.0" + version = "1.0.1" ) var ( @@ -23,7 +21,7 @@ var ( var rootCmd = &cobra.Command{ Use: "pman", Short: "A cli project manager", - Version: utils.GetVersion(), + Version: version, SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { if len(args) == 0 { diff --git a/pkg/ui/interactiveTable.go b/pkg/ui/interactiveTable.go index ae79e3e..3ee7b2a 100644 --- a/pkg/ui/interactiveTable.go +++ b/pkg/ui/interactiveTable.go @@ -3,6 +3,7 @@ package ui import ( "fmt" "sort" + "strconv" "strings" "github.com/charmbracelet/bubbles/table" @@ -60,6 +61,7 @@ func (m tableModel) View() string { func RenderInteractiveTable(data map[string]string, refreshLastEditedTime bool) error { var rows []table.Row var lastEdited string + var timestamp int64 col := []table.Column{ {Title: "Status", Width: 20}, @@ -93,8 +95,8 @@ func RenderInteractiveTable(data map[string]string, refreshLastEditedTime bool) for proj, status := range data { alias, err := db.GetRecord(db.DBName, proj, pkg.ProjectAliasBucket) if refreshLastEditedTime { - lastEdited = utils.GetLastModifiedTime(db.DBName, proj) - rec := map[string]string{proj: lastEdited} + lastEdited, timestamp = utils.GetLastModifiedTime(db.DBName, proj) + rec := map[string]string{proj: fmt.Sprintf("%s-%d", lastEdited, timestamp)} err := db.WriteToDB(db.DBName, rec, pkg.LastUpdatedBucket) if err != nil { return err @@ -104,14 +106,20 @@ func RenderInteractiveTable(data map[string]string, refreshLastEditedTime bool) if err != nil { return err } - lastEdited = lE + out := strings.Split(lE, "-") + lastEdited = out[0] + tstmp, err := strconv.ParseInt(out[1], 10, 64) + if err != nil { + return err + } + timestamp = tstmp } if err == nil { pname := fmt.Sprintf("%s (%s)", proj, alias) - row := []string{utils.TitleCase(status), pname, lastEdited} // Status | projectName (alias) | lastEdited + row := []string{utils.TitleCase(status), pname, lastEdited, fmt.Sprint(timestamp)} // Status | projectName (alias) | lastEdited | timestamp rows = append(rows, row) } else { - row := []string{utils.TitleCase(status), proj, lastEdited} // Status | projectName | lastEdited + row := []string{utils.TitleCase(status), proj, lastEdited, fmt.Sprint(timestamp)} // Status | projectName | lastEdited | timestamp rows = append(rows, row) } } @@ -125,10 +133,19 @@ func RenderInteractiveTable(data map[string]string, refreshLastEditedTime bool) return nil } sort.Slice(rows, func(i, j int) bool { - valI := rows[i][1] - valJ := rows[j][1] - return valI < valJ + valI, _ := strconv.ParseInt(rows[i][3], 10, 64) + valJ, _ := strconv.ParseInt(rows[j][3], 10, 64) + return valI > valJ }) + cleanUp := func(r []table.Row) []table.Row { + result := make([]table.Row, len(r)) + for i, inner := range r { + n := len(inner) + result[i] = inner[:n-1] + } + return result + } + rows = cleanUp(rows) t := table.New( table.WithColumns(col), table.WithRows(rows), diff --git a/pkg/ui/statusTable.go b/pkg/ui/statusTable.go index 2ae266a..0c34ee9 100644 --- a/pkg/ui/statusTable.go +++ b/pkg/ui/statusTable.go @@ -4,6 +4,8 @@ import ( "fmt" "os" "sort" + "strconv" + "strings" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" @@ -17,6 +19,7 @@ import ( func RenderTable(data map[string]string, refreshLastEditedTime bool) error { var tableData [][]string var lastEdited string + var timestamp int64 if refreshLastEditedTime { err := utils.UpdateLastEditedTime() @@ -44,8 +47,8 @@ func RenderTable(data map[string]string, refreshLastEditedTime bool) error { for p, status := range data { alias, err := db.GetRecord(db.DBName, p, pkg.ProjectAliasBucket) if refreshLastEditedTime { - lastEdited = utils.GetLastModifiedTime(db.DBName, p) - rec := map[string]string{p: lastEdited} + lastEdited, timestamp = utils.GetLastModifiedTime(db.DBName, p) + rec := map[string]string{p: fmt.Sprintf("%s-%d", lastEdited, timestamp)} err := db.WriteToDB(db.DBName, rec, pkg.LastUpdatedBucket) if err != nil { return err @@ -55,14 +58,20 @@ func RenderTable(data map[string]string, refreshLastEditedTime bool) error { if err != nil { return err } - lastEdited = lE + out := strings.Split(lE, "-") + lastEdited = out[0] + tstmp, err := strconv.ParseInt(out[1], 10, 64) + if err != nil { + return err + } + timestamp = tstmp } if err == nil { pname := fmt.Sprintf("%s (%s) nil error", p, alias) - row := []string{utils.TitleCase(status), pname, lastEdited} // Status | projectName (alias) | lastEdited + row := []string{utils.TitleCase(status), pname, lastEdited, fmt.Sprint(timestamp)} // Status | projectName (alias) | lastEdited | timestamp tableData = append(tableData, row) } else { - row := []string{utils.TitleCase(status), p, lastEdited} // Status | projectName | lastEdited + row := []string{utils.TitleCase(status), p, lastEdited, fmt.Sprint(timestamp)} // Status | projectName | lastEdited | timestamp tableData = append(tableData, row) } } @@ -75,10 +84,22 @@ func RenderTable(data map[string]string, refreshLastEditedTime bool) error { return fmt.Errorf("no database initialized") } sort.Slice(tableData, func(i, j int) bool { - valI := tableData[i][1] - valJ := tableData[j][1] - return valI < valJ + valI, _ := strconv.ParseInt(tableData[i][3], 10, 64) + valJ, _ := strconv.ParseInt(tableData[j][3], 10, 64) + return valI > valJ }) + + cleanUp := func(tbl [][]string) [][]string { // cleanUp func removes the unix timestamp col from the tabledata + result := make([][]string, len(tbl)) + for i, inner := range tbl { + n := len(inner) + result[i] = inner[:n-1] + } + return result + } + + tableData = cleanUp(tableData) + re := lipgloss.NewRenderer(os.Stdout) baseStyle := re.NewStyle().Padding(0, 1) headerStyle := baseStyle.Copy().Foreground(lipgloss.Color("252")).Bold(true) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 8a13913..19a3899 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -5,10 +5,8 @@ import ( "fmt" "log" "os" - "os/exec" "path/filepath" "strconv" - "strings" "time" "github.com/charmbracelet/glamour" @@ -43,12 +41,13 @@ func FilterByStatuses(data map[string]string, status []string) map[string]string return filteredData } -func GetLastModifiedTime(dbname, pname string) string { +// GetLastModifiedTime returns the last modified time and the unix timestamp as well that is used to sort the projects later +func GetLastModifiedTime(dbname, pname string) (string, int64) { var lastModTime time.Time today := time.Now() pPath, err := db.GetRecord(dbname, pname, pkg.ProjectPaths) if err != nil { - return "Something went wrong" + return "Something went wrong", 0 } _ = filepath.Walk(pPath, func(_ string, info os.FileInfo, err error) error { if err != nil { @@ -62,11 +61,11 @@ func GetLastModifiedTime(dbname, pname string) string { switch fmt.Sprint(lastModTime.Date()) { case fmt.Sprint(today.Date()): - return fmt.Sprintf("Today %s", lastModTime.Format("15:04")) + return fmt.Sprintf("Today %s", lastModTime.Format("15:04")), int64(lastModTime.Unix()) case fmt.Sprint(today.AddDate(0, 0, -1).Date()): - return fmt.Sprintf("Yesterday %s", lastModTime.Format("17:00")) + return fmt.Sprintf("Yesterday %s", lastModTime.Format("17:00")), int64(lastModTime.Unix()) } - return fmt.Sprint(lastModTime.Format("02 Jan 06 15:04")) + return fmt.Sprint(lastModTime.Format("02 Jan 06 15:04")), int64(lastModTime.Unix()) } // BeautifyMD: returns styled markdown @@ -129,12 +128,3 @@ func DayPassed(t string) bool { recTime, _ := strconv.ParseInt(t, 10, 64) return now-recTime > int64(oneDay) } - -func GetVersion() string { - cmd := exec.Command("git", "describe", "--tags", "--always") - out, err := cmd.Output() - if err != nil { - return "unknown" - } - return strings.TrimSpace(string(out)) -} diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index d15a81a..d022776 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -223,7 +223,7 @@ func Test_GetLastModifiedTime(t *testing.T) { err = db.WriteToDB(dbname, map[string]string{projectName: projectPath}, pkg.ProjectPaths) require.NoError(t, err) - actual := utils.GetLastModifiedTime(dbname, projectName) + actual, _ := utils.GetLastModifiedTime(dbname, projectName) assert.NotEqual(t, expectedMsg, actual) assert.Contains(t, actual, "Today") @@ -248,7 +248,7 @@ func Test_GetLastModifiedTime(t *testing.T) { err = db.WriteToDB(dbname, map[string]string{projectName: projectPath}, pkg.ProjectPaths) require.NoError(t, err) - actual := utils.GetLastModifiedTime(dbname, projectName) + actual, _ := utils.GetLastModifiedTime(dbname, projectName) assert.NotEqual(t, expectedMsg, actual) assert.Contains(t, actual, "Yesterday") @@ -272,7 +272,7 @@ func Test_GetLastModifiedTime(t *testing.T) { err = db.WriteToDB(dbname, map[string]string{projectName: projectPath}, pkg.ProjectPaths) require.NoError(t, err) - actual := utils.GetLastModifiedTime(dbname, projectName) + actual, _ := utils.GetLastModifiedTime(dbname, projectName) assert.NotEqual(t, expectedMsg, actual) assert.NotEmpty(t, actual) @@ -280,7 +280,7 @@ func Test_GetLastModifiedTime(t *testing.T) { t.Run("Test GetLastModifiedTime with invalid project", func(t *testing.T) { projectPath := "./invalid_project" - actual := utils.GetLastModifiedTime(dbname, projectPath) + actual, _ := utils.GetLastModifiedTime(dbname, projectPath) assert.Equal(t, expectedMsg, actual) })