From c504cc2ea0dcd086b80816ce7095a49931a9d574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Thu, 9 May 2024 20:50:45 +0200 Subject: [PATCH 01/10] chores: make some polysh in all the project --- cmd/alias.go | 6 ++-- cmd/delete.go | 12 +++---- cmd/ls.go | 2 +- cmd/reset.go | 2 +- cmd/set.go | 4 +-- cmd/status.go | 4 +-- pkg/db/db.go | 78 +++++++++++++++++++++++++++---------------- pkg/indexer.go | 37 ++++++++++++-------- pkg/ui/statusTable.go | 2 +- pkg/ui/tui.go | 2 +- pkg/utils/utils.go | 8 ++--- 11 files changed, 94 insertions(+), 63 deletions(-) diff --git a/cmd/alias.go b/cmd/alias.go index 97396c1..3cbdb4c 100644 --- a/cmd/alias.go +++ b/cmd/alias.go @@ -21,7 +21,7 @@ avlpn or something smaller and use that to query pman`, } pname := args[0] alias := args[1] - _, err := db.GetRecord(pname, StatusBucket) + _, err := db.GetRecord(db.DBName, pname, StatusBucket) if err != nil { fmt.Printf("%s project does not exist in db", pname) return @@ -29,8 +29,8 @@ avlpn or something smaller and use that to query pman`, fmt.Printf("Aliasing %s to %s \n", pname, alias) data := map[string]string{alias: pname} revData := map[string]string{pname: alias} - db.WriteToDB(data, ProjectAliasBucket) - db.WriteToDB(revData, ProjectAliasBucket) + db.WriteToDB(db.DBName, data, ProjectAliasBucket) + db.WriteToDB(db.DBName, revData, ProjectAliasBucket) }, } diff --git a/cmd/delete.go b/cmd/delete.go index 4e7d2d8..496073e 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -19,27 +19,27 @@ var delCmd = &cobra.Command{ return } projName := args[0] - _, err := db.GetRecord(projName, StatusBucket) + _, err := db.GetRecord(db.DBName, projName, StatusBucket) if err != nil { fmt.Printf("%s is not a valid project to be deleted\n", projName) fmt.Println("Note : projects cannot be deleted using their alias") return } - err = db.DeleteFromDb(projName, ProjectPathBucket) + err = db.DeleteFromDb(db.DBName, projName, ProjectPathBucket) if err != nil { log.Fatal(err) } - err = db.DeleteFromDb(projName, StatusBucket) + err = db.DeleteFromDb(db.DBName, projName, StatusBucket) if err != nil { log.Fatal(err) } - alias, err := db.GetRecord(projName, ProjectAliasBucket) + alias, err := db.GetRecord(db.DBName, projName, ProjectAliasBucket) if err == nil { - err = db.DeleteFromDb(alias, ProjectAliasBucket) + err = db.DeleteFromDb(db.DBName, alias, ProjectAliasBucket) if err != nil { log.Fatal(err) } - err = db.DeleteFromDb(projName, ProjectAliasBucket) + err = db.DeleteFromDb(db.DBName, projName, ProjectAliasBucket) if err != nil { log.Fatal(err) } diff --git a/cmd/ls.go b/cmd/ls.go index 3ba27f3..fef82f9 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -19,7 +19,7 @@ var lsCmd = &cobra.Command{ `, Run: func(cmd *cobra.Command, args []string) { filterFlag, _ := cmd.Flags().GetString("f") - data, err := db.GetAllRecords(StatusBucket) + data, err := db.GetAllRecords(db.DBName, StatusBucket) if err != nil { log.Fatal(err) } diff --git a/cmd/reset.go b/cmd/reset.go index 05ba29a..1cfa19d 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -12,7 +12,7 @@ var resetCmd = &cobra.Command{ Use: "reset", Short: "Deletes the current indexed projects, run pman init to reindex the projects", Run: func(cmd *cobra.Command, args []string) { - err := db.DeleteDb() + err := db.DeleteDb(db.DBName) if err != nil { fmt.Println(err) } diff --git a/cmd/set.go b/cmd/set.go index 3fc5b8e..5e885e5 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -30,13 +30,13 @@ var setCmd = &cobra.Command{ var pname string alias := args[0] status := args[1] - project, err := db.GetRecord(alias, ProjectAliasBucket) + project, err := db.GetRecord(db.DBName, alias, ProjectAliasBucket) if err == nil { pname = project } else { pname = alias } - err = db.UpdateRec(pname, status, StatusBucket) + err = db.UpdateRec(db.DBName, pname, status, StatusBucket) if err != nil { fmt.Println("Error updating record : ", err) return diff --git a/cmd/status.go b/cmd/status.go index 62292b0..03c9b36 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -21,12 +21,12 @@ var statusCmd = &cobra.Command{ return } projName := args[0] - actualName, err := db.GetRecord(projName, ProjectAliasBucket) + actualName, err := db.GetRecord(db.DBName, projName, ProjectAliasBucket) if err == nil { // check if user has supplied an alias instead of actual project name alias = projName projName = actualName } - status, err := db.GetRecord(projName, StatusBucket) + status, err := db.GetRecord(db.DBName, projName, StatusBucket) if err != nil { fmt.Printf("%s is not a valid project name : Err -> %s", projName, err) return diff --git a/pkg/db/db.go b/pkg/db/db.go index 578003e..3a317a1 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -1,6 +1,7 @@ package db import ( + "errors" "fmt" "log" "os" @@ -10,24 +11,38 @@ import ( bolt "go.etcd.io/bbolt" ) -const DBName = "projects.db" +const DBName string = "projects.db" +const DBTestName string = "projects_test.db" + +var ( + ErrOpenDB = errors.New("error opening database") + ErrCreateBucket = errors.New("error creating bucket") + ErrWriteToDB = errors.New("error writing to database") + ErrBucketNotFound = errors.New("bucket not found") + ErrProjectNotFound = errors.New("project not found") + ErrDeleteFromDB = errors.New("error deleting from database") + ErrKeyNotFound = errors.New("key not found in db") + ErrListAllRecords = errors.New("error listing all records") + ErrClearDB = errors.New("error clearing database") +) // WriteToDB writes the data to the specified bucket in the database -func WriteToDB(data map[string]string, bucketName string) error { - db, err := bolt.Open(getDBLoc(DBName), 0o600, nil) // create the database if it doesn't exist then open it +func WriteToDB(dbname string, data map[string]string, bucketName string) error { + db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it if err != nil { - log.Fatal(err) + log.Printf("%v : %v", ErrOpenDB, err) + return errors.Join(ErrOpenDB, err) } defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(bucketName)) if err != nil { - return err + return errors.Join(ErrCreateBucket, err) } for k, v := range data { err = bucket.Put([]byte(k), []byte(v)) if err != nil { - return err + return errors.Join(ErrWriteToDB, err) } } return nil @@ -35,20 +50,21 @@ func WriteToDB(data map[string]string, bucketName string) error { return err } -func DeleteFromDb(key string, bucketName string) error { - db, err := bolt.Open(getDBLoc(DBName), 0o600, nil) // create the database if it doesn't exist then open it +func DeleteFromDb(dbname, key, bucketName string) error { + db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it if err != nil { - log.Fatal(err) + log.Printf("%v : %v", ErrOpenDB, err) + return errors.Join(ErrOpenDB, err) } defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { - return fmt.Errorf("bucket %s not found", bucketName) + return ErrBucketNotFound } err := bucket.Delete([]byte(key)) if err != nil { - return err + return errors.Join(ErrDeleteFromDB, err) } return nil }) @@ -69,21 +85,22 @@ func getDBLoc(dbname string) string { } // GetRecord returns the value of the key from the specified bucket, and error if it does not exist -func GetRecord(key string, bucketName string) (string, error) { +func GetRecord(dbname, key, bucketName string) (string, error) { var rec string - db, err := bolt.Open(getDBLoc(DBName), 0o600, nil) + db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) if err != nil { - log.Fatal(err) + log.Printf("%v : %v", ErrOpenDB, err) + return "", errors.Join(ErrOpenDB, err) } defer db.Close() err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { - return fmt.Errorf("Bucket not found") + return ErrBucketNotFound } v := bucket.Get([]byte(key)) if v == nil { - return fmt.Errorf("Key not found in db\n") + return ErrKeyNotFound } rec = string(v) return nil @@ -95,23 +112,25 @@ func GetRecord(key string, bucketName string) (string, error) { } // GetAllRecords returns all the records from the specified bucket as a dictionary -func GetAllRecords(bucketName string) (map[string]string, error) { - db, err := bolt.Open(getDBLoc(DBName), 0o600, nil) +func GetAllRecords(dbname, bucketName string) (map[string]string, error) { + db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) if err != nil { - log.Fatal(err) + log.Printf("%v : %v", ErrOpenDB, err) + return map[string]string{}, errors.Join(ErrOpenDB, err) } defer db.Close() records := make(map[string]string) err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { - return fmt.Errorf("Database not found. \nThis could be because no project dir has been initialized yet.") + fmt.Print("Database not found \nThis could be because no project dir has been initialized yet") + return ErrBucketNotFound } err := bucket.ForEach(func(k, v []byte) error { records[string(k)] = string(v) return nil }) - return err + return errors.Join(ErrListAllRecords, err) }) if err != nil { return nil, err @@ -120,8 +139,8 @@ func GetAllRecords(bucketName string) (map[string]string, error) { } // UpdateRec updates the value of the key in the specified bucket, usually used to update the status of a project -func UpdateRec(key, val, bucketName string) error { - db, err := bolt.Open(getDBLoc(DBName), 0o600, nil) +func UpdateRec(dbname, key, val, bucketName string) error { + db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) if err != nil { log.Fatal(err) } @@ -129,11 +148,11 @@ func UpdateRec(key, val, bucketName string) error { err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { - return fmt.Errorf("Bucket not found") + return ErrBucketNotFound } v := bucket.Get([]byte(key)) if v == nil { - return fmt.Errorf("Project not found") + return ErrProjectNotFound } err := bucket.Put([]byte(key), []byte(val)) return err @@ -141,7 +160,10 @@ func UpdateRec(key, val, bucketName string) error { return err } -func DeleteDb() error { - err := os.Remove(getDBLoc(DBName)) - return err +func DeleteDb(dbname string) error { + err := os.Remove(getDBLoc(dbname)) + if err != nil { + return errors.Join(ErrClearDB, err) + } + return nil } diff --git a/pkg/indexer.go b/pkg/indexer.go index ff677bd..6f2d737 100644 --- a/pkg/indexer.go +++ b/pkg/indexer.go @@ -1,6 +1,7 @@ package pkg import ( + "errors" "fmt" "log" "os" @@ -10,31 +11,38 @@ import ( ) const ( - StatusBucket = "projects" - ProjectPaths = "projectPaths" - ProjectAliasBucket = "projectAliases" + StatusBucket string = "projects" + ProjectPaths string = "projectPaths" + ProjectAliasBucket string = "projectAliases" +) + +var ( + ErrDirname = errors.New("error providing a directory name") + ErrDirInvalid = errors.New("error providing a valid directory name") + ErrIsNotDir = errors.New("error providing a file instead of a directory") + ErrIndexDir = errors.New("error indexing directory") ) // InitDirs indexes a directory for project directories and writes the data to the db -func InitDirs(args []string) { +func InitDirs(args []string) error { // the file which identifies a project directory projIdentifier := "README.md" if len(args) != 1 { fmt.Println("Please provide a directory name") - return + return ErrDirname } dirname := args[0] if stat, err := os.Stat(dirname); os.IsNotExist(err) { fmt.Printf("%s is not a directory \n", dirname) - return + return ErrDirInvalid } else if !stat.IsDir() { fmt.Printf("%s is a file and not a directory \n", dirname) - return + return ErrIsNotDir } projDirs, err := indexDir(dirname, projIdentifier) if err != nil { fmt.Println(err) - return + return ErrIndexDir } fmt.Printf("Indexed %d project directories . . .\n", len(projDirs)) projectStatusMap := make(map[string]string) @@ -43,16 +51,17 @@ func InitDirs(args []string) { projectStatusMap[filepath.Base(k)] = v // filepath.Base(k) : project name projectPathMap[filepath.Base(k)] = k } - err = db.WriteToDB(projectStatusMap, StatusBucket) + err = db.WriteToDB(db.DBName, projectStatusMap, StatusBucket) if err != nil { - log.Fatal(err) - return + log.Print(err) + return err } - err = db.WriteToDB(projectPathMap, ProjectPaths) + err = db.WriteToDB(db.DBName, projectPathMap, ProjectPaths) if err != nil { - log.Fatal(err) - return + log.Print(err) + return err } + return nil } // indexDir indexes a directory for project directories diff --git a/pkg/ui/statusTable.go b/pkg/ui/statusTable.go index 2c979b2..0b2dc83 100644 --- a/pkg/ui/statusTable.go +++ b/pkg/ui/statusTable.go @@ -18,7 +18,7 @@ func RenderTable(data map[string]string) error { var TableData [][]string for p, status := range data { - alias, err := db.GetRecord(p, pkg.ProjectAliasBucket) + alias, err := db.GetRecord(db.DBName, p, pkg.ProjectAliasBucket) lastEdited := utils.GetLastModifiedTime(p) if err == nil { pname := fmt.Sprintf("%s (%s)", p, alias) diff --git a/pkg/ui/tui.go b/pkg/ui/tui.go index d9aaa8c..1e62698 100644 --- a/pkg/ui/tui.go +++ b/pkg/ui/tui.go @@ -82,7 +82,7 @@ func newModel() model { delegateKeys = newDelegateKeyMap() ) - data, err := db.GetAllRecords(pkg.StatusBucket) + data, err := db.GetAllRecords(db.DBName, pkg.StatusBucket) if err != nil { log.Fatal(err) } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 95e1829..0e68d8c 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -33,7 +33,7 @@ func FilterByStatus(data map[string]string, status string) map[string]string { // Deprecated: Use ui.RenderTable instead func PrintData(data map[string]string) { for k, v := range data { - alias, err := db.GetRecord(k, pkg.ProjectAliasBucket) + alias, err := db.GetRecord(db.DBName, k, pkg.ProjectAliasBucket) if err == nil { fmt.Printf("%s : %s (%s) \n", TitleCase(v), k, alias) } else { @@ -47,7 +47,7 @@ func GetLastModifiedTime(pname string) string { var lastModFile string today := time.Now() _ = lastModFile - pPath, err := db.GetRecord(pname, pkg.ProjectPaths) + pPath, err := db.GetRecord(db.DBName, pname, pkg.ProjectPaths) if err != nil { return "Something went wrong" } @@ -89,11 +89,11 @@ func BeautifyMD(data []byte) string { // ReadREADME: returns the byte array of README.md of a project func ReadREADME(projectName string) []byte { - actualName, err := db.GetRecord(projectName, pkg.ProjectAliasBucket) + actualName, err := db.GetRecord(db.DBName, projectName, pkg.ProjectAliasBucket) if err == nil { projectName = actualName } - path, err := db.GetRecord(projectName, pkg.ProjectPaths) + path, err := db.GetRecord(db.DBName, projectName, pkg.ProjectPaths) if err != nil { log.Fatalf("project: %v not a valid project\n", projectName) } From 1782bb3b034ea63cb881cc1f65a53af4763a35d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Fri, 10 May 2024 01:03:44 +0200 Subject: [PATCH 02/10] chores: refactor all the project --- cmd/add.go | 4 ++-- cmd/alias.go | 23 ++++++++++++++++++----- cmd/delete.go | 23 ++++++++++++++--------- cmd/info.go | 20 ++++++++++++++++---- cmd/init.go | 4 ++-- cmd/ls.go | 7 +++---- cmd/reset.go | 4 +++- cmd/set.go | 15 +++++++++++---- cmd/status.go | 11 ++++++++--- pkg/db/db.go | 10 +++++----- pkg/indexer.go | 8 ++++---- pkg/ui/pager/renderer.go | 11 +++++++++-- pkg/utils/utils.go | 20 ++++++++++++++------ 13 files changed, 109 insertions(+), 51 deletions(-) diff --git a/cmd/add.go b/cmd/add.go index e0ced37..d4e3db9 100644 --- a/cmd/add.go +++ b/cmd/add.go @@ -12,8 +12,8 @@ var addCmd = &cobra.Command{ Long: `This command will add a directory to the project database. The directory will not be added if it does not contain a README.md. `, - Run: func(cmd *cobra.Command, args []string) { - pkg.InitDirs(args) + RunE: func(cmd *cobra.Command, args []string) error { + return pkg.InitDirs(args) }, } diff --git a/cmd/alias.go b/cmd/alias.go index 3cbdb4c..1709539 100644 --- a/cmd/alias.go +++ b/cmd/alias.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -8,29 +9,41 @@ import ( "github.com/theredditbandit/pman/pkg/db" ) +var ( + ErrBadUsageAliasCmd error = errors.New("bad usage of alias command") +) + // aliasCmd represents the alias command var aliasCmd = &cobra.Command{ Use: "alias", Short: "Sets the alias for a project, whose name might be too big", Long: `The idea is instead of having to type a-very-long-project-name-every-time you can alias it to avlpn or something smaller and use that to query pman`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 2 { fmt.Println("Usage: pman alias ") - return + return ErrBadUsageAliasCmd } pname := args[0] alias := args[1] _, err := db.GetRecord(db.DBName, pname, StatusBucket) if err != nil { fmt.Printf("%s project does not exist in db", pname) - return + return err } fmt.Printf("Aliasing %s to %s \n", pname, alias) data := map[string]string{alias: pname} revData := map[string]string{pname: alias} - db.WriteToDB(db.DBName, data, ProjectAliasBucket) - db.WriteToDB(db.DBName, revData, ProjectAliasBucket) + err = db.WriteToDB(db.DBName, data, ProjectAliasBucket) + if err != nil { + return err + } + err = db.WriteToDB(db.DBName, revData, ProjectAliasBucket) + if err != nil { + return err + } + + return nil }, } diff --git a/cmd/delete.go b/cmd/delete.go index 496073e..88c4def 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -1,54 +1,59 @@ package cmd import ( + "errors" "fmt" - "log" "github.com/spf13/cobra" "github.com/theredditbandit/pman/pkg/db" ) +var ( + ErrBadUsageDelCmd error = errors.New("bad usage of delete command") +) + var delCmd = &cobra.Command{ Use: "delete", Short: "Deletes a project from the index database. This does not delete the project from the filesystem", Aliases: []string{"del", "d"}, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { fmt.Println("Usage : pman delete ") - return + return ErrBadUsageDelCmd } projName := args[0] _, err := db.GetRecord(db.DBName, projName, StatusBucket) if err != nil { fmt.Printf("%s is not a valid project to be deleted\n", projName) fmt.Println("Note : projects cannot be deleted using their alias") - return + return err } err = db.DeleteFromDb(db.DBName, projName, ProjectPathBucket) if err != nil { - log.Fatal(err) + return err } err = db.DeleteFromDb(db.DBName, projName, StatusBucket) if err != nil { - log.Fatal(err) + return err } alias, err := db.GetRecord(db.DBName, projName, ProjectAliasBucket) if err == nil { err = db.DeleteFromDb(db.DBName, alias, ProjectAliasBucket) if err != nil { - log.Fatal(err) + return err } err = db.DeleteFromDb(db.DBName, projName, ProjectAliasBucket) if err != nil { - log.Fatal(err) + return err } } err = nil if err != nil { - log.Fatal(err) + return err } fmt.Printf("Successfully deleted %s from the db \n", projName) + return nil }, } diff --git a/cmd/info.go b/cmd/info.go index 71e5cd1..2b35730 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -8,19 +9,30 @@ import ( "github.com/theredditbandit/pman/pkg/utils" ) +var ( + ErrBadUsageInfoCmd error = errors.New("bad usage of info command") +) + var infoCmd = &cobra.Command{ Use: "info", Short: "The info command pretty prints the README.md file present at the root of the specified project.", Aliases: []string{"ifo", "ifno", "ino"}, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if len(args) != 1 { fmt.Println("Please provide a project name") - return + return ErrBadUsageInfoCmd } projectName := args[0] - infoData := utils.ReadREADME(projectName) - md := utils.BeautifyMD(infoData) + infoData, err := utils.ReadREADME(projectName) + if err != nil { + return err + } + md, err := utils.BeautifyMD(infoData) + if err != nil { + return err + } fmt.Print(md) + return nil }, } diff --git a/cmd/init.go b/cmd/init.go index 22e9574..b9329f3 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -15,8 +15,8 @@ var initCmd = &cobra.Command{ Running pman init is the same as running: pman add /* `, - Run: func(cmd *cobra.Command, args []string) { - pkg.InitDirs(args) + RunE: func(cmd *cobra.Command, args []string) error { + return pkg.InitDirs(args) }, } diff --git a/cmd/ls.go b/cmd/ls.go index fef82f9..ed4ff2a 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "log" "github.com/spf13/cobra" @@ -17,19 +16,19 @@ var lsCmd = &cobra.Command{ Long: `List all indexed projects along with their status Usage : pman ls `, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { filterFlag, _ := cmd.Flags().GetString("f") data, err := db.GetAllRecords(db.DBName, StatusBucket) if err != nil { - log.Fatal(err) + return err } if filterFlag != "" { fmt.Println("Filtering by status : ", filterFlag) data := utils.FilterByStatus(data, filterFlag) ui.RenderTable(data) - return } ui.RenderTable(data) + return nil }, } diff --git a/cmd/reset.go b/cmd/reset.go index 1cfa19d..1eeb819 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -11,12 +11,14 @@ import ( var resetCmd = &cobra.Command{ Use: "reset", Short: "Deletes the current indexed projects, run pman init to reindex the projects", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { err := db.DeleteDb(db.DBName) if err != nil { fmt.Println(err) + return err } fmt.Println("Successfully reset the database, run pman init to reindex the projects") + return nil }, } diff --git a/cmd/set.go b/cmd/set.go index 5e885e5..8290656 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -1,6 +1,7 @@ package cmd import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -8,6 +9,11 @@ import ( "github.com/theredditbandit/pman/pkg/db" ) +var ( + ErrFlagNotImplemented error = errors.New("flag not implemented yet") + ErrBadUsageSetCmd error = errors.New("bad usage of set command") +) + var setCmd = &cobra.Command{ Use: "set", Short: "Set the status of a project", @@ -17,15 +23,15 @@ var setCmd = &cobra.Command{ Common statuses: Indexed (default), Idea, Started, Paused, Completed, Aborted, Ongoing, Not Started `, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { interactiveFlag, _ := cmd.Flags().GetBool("i") // TODO: Implement this if interactiveFlag { fmt.Println("Not implemented yet") - return + return ErrFlagNotImplemented } if len(args) != 2 { fmt.Println("Please provide a directory name") - return + return ErrBadUsageSetCmd } var pname string alias := args[0] @@ -39,9 +45,10 @@ var setCmd = &cobra.Command{ err = db.UpdateRec(db.DBName, pname, status, StatusBucket) if err != nil { fmt.Println("Error updating record : ", err) - return + return err } fmt.Printf("Project %s set to status %s\n", pname, status) + return nil }, } diff --git a/cmd/status.go b/cmd/status.go index 03c9b36..60949d7 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -9,16 +9,20 @@ import ( "github.com/theredditbandit/pman/pkg/utils" ) +var ( + ErrBadUsageStatusCmd error = fmt.Errorf("bad usage of status command") +) + // statusCmd represents the status command var statusCmd = &cobra.Command{ Use: "status", Short: "Get the status of a project", Long: `Query the database for the status of a project.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { var alias string if len(args) != 1 { fmt.Println("Please provide a project name") - return + return ErrBadUsageStatusCmd } projName := args[0] actualName, err := db.GetRecord(db.DBName, projName, ProjectAliasBucket) @@ -29,13 +33,14 @@ var statusCmd = &cobra.Command{ status, err := db.GetRecord(db.DBName, projName, StatusBucket) if err != nil { fmt.Printf("%s is not a valid project name : Err -> %s", projName, err) - return + return err } if alias != "" { fmt.Printf("Status of %s (%s) : %s\n", projName, alias, utils.TitleCase(status)) } else { fmt.Printf("Status of %s : %s\n", projName, utils.TitleCase(status)) } + return nil }, } diff --git a/pkg/db/db.go b/pkg/db/db.go index 3a317a1..49a0b06 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -30,7 +30,7 @@ var ( func WriteToDB(dbname string, data map[string]string, bucketName string) error { db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it if err != nil { - log.Printf("%v : %v", ErrOpenDB, err) + log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } defer db.Close() @@ -53,7 +53,7 @@ func WriteToDB(dbname string, data map[string]string, bucketName string) error { func DeleteFromDb(dbname, key, bucketName string) error { db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it if err != nil { - log.Printf("%v : %v", ErrOpenDB, err) + log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } defer db.Close() @@ -89,7 +89,7 @@ func GetRecord(dbname, key, bucketName string) (string, error) { var rec string db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) if err != nil { - log.Printf("%v : %v", ErrOpenDB, err) + log.Printf("%v : %v \n", ErrOpenDB, err) return "", errors.Join(ErrOpenDB, err) } defer db.Close() @@ -115,7 +115,7 @@ func GetRecord(dbname, key, bucketName string) (string, error) { func GetAllRecords(dbname, bucketName string) (map[string]string, error) { db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) if err != nil { - log.Printf("%v : %v", ErrOpenDB, err) + log.Printf("%v : %v \n", ErrOpenDB, err) return map[string]string{}, errors.Join(ErrOpenDB, err) } defer db.Close() @@ -123,7 +123,7 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { - fmt.Print("Database not found \nThis could be because no project dir has been initialized yet") + fmt.Print("Database not found \nThis could be because no project dir has been initialized yet \n") return ErrBucketNotFound } err := bucket.ForEach(func(k, v []byte) error { diff --git a/pkg/indexer.go b/pkg/indexer.go index 6f2d737..e814ee6 100644 --- a/pkg/indexer.go +++ b/pkg/indexer.go @@ -17,10 +17,10 @@ const ( ) var ( - ErrDirname = errors.New("error providing a directory name") - ErrDirInvalid = errors.New("error providing a valid directory name") - ErrIsNotDir = errors.New("error providing a file instead of a directory") - ErrIndexDir = errors.New("error indexing directory") + ErrDirname error = errors.New("error providing a directory name") + ErrDirInvalid error = errors.New("error providing a valid directory name") + ErrIsNotDir error = errors.New("error providing a file instead of a directory") + ErrIndexDir error = errors.New("error indexing directory") ) // InitDirs indexes a directory for project directories and writes the data to the db diff --git a/pkg/ui/pager/renderer.go b/pkg/ui/pager/renderer.go index cb6a5a8..779d4f5 100644 --- a/pkg/ui/pager/renderer.go +++ b/pkg/ui/pager/renderer.go @@ -102,10 +102,17 @@ func (m model) footerView() string { } func LaunchRenderer(file string) { - content := utils.ReadREADME(file) + content, err := utils.ReadREADME(file) + if err != nil { + log.Fatal("could not read README :", err) + } + modelContent, err := utils.BeautifyMD(content) + if err != nil { + log.Fatal("could not beautify markdown :", err) + } p := tea.NewProgram( model{ - content: utils.BeautifyMD(content), + content: modelContent, project: file, }, tea.WithAltScreen(), // use the full size of the terminal in its "alternate screen buffer" diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 0e68d8c..0c6019b 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "errors" "fmt" "log" "os" @@ -15,6 +16,11 @@ import ( "github.com/theredditbandit/pman/pkg/db" ) +var ( + ErrBeautifyMD error = errors.New("error beautifying markdown") + ErrReadREADME error = errors.New("error reading README") +) + func TitleCase(s string) string { c := cases.Title(language.English) return c.String(s) @@ -74,33 +80,35 @@ func GetLastModifiedTime(pname string) string { } // BeautifyMD: returns styled markdown -func BeautifyMD(data []byte) string { +func BeautifyMD(data []byte) (string, error) { r, err := glamour.NewTermRenderer( glamour.WithAutoStyle(), glamour.WithWordWrap(120), glamour.WithAutoStyle(), ) if err != nil { - log.Fatal("something went wrong while creating renderer: ", err) + log.Print("something went wrong while creating renderer: ", err) + return "", errors.Join(ErrBeautifyMD, err) } out, _ := r.Render(string(data)) - return out + return out, nil } // ReadREADME: returns the byte array of README.md of a project -func ReadREADME(projectName string) []byte { +func ReadREADME(projectName string) ([]byte, error) { actualName, err := db.GetRecord(db.DBName, projectName, pkg.ProjectAliasBucket) if err == nil { projectName = actualName } path, err := db.GetRecord(db.DBName, projectName, pkg.ProjectPaths) if err != nil { - log.Fatalf("project: %v not a valid project\n", projectName) + log.Printf("project: %v not a valid project\n", projectName) + return nil, errors.Join(ErrReadREADME, err) } pPath := filepath.Join(path, "README.md") data, err := os.ReadFile(pPath) if err != nil { log.Fatal("Something went wrong while reading README for ", projectName, "\nERR : ", err) } - return data + return data, nil } From b8b2a79c11ee763f9c932c9e847dbf3aa85bf1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Fri, 10 May 2024 02:18:24 +0200 Subject: [PATCH 03/10] chores: add type on constant declared in utils/indexer.go --- cmd/root.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 6ba5c78..7adf70a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,16 +7,17 @@ import ( ) const ( - StatusBucket = "projects" - ProjectPathBucket = "projectPaths" - ProjectAliasBucket = "projectAliases" - version = "1.0" + StatusBucket string = "projects" + ProjectPathBucket string = "projectPaths" + ProjectAliasBucket string = "projectAliases" + version string = "1.0" ) var rootCmd = &cobra.Command{ - Use: "pman", - Short: "A cli project manager", - Version: version, + Use: "pman", + Short: "A cli project manager", + Version: version, + SilenceUsage: true, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Help() From a20caa5a7b149c2f146faccccc678a936c06c9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Fri, 10 May 2024 12:34:27 +0200 Subject: [PATCH 04/10] test: add tests for db.go --- go.mod | 4 + go.sum | 6 + pkg/db/db.go | 63 +++++++--- pkg/db/db_test.go | 285 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 342 insertions(+), 16 deletions(-) create mode 100644 pkg/db/db_test.go diff --git a/go.mod b/go.mod index 8d73611..945d5d4 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.10.0 github.com/spf13/cobra v1.8.0 + github.com/stretchr/testify v1.8.1 github.com/thoas/go-funk v0.9.3 go.etcd.io/bbolt v1.3.9 golang.org/x/text v0.14.0 @@ -19,6 +20,7 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/containerd/console v1.0.4 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.11.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -32,6 +34,7 @@ require ( github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -41,4 +44,5 @@ require ( golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/term v0.19.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 20d78e5..79e3b95 100644 --- a/go.sum +++ b/go.sum @@ -72,7 +72,11 @@ github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyh github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= @@ -96,7 +100,9 @@ golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/db/db.go b/pkg/db/db.go index 49a0b06..edf5f4e 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -11,8 +11,8 @@ import ( bolt "go.etcd.io/bbolt" ) -const DBName string = "projects.db" -const DBTestName string = "projects_test.db" +const DBName string = "projects" +const DBTestName string = "projects_test" var ( ErrOpenDB = errors.New("error opening database") @@ -24,11 +24,16 @@ var ( ErrKeyNotFound = errors.New("key not found in db") ErrListAllRecords = errors.New("error listing all records") ErrClearDB = errors.New("error clearing database") + ErrDBNameEmpty = errors.New("dbname cannot be empty") ) // WriteToDB writes the data to the specified bucket in the database func WriteToDB(dbname string, data map[string]string, bucketName string) error { - db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return errors.Join(ErrOpenDB, err) + } + db, err := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) @@ -51,7 +56,11 @@ func WriteToDB(dbname string, data map[string]string, bucketName string) error { } func DeleteFromDb(dbname, key, bucketName string) error { - db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) // create the database if it doesn't exist then open it + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return errors.Join(ErrOpenDB, err) + } + db, err := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) @@ -62,32 +71,38 @@ func DeleteFromDb(dbname, key, bucketName string) error { if bucket == nil { return ErrBucketNotFound } - err := bucket.Delete([]byte(key)) - if err != nil { - return errors.Join(ErrDeleteFromDB, err) - } + bucket.Delete([]byte(key)) + return nil }) return err } // getDBLoc returns the path to the database file, creating the directory if it doesn't exist -func getDBLoc(dbname string) string { +func GetDBLoc(dbname string) (string, error) { usr, err := user.Current() if err != nil { panic(err) } + if dbname == "" { + return "", ErrDBNameEmpty + } + dbname = dbname + ".db" dbPath := filepath.Join(usr.HomeDir, ".local", "share", "pman", dbname) if _, err := os.Stat(filepath.Dir(dbPath)); os.IsNotExist(err) { os.MkdirAll(filepath.Dir(dbPath), 0o755) } - return dbPath + return dbPath, nil } // GetRecord returns the value of the key from the specified bucket, and error if it does not exist func GetRecord(dbname, key, bucketName string) (string, error) { var rec string - db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return "", err + } + db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return "", errors.Join(ErrOpenDB, err) @@ -113,7 +128,11 @@ func GetRecord(dbname, key, bucketName string) (string, error) { // GetAllRecords returns all the records from the specified bucket as a dictionary func GetAllRecords(dbname, bucketName string) (map[string]string, error) { - db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return map[string]string{}, err + } + db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return map[string]string{}, errors.Join(ErrOpenDB, err) @@ -130,7 +149,10 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { records[string(k)] = string(v) return nil }) - return errors.Join(ErrListAllRecords, err) + if err != nil { + return errors.Join(ErrListAllRecords, err) + } + return nil }) if err != nil { return nil, err @@ -140,9 +162,14 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { // UpdateRec updates the value of the key in the specified bucket, usually used to update the status of a project func UpdateRec(dbname, key, val, bucketName string) error { - db, err := bolt.Open(getDBLoc(dbname), 0o600, nil) + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return err + } + db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { - log.Fatal(err) + log.Print(err) + return errors.Join(ErrOpenDB, err) } defer db.Close() err = db.Update(func(tx *bolt.Tx) error { @@ -161,7 +188,11 @@ func UpdateRec(dbname, key, val, bucketName string) error { } func DeleteDb(dbname string) error { - err := os.Remove(getDBLoc(dbname)) + DBLoc, err := GetDBLoc(dbname) + if err != nil { + return err + } + err = os.Remove(DBLoc) if err != nil { return errors.Join(ErrClearDB, err) } diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go new file mode 100644 index 0000000..74ca434 --- /dev/null +++ b/pkg/db/db_test.go @@ -0,0 +1,285 @@ +package db_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" + "github.com/theredditbandit/pman/pkg/db" + bolt "go.etcd.io/bbolt" +) + +func Test_GetDBLoc(t *testing.T) { + t.Run("Test getDBLoc", func(t *testing.T) { + expectedWords := []string{".local", "share", "pman"} + + actualPath, err := db.GetDBLoc(db.DBTestName) + defer os.Remove(actualPath) + + require.Equal(t, err, nil) + require.Contains(t, actualPath, expectedWords[0], expectedWords[1], expectedWords[2], db.DBTestName) + }) + + t.Run("Test GetDBLoc with empty dbname", func(t *testing.T) { + dbname := "" + expectedErr := db.ErrDBNameEmpty + + actualPath, err := db.GetDBLoc(dbname) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + require.Empty(t, actualPath) + }) + + t.Run("Test getDBLoc with panic", func(t *testing.T) { + + }) +} + +func Test_GetRecord(t *testing.T) { + t.Run("Test GetRecord", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + expectedValue := "testValue" + key := "testKey" + bucketName := "testBucket" + + err = db.WriteToDB(dbname, map[string]string{key: expectedValue}, bucketName) + require.NoError(t, err) + + actualValue, err := db.GetRecord(dbname, key, bucketName) + require.NoError(t, err) + require.Equal(t, expectedValue, actualValue) + }) + + t.Run("Test GetRecord with key not found", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + key := "testKey" + bucketName := "testBucket" + expectedErr := db.ErrKeyNotFound + + err = db.WriteToDB(dbname, map[string]string{}, bucketName) + require.NoError(t, err) + + actualValue, err := db.GetRecord(dbname, key, bucketName) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + require.Empty(t, actualValue) + }) + + t.Run("Test GetRecord with bucket not found", func(t *testing.T) { + dbname := db.DBTestName + key := "testKey" + bucketName := "testBucket" + expectedErr := db.ErrBucketNotFound + + actualValue, err := db.GetRecord(dbname, key, bucketName) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + require.Empty(t, actualValue) + }) +} +func Test_WriteToDB(t *testing.T) { + t.Run("Test WriteToDB", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + // Verify that the data was written correctly + db, err := bolt.Open(DBLoc, 0o600, nil) + require.NoError(t, err) + defer db.Close() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(bucketName)) + require.NotNil(t, bucket) + + for k, v := range data { + value := bucket.Get([]byte(k)) + require.Equal(t, []byte(v), value) + } + + return nil + }) + require.NoError(t, err) + }) + + t.Run("Test WriteToDB with empty bucketname", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "" + + err = db.WriteToDB(dbname, data, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, db.ErrCreateBucket) + }) + + t.Run("Test WriteToDB with empty map key", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "": "value1", + } + bucketName := "testBucket" + + err = db.WriteToDB(dbname, data, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, db.ErrWriteToDB) + }) + + t.Run("Test WriteToDB with empty dbname value", func(t *testing.T) { + dbname := "" + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + + err := db.WriteToDB(dbname, data, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, db.ErrOpenDB) + }) +} + +func Test_DeleteFromDb(t *testing.T) { + t.Run("Test DeleteFromDb", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + key := "key1" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + err = db.DeleteFromDb(dbname, key, bucketName) + require.NoError(t, err) + + // Verify that the key was deleted + db, err := bolt.Open(DBLoc, 0o600, nil) + require.NoError(t, err) + defer db.Close() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(bucketName)) + require.NotNil(t, bucket) + + value := bucket.Get([]byte(key)) + require.Nil(t, value) + + return nil + }) + require.NoError(t, err) + }) + + t.Run("Test DeleteFromDb with key not found", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + key := "key4" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + err = db.DeleteFromDb(dbname, key, bucketName) + + require.NoError(t, err) + }) + + t.Run("Test DeleteFromDb with bucket not found", func(t *testing.T) { + dbname := db.DBTestName + key := "key1" + bucketName := "testBucket" + expectedErr := db.ErrBucketNotFound + + err := db.DeleteFromDb(dbname, key, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, expectedErr) + }) +} + +func Test_ListAllRecords(t *testing.T) { + t.Run("Test ListAllRecords", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + records, err := db.GetAllRecords(dbname, bucketName) + + require.NoError(t, err) + require.Equal(t, data, records) + }) + + t.Run("Test ListAllRecords with bucket not found", func(t *testing.T) { + dbname := db.DBTestName + bucketName := "testBucket" + expectedErr := db.ErrBucketNotFound + + records, err := db.GetAllRecords(dbname, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, expectedErr) + require.Nil(t, records) + }) +} From 54ffa88cbcd78fae8dd5c58bf848576cb3c6ea52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Fri, 10 May 2024 14:10:02 +0200 Subject: [PATCH 05/10] test: end db.go testing --- pkg/db/db.go | 39 ++++-------- pkg/db/db_test.go | 150 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 27 deletions(-) diff --git a/pkg/db/db.go b/pkg/db/db.go index edf5f4e..5e3bb6f 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -30,14 +30,11 @@ var ( // WriteToDB writes the data to the specified bucket in the database func WriteToDB(dbname string, data map[string]string, bucketName string) error { DBLoc, err := GetDBLoc(dbname) - if err != nil { - return errors.Join(ErrOpenDB, err) - } - db, err := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } + db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(bucketName)) @@ -57,14 +54,11 @@ func WriteToDB(dbname string, data map[string]string, bucketName string) error { func DeleteFromDb(dbname, key, bucketName string) error { DBLoc, err := GetDBLoc(dbname) - if err != nil { - return errors.Join(ErrOpenDB, err) - } - db, err := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } + db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) @@ -99,14 +93,12 @@ func GetDBLoc(dbname string) (string, error) { func GetRecord(dbname, key, bucketName string) (string, error) { var rec string DBLoc, err := GetDBLoc(dbname) - if err != nil { - return "", err - } - db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) - return "", errors.Join(ErrOpenDB, err) + return "", err } + db, _ := bolt.Open(DBLoc, 0o600, nil) + defer db.Close() err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) @@ -129,14 +121,12 @@ func GetRecord(dbname, key, bucketName string) (string, error) { // GetAllRecords returns all the records from the specified bucket as a dictionary func GetAllRecords(dbname, bucketName string) (map[string]string, error) { DBLoc, err := GetDBLoc(dbname) - if err != nil { - return map[string]string{}, err - } - db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) - return map[string]string{}, errors.Join(ErrOpenDB, err) + + return map[string]string{}, err } + db, _ := bolt.Open(DBLoc, 0o600, nil) defer db.Close() records := make(map[string]string) err = db.View(func(tx *bolt.Tx) error { @@ -163,14 +153,12 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { // UpdateRec updates the value of the key in the specified bucket, usually used to update the status of a project func UpdateRec(dbname, key, val, bucketName string) error { DBLoc, err := GetDBLoc(dbname) - if err != nil { - return err - } - db, err := bolt.Open(DBLoc, 0o600, nil) if err != nil { log.Print(err) - return errors.Join(ErrOpenDB, err) + return err } + db, _ := bolt.Open(DBLoc, 0o600, nil) + defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) @@ -192,9 +180,6 @@ func DeleteDb(dbname string) error { if err != nil { return err } - err = os.Remove(DBLoc) - if err != nil { - return errors.Join(ErrClearDB, err) - } + os.Remove(DBLoc) return nil } diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go index 74ca434..72757f2 100644 --- a/pkg/db/db_test.go +++ b/pkg/db/db_test.go @@ -55,6 +55,19 @@ func Test_GetRecord(t *testing.T) { require.Equal(t, expectedValue, actualValue) }) + t.Run("Test GetRecord with empty dbname", func(t *testing.T) { + dbname := "" + key := "testKey" + bucketName := "testBucket" + expectedErr := db.ErrDBNameEmpty + + actualValue, err := db.GetRecord(dbname, key, bucketName) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + require.Empty(t, actualValue) + }) + t.Run("Test GetRecord with key not found", func(t *testing.T) { dbname := db.DBTestName DBLoc, err := db.GetDBLoc(dbname) @@ -213,6 +226,18 @@ func Test_DeleteFromDb(t *testing.T) { require.NoError(t, err) }) + t.Run("Test DeleteFromDb with empty dbname", func(t *testing.T) { + dbname := "" + key := "key1" + bucketName := "testBucket" + expectedErr := db.ErrDBNameEmpty + + err := db.DeleteFromDb(dbname, key, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, expectedErr) + }) + t.Run("Test DeleteFromDb with key not found", func(t *testing.T) { dbname := db.DBTestName DBLoc, err := db.GetDBLoc(dbname) @@ -271,6 +296,19 @@ func Test_ListAllRecords(t *testing.T) { require.Equal(t, data, records) }) + t.Run("Test ListAllRecords with empty dbname", func(t *testing.T) { + dbname := "" + bucketName := "testBucket" + expectedErr := db.ErrDBNameEmpty + expectedValue := map[string]string{} + + records, err := db.GetAllRecords(dbname, bucketName) + + require.Error(t, err) + require.ErrorIs(t, err, expectedErr) + require.Equal(t, records, expectedValue) + }) + t.Run("Test ListAllRecords with bucket not found", func(t *testing.T) { dbname := db.DBTestName bucketName := "testBucket" @@ -283,3 +321,115 @@ func Test_ListAllRecords(t *testing.T) { require.Nil(t, records) }) } +func Test_UpdateRec(t *testing.T) { + t.Run("Test UpdateRec", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + key := "key1" + newValue := "updatedValue" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + err = db.UpdateRec(dbname, key, newValue, bucketName) + require.NoError(t, err) + + // Verify that the value was updated + db, err := bolt.Open(DBLoc, 0o600, nil) + require.NoError(t, err) + defer db.Close() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket([]byte(bucketName)) + require.NotNil(t, bucket) + + value := bucket.Get([]byte(key)) + require.Equal(t, []byte(newValue), value) + return nil + }) + require.NoError(t, err) + }) + + t.Run("Test UpdateRec with empty dbname", func(t *testing.T) { + dbname := "" + key := "key1" + newValue := "updatedValue" + bucketName := "testBucket" + err := db.UpdateRec(dbname, key, newValue, bucketName) + + require.Error(t, err) + require.Equal(t, db.ErrDBNameEmpty, err) + }) + + t.Run("Test UpdateRec with key not found", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + data := map[string]string{ + "key1": "value1", + "key2": "value2", + "key3": "value3", + } + bucketName := "testBucket" + key := "key4" + newValue := "updatedValue" + + err = db.WriteToDB(dbname, data, bucketName) + require.NoError(t, err) + + err = db.UpdateRec(dbname, key, newValue, bucketName) + + require.Error(t, err) + require.Equal(t, db.ErrProjectNotFound, err) + }) + + t.Run("Test UpdateRec with bucket not found", func(t *testing.T) { + dbname := db.DBTestName + key := "key1" + newValue := "updatedValue" + bucketName := "testBucket" + expectedErr := db.ErrBucketNotFound + + err := db.UpdateRec(dbname, key, newValue, bucketName) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + }) +} + +func Test_DeleteDb(t *testing.T) { + t.Run("Test DeleteDb", func(t *testing.T) { + dbname := db.DBTestName + DBLoc, err := db.GetDBLoc(dbname) + require.NoError(t, err) + defer os.Remove(DBLoc) + + err = db.DeleteDb(dbname) + require.NoError(t, err) + + // Verify that the database file is deleted + _, err = os.Stat(DBLoc) + require.True(t, os.IsNotExist(err)) + }) + + t.Run("Test DeleteDb with empty dbname", func(t *testing.T) { + dbname := "" + expectedErr := db.ErrDBNameEmpty + + err := db.DeleteDb(dbname) + + require.Error(t, err) + require.Equal(t, expectedErr, err) + }) +} From 0cb5ae613875ca01462e2135fb069217e7dd5002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Sun, 12 May 2024 02:04:21 +0200 Subject: [PATCH 06/10] chores: Make the suggestions requested --- cmd/alias.go | 4 +- cmd/delete.go | 4 +- cmd/info.go | 4 +- cmd/init.go | 2 +- cmd/ls.go | 10 +- cmd/reset.go | 2 +- cmd/root.go | 20 ++-- cmd/set.go | 6 +- cmd/status.go | 2 +- pkg/db/db_test.go | 282 +++++++++++++++++++++++---------------------- pkg/indexer.go | 25 ++-- pkg/utils/utils.go | 10 +- 12 files changed, 190 insertions(+), 181 deletions(-) diff --git a/cmd/alias.go b/cmd/alias.go index 1709539..e85ff66 100644 --- a/cmd/alias.go +++ b/cmd/alias.go @@ -10,7 +10,7 @@ import ( ) var ( - ErrBadUsageAliasCmd error = errors.New("bad usage of alias command") + ErrBadUsageAliasCmd = errors.New("bad usage of alias command") ) // aliasCmd represents the alias command @@ -19,7 +19,7 @@ var aliasCmd = &cobra.Command{ Short: "Sets the alias for a project, whose name might be too big", Long: `The idea is instead of having to type a-very-long-project-name-every-time you can alias it to avlpn or something smaller and use that to query pman`, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { if len(args) != 2 { fmt.Println("Usage: pman alias ") return ErrBadUsageAliasCmd diff --git a/cmd/delete.go b/cmd/delete.go index 88c4def..b759380 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -10,14 +10,14 @@ import ( ) var ( - ErrBadUsageDelCmd error = errors.New("bad usage of delete command") + ErrBadUsageDelCmd = errors.New("bad usage of delete command") ) var delCmd = &cobra.Command{ Use: "delete", Short: "Deletes a project from the index database. This does not delete the project from the filesystem", Aliases: []string{"del", "d"}, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { if len(args) != 1 { fmt.Println("Usage : pman delete ") return ErrBadUsageDelCmd diff --git a/cmd/info.go b/cmd/info.go index 2b35730..3c73fa6 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -10,14 +10,14 @@ import ( ) var ( - ErrBadUsageInfoCmd error = errors.New("bad usage of info command") + ErrBadUsageInfoCmd = errors.New("bad usage of info command") ) var infoCmd = &cobra.Command{ Use: "info", Short: "The info command pretty prints the README.md file present at the root of the specified project.", Aliases: []string{"ifo", "ifno", "ino"}, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { if len(args) != 1 { fmt.Println("Please provide a project name") return ErrBadUsageInfoCmd diff --git a/cmd/init.go b/cmd/init.go index b9329f3..da3d2d6 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -15,7 +15,7 @@ var initCmd = &cobra.Command{ Running pman init is the same as running: pman add /* `, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { return pkg.InitDirs(args) }, } diff --git a/cmd/ls.go b/cmd/ls.go index e6f762c..6b3c4f6 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -18,17 +18,19 @@ var lsCmd = &cobra.Command{ `, RunE: func(cmd *cobra.Command, args []string) error { filterFlag, _ := cmd.Flags().GetString("f") + oldUi, _ := cmd.Flags().GetBool("o") data, err := db.GetAllRecords(db.DBName, StatusBucket) if err != nil { return err } if filterFlag != "" { fmt.Println("Filtering by status : ", filterFlag) - data := utils.FilterByStatus(data, filterFlag) - ui.RenderTable(data) + data = utils.FilterByStatus(data, filterFlag) } - ui.RenderTable(data) - return nil + if oldUi { + return ui.RenderTable(data) + } + return ui.RenderInteractiveTable(data) }, } diff --git a/cmd/reset.go b/cmd/reset.go index 852f6f6..1c90373 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -11,7 +11,7 @@ import ( var resetCmd = &cobra.Command{ Use: "reset", Short: "Deletes the current indexed projects, run pman init to reindex the projects", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { err := db.DeleteDb(db.DBName) if err != nil { fmt.Println(err) diff --git a/cmd/root.go b/cmd/root.go index 97396ee..4889b96 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -7,20 +7,24 @@ import ( ) const ( - StatusBucket string = "projects" - ProjectPathBucket string = "projectPaths" - ProjectAliasBucket string = "projectAliases" - version string = "1.0" + StatusBucket = "projects" + ProjectPathBucket = "projectPaths" + ProjectAliasBucket = "projectAliases" + version = "1.0" +) + +var ( + ErrNoArgs = errors.New("this command has no argument") ) var rootCmd = &cobra.Command{ - Use: "pman", - Short: "A cli project manager", - Version: version, + Use: "pman", + Short: "A cli project manager", + Version: version, SilenceUsage: true, RunE: func(_ *cobra.Command, args []string) error { if len(args) == 0 { - return errors.New("this command has no argument") + return ErrNoArgs } return nil }, diff --git a/cmd/set.go b/cmd/set.go index 8290656..e72ad48 100644 --- a/cmd/set.go +++ b/cmd/set.go @@ -10,8 +10,8 @@ import ( ) var ( - ErrFlagNotImplemented error = errors.New("flag not implemented yet") - ErrBadUsageSetCmd error = errors.New("bad usage of set command") + ErrFlagNotImplemented = errors.New("flag not implemented yet") + ErrBadUsageSetCmd = errors.New("bad usage of set command") ) var setCmd = &cobra.Command{ @@ -26,7 +26,7 @@ var setCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { interactiveFlag, _ := cmd.Flags().GetBool("i") // TODO: Implement this if interactiveFlag { - fmt.Println("Not implemented yet") + cmd.SilenceUsage = true return ErrFlagNotImplemented } if len(args) != 2 { diff --git a/cmd/status.go b/cmd/status.go index 04cebae..2ec84e6 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -19,7 +19,7 @@ var statusCmd = &cobra.Command{ Use: "status", Short: "Get the status of a project", Long: `Query the database for the status of a project.`, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { var alias string if len(args) != 1 { fmt.Println("Please provide a project name") diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go index 72757f2..7c3319b 100644 --- a/pkg/db/db_test.go +++ b/pkg/db/db_test.go @@ -4,20 +4,30 @@ import ( "os" "testing" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" "github.com/theredditbandit/pman/pkg/db" bolt "go.etcd.io/bbolt" ) +const dbname = db.DBTestName +const bucketName = "testBucket" +const key = "testKey" + func Test_GetDBLoc(t *testing.T) { t.Run("Test getDBLoc", func(t *testing.T) { expectedWords := []string{".local", "share", "pman"} - actualPath, err := db.GetDBLoc(db.DBTestName) - defer os.Remove(actualPath) + actualPath, err := db.GetDBLoc(dbname) + + t.Cleanup(func() { + os.Remove(actualPath) + }) - require.Equal(t, err, nil) - require.Contains(t, actualPath, expectedWords[0], expectedWords[1], expectedWords[2], db.DBTestName) + assert.Equal(t, err, nil) + assert.Contains(t, actualPath, expectedWords[0]) + assert.Contains(t, actualPath, expectedWords[1]) + assert.Contains(t, actualPath, expectedWords[2]) + assert.Contains(t, actualPath, db.DBTestName) }) t.Run("Test GetDBLoc with empty dbname", func(t *testing.T) { @@ -26,9 +36,8 @@ func Test_GetDBLoc(t *testing.T) { actualPath, err := db.GetDBLoc(dbname) - require.Error(t, err) - require.Equal(t, expectedErr, err) - require.Empty(t, actualPath) + assert.ErrorIs(t, err, expectedErr) + assert.Empty(t, actualPath) }) t.Run("Test getDBLoc with panic", func(t *testing.T) { @@ -38,21 +47,21 @@ func Test_GetDBLoc(t *testing.T) { func Test_GetRecord(t *testing.T) { t.Run("Test GetRecord", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) expectedValue := "testValue" - key := "testKey" - bucketName := "testBucket" err = db.WriteToDB(dbname, map[string]string{key: expectedValue}, bucketName) - require.NoError(t, err) + assert.NoError(t, err) actualValue, err := db.GetRecord(dbname, key, bucketName) - require.NoError(t, err) - require.Equal(t, expectedValue, actualValue) + assert.NoError(t, err) + assert.Equal(t, expectedValue, actualValue) }) t.Run("Test GetRecord with empty dbname", func(t *testing.T) { @@ -63,49 +72,45 @@ func Test_GetRecord(t *testing.T) { actualValue, err := db.GetRecord(dbname, key, bucketName) - require.Error(t, err) - require.Equal(t, expectedErr, err) - require.Empty(t, actualValue) + assert.ErrorIs(t, err, expectedErr) + assert.Empty(t, actualValue) }) t.Run("Test GetRecord with key not found", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) - key := "testKey" - bucketName := "testBucket" expectedErr := db.ErrKeyNotFound + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) err = db.WriteToDB(dbname, map[string]string{}, bucketName) - require.NoError(t, err) + assert.NoError(t, err) actualValue, err := db.GetRecord(dbname, key, bucketName) - require.Error(t, err) - require.Equal(t, expectedErr, err) - require.Empty(t, actualValue) + assert.ErrorIs(t, err, expectedErr) + assert.Empty(t, actualValue) }) t.Run("Test GetRecord with bucket not found", func(t *testing.T) { - dbname := db.DBTestName - key := "testKey" - bucketName := "testBucket" expectedErr := db.ErrBucketNotFound actualValue, err := db.GetRecord(dbname, key, bucketName) - require.Error(t, err) - require.Equal(t, expectedErr, err) - require.Empty(t, actualValue) + assert.ErrorIs(t, err, expectedErr) + assert.Empty(t, actualValue) }) } func Test_WriteToDB(t *testing.T) { t.Run("Test WriteToDB", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", @@ -115,32 +120,34 @@ func Test_WriteToDB(t *testing.T) { bucketName := "testBucket" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) // Verify that the data was written correctly - db, err := bolt.Open(DBLoc, 0o600, nil) - require.NoError(t, err) + db, err := bolt.Open(actualPath, 0o600, nil) + assert.NoError(t, err) defer db.Close() err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) - require.NotNil(t, bucket) + assert.NotNil(t, bucket) for k, v := range data { value := bucket.Get([]byte(k)) - require.Equal(t, []byte(v), value) + assert.Equal(t, []byte(v), value) } return nil }) - require.NoError(t, err) + assert.NoError(t, err) }) t.Run("Test WriteToDB with empty bucketname", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", @@ -151,25 +158,24 @@ func Test_WriteToDB(t *testing.T) { err = db.WriteToDB(dbname, data, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, db.ErrCreateBucket) + assert.ErrorIs(t, err, db.ErrCreateBucket) }) t.Run("Test WriteToDB with empty map key", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "": "value1", } - bucketName := "testBucket" err = db.WriteToDB(dbname, data, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, db.ErrWriteToDB) + assert.ErrorIs(t, err, db.ErrWriteToDB) }) t.Run("Test WriteToDB with empty dbname value", func(t *testing.T) { @@ -183,150 +189,150 @@ func Test_WriteToDB(t *testing.T) { err := db.WriteToDB(dbname, data, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, db.ErrOpenDB) + assert.ErrorIs(t, err, db.ErrOpenDB) }) } func Test_DeleteFromDb(t *testing.T) { t.Run("Test DeleteFromDb", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", "key2": "value2", "key3": "value3", } - bucketName := "testBucket" key := "key1" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) err = db.DeleteFromDb(dbname, key, bucketName) - require.NoError(t, err) + assert.NoError(t, err) // Verify that the key was deleted - db, err := bolt.Open(DBLoc, 0o600, nil) - require.NoError(t, err) + db, err := bolt.Open(actualPath, 0o600, nil) + assert.NoError(t, err) defer db.Close() err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) - require.NotNil(t, bucket) + assert.NotNil(t, bucket) value := bucket.Get([]byte(key)) - require.Nil(t, value) + assert.Nil(t, value) return nil }) - require.NoError(t, err) + assert.NoError(t, err) }) t.Run("Test DeleteFromDb with empty dbname", func(t *testing.T) { dbname := "" key := "key1" - bucketName := "testBucket" expectedErr := db.ErrDBNameEmpty err := db.DeleteFromDb(dbname, key, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, expectedErr) + assert.ErrorIs(t, err, expectedErr) }) t.Run("Test DeleteFromDb with key not found", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", "key2": "value2", "key3": "value3", } - bucketName := "testBucket" key := "key4" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) err = db.DeleteFromDb(dbname, key, bucketName) - require.NoError(t, err) + assert.NoError(t, err) }) t.Run("Test DeleteFromDb with bucket not found", func(t *testing.T) { - dbname := db.DBTestName + key := "key1" - bucketName := "testBucket" expectedErr := db.ErrBucketNotFound err := db.DeleteFromDb(dbname, key, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, expectedErr) + assert.ErrorIs(t, err, expectedErr) }) } func Test_ListAllRecords(t *testing.T) { t.Run("Test ListAllRecords", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", "key2": "value2", "key3": "value3", } - bucketName := "testBucket" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) records, err := db.GetAllRecords(dbname, bucketName) - require.NoError(t, err) - require.Equal(t, data, records) + assert.NoError(t, err) + assert.Equal(t, records, data) }) t.Run("Test ListAllRecords with empty dbname", func(t *testing.T) { dbname := "" - bucketName := "testBucket" expectedErr := db.ErrDBNameEmpty expectedValue := map[string]string{} records, err := db.GetAllRecords(dbname, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, expectedErr) - require.Equal(t, records, expectedValue) + assert.ErrorIs(t, err, expectedErr) + assert.Equal(t, records, expectedValue) }) t.Run("Test ListAllRecords with bucket not found", func(t *testing.T) { - dbname := db.DBTestName - bucketName := "testBucket" + expectedErr := db.ErrBucketNotFound records, err := db.GetAllRecords(dbname, bucketName) - require.Error(t, err) - require.ErrorIs(t, err, expectedErr) - require.Nil(t, records) + assert.ErrorIs(t, err, expectedErr) + assert.Nil(t, records) }) } func Test_UpdateRec(t *testing.T) { t.Run("Test UpdateRec", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", @@ -338,89 +344,88 @@ func Test_UpdateRec(t *testing.T) { newValue := "updatedValue" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) err = db.UpdateRec(dbname, key, newValue, bucketName) - require.NoError(t, err) + assert.NoError(t, err) // Verify that the value was updated - db, err := bolt.Open(DBLoc, 0o600, nil) - require.NoError(t, err) + db, err := bolt.Open(actualPath, 0o600, nil) + assert.NoError(t, err) defer db.Close() err = db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) - require.NotNil(t, bucket) + assert.NotNil(t, bucket) value := bucket.Get([]byte(key)) - require.Equal(t, []byte(newValue), value) + assert.Equal(t, []byte(newValue), value) return nil }) - require.NoError(t, err) + assert.NoError(t, err) }) t.Run("Test UpdateRec with empty dbname", func(t *testing.T) { dbname := "" key := "key1" newValue := "updatedValue" - bucketName := "testBucket" err := db.UpdateRec(dbname, key, newValue, bucketName) - require.Error(t, err) - require.Equal(t, db.ErrDBNameEmpty, err) + assert.ErrorIs(t, err, db.ErrDBNameEmpty) }) t.Run("Test UpdateRec with key not found", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) data := map[string]string{ "key1": "value1", "key2": "value2", "key3": "value3", } - bucketName := "testBucket" key := "key4" newValue := "updatedValue" err = db.WriteToDB(dbname, data, bucketName) - require.NoError(t, err) + assert.NoError(t, err) err = db.UpdateRec(dbname, key, newValue, bucketName) - require.Error(t, err) - require.Equal(t, db.ErrProjectNotFound, err) + assert.ErrorIs(t, err, db.ErrProjectNotFound) }) t.Run("Test UpdateRec with bucket not found", func(t *testing.T) { - dbname := db.DBTestName + key := "key1" newValue := "updatedValue" - bucketName := "testBucket" expectedErr := db.ErrBucketNotFound err := db.UpdateRec(dbname, key, newValue, bucketName) - require.Error(t, err) - require.Equal(t, expectedErr, err) + assert.ErrorIs(t, err, expectedErr) }) } func Test_DeleteDb(t *testing.T) { t.Run("Test DeleteDb", func(t *testing.T) { - dbname := db.DBTestName - DBLoc, err := db.GetDBLoc(dbname) - require.NoError(t, err) - defer os.Remove(DBLoc) + actualPath, err := db.GetDBLoc(dbname) + assert.NoError(t, err) + + t.Cleanup(func() { + os.Remove(actualPath) + }) err = db.DeleteDb(dbname) - require.NoError(t, err) + assert.NoError(t, err) // Verify that the database file is deleted - _, err = os.Stat(DBLoc) - require.True(t, os.IsNotExist(err)) + _, err = os.Stat(actualPath) + assert.True(t, os.IsNotExist(err)) }) t.Run("Test DeleteDb with empty dbname", func(t *testing.T) { @@ -429,7 +434,6 @@ func Test_DeleteDb(t *testing.T) { err := db.DeleteDb(dbname) - require.Error(t, err) - require.Equal(t, expectedErr, err) + assert.ErrorIs(t, err, expectedErr) }) } diff --git a/pkg/indexer.go b/pkg/indexer.go index 6a5e69e..dff5575 100644 --- a/pkg/indexer.go +++ b/pkg/indexer.go @@ -2,7 +2,6 @@ package pkg import ( "errors" - "fmt" "log" "os" "path/filepath" @@ -11,16 +10,16 @@ import ( ) const ( - StatusBucket string = "projects" - ProjectPaths string = "projectPaths" - ProjectAliasBucket string = "projectAliases" + StatusBucket = "projects" + ProjectPaths = "projectPaths" + ProjectAliasBucket = "projectAliases" ) var ( - ErrDirname error = errors.New("error providing a directory name") - ErrDirInvalid error = errors.New("error providing a valid directory name") - ErrIsNotDir error = errors.New("error providing a file instead of a directory") - ErrIndexDir error = errors.New("error indexing directory") + ErrDirname = errors.New("error providing a directory name") + ErrDirInvalid = errors.New("error providing a valid directory name") + ErrIsNotDir = errors.New("error providing a file instead of a directory") + ErrIndexDir = errors.New("error indexing directory") ) // InitDirs indexes a directory for project directories and writes the data to the DB @@ -28,23 +27,23 @@ func InitDirs(args []string) error { // the file which identifies a project directory projIdentifier := "README.md" if len(args) != 1 { - fmt.Println("Please provide a directory name") + log.Print("Please provide a directory name") return ErrDirname } dirname := args[0] if stat, err := os.Stat(dirname); os.IsNotExist(err) { - fmt.Printf("%s is not a directory \n", dirname) + log.Printf("%s is not a directory \n", dirname) return ErrDirInvalid } else if !stat.IsDir() { - fmt.Printf("%s is a file and not a directory \n", dirname) + log.Printf("%s is a file and not a directory \n", dirname) return ErrIsNotDir } projDirs, err := indexDir(dirname, projIdentifier) if err != nil { - fmt.Println(err) + log.Print(err) return ErrIndexDir } - fmt.Printf("Indexed %d project directories . . .\n", len(projDirs)) + log.Printf("Indexed %d project directories . . .\n", len(projDirs)) projectStatusMap := make(map[string]string) projectPathMap := make(map[string]string) for k, v := range projDirs { // k : full project path, v : project status , diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e69c06e..ddca814 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -17,8 +17,8 @@ import ( ) var ( - ErrBeautifyMD error = errors.New("error beautifying markdown") - ErrReadREADME error = errors.New("error reading README") + ErrBeautifyMD = errors.New("error beautifying markdown") + ErrReadREADME = errors.New("error reading README") ) func TitleCase(s string) string { @@ -41,9 +41,9 @@ func PrintData(data map[string]string) { for k, v := range data { alias, err := db.GetRecord(db.DBName, k, pkg.ProjectAliasBucket) if err == nil { - fmt.Printf("%s : %s (%s) \n", TitleCase(v), k, alias) + log.Printf("%s : %s (%s) \n", TitleCase(v), k, alias) } else { - fmt.Printf("%s : %s \n", TitleCase(v), k) + log.Printf("%s : %s \n", TitleCase(v), k) } } } @@ -108,7 +108,7 @@ func ReadREADME(projectName string) ([]byte, error) { pPath := filepath.Join(path, "README.md") data, err := os.ReadFile(pPath) if err != nil { - return nil, fmt.Errorf("Something went wrong while reading README for %s: %w", projectName, err) + return nil, fmt.Errorf("something went wrong while reading README for %s: %w", projectName, err) } return data, nil } From 34eb1b84b4a1e5bc830744587d07e2f526fe93aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Sun, 12 May 2024 13:04:51 +0200 Subject: [PATCH 07/10] make suggestions asked by ci --- cmd/ls.go | 2 +- cmd/reset.go | 2 +- pkg/db/db.go | 29 +++++++++++++---------------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 6b3c4f6..6c3feba 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -16,7 +16,7 @@ var lsCmd = &cobra.Command{ Long: `List all indexed projects along with their status Usage : pman ls `, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { filterFlag, _ := cmd.Flags().GetString("f") oldUi, _ := cmd.Flags().GetBool("o") data, err := db.GetAllRecords(db.DBName, StatusBucket) diff --git a/cmd/reset.go b/cmd/reset.go index 1c90373..f4cd8af 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -11,7 +11,7 @@ import ( var resetCmd = &cobra.Command{ Use: "reset", Short: "Deletes the current indexed projects, run pman init to reindex the projects", - RunE: func(_ *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { err := db.DeleteDb(db.DBName) if err != nil { fmt.Println(err) diff --git a/pkg/db/db.go b/pkg/db/db.go index 52f1889..2698ae4 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -29,12 +29,12 @@ var ( // WriteToDB writes the data to the specified bucket in the database func WriteToDB(dbname string, data map[string]string, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } - db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it + db, _ := bolt.Open(dbLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(bucketName)) @@ -53,21 +53,19 @@ func WriteToDB(dbname string, data map[string]string, bucketName string) error { } func DeleteFromDb(dbname, key, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } - db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it + db, _ := bolt.Open(dbLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { return ErrBucketNotFound } - bucket.Delete([]byte(key)) - - return nil + return bucket.Delete([]byte(key)) }) return err } @@ -95,12 +93,12 @@ func GetDBLoc(dbname string) (string, error) { // GetRecord returns the value of the key from the specified bucket, and error if it does not exist func GetRecord(dbname, key, bucketName string) (string, error) { var rec string - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return "", err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() err = db.View(func(tx *bolt.Tx) error { @@ -123,13 +121,13 @@ func GetRecord(dbname, key, bucketName string) (string, error) { // GetAllRecords returns all the records from the specified bucket as a dictionary func GetAllRecords(dbname, bucketName string) (map[string]string, error) { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return map[string]string{}, err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() records := make(map[string]string) err = db.View(func(tx *bolt.Tx) error { @@ -155,12 +153,12 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { // UpdateRec updates the value of the key in the specified bucket, usually used to update the status of a project func UpdateRec(dbname, key, val, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Print(err) return err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() err = db.Update(func(tx *bolt.Tx) error { @@ -179,10 +177,9 @@ func UpdateRec(dbname, key, val, bucketName string) error { } func DeleteDb(dbname string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { return err } - os.Remove(DBLoc) - return nil + return os.Remove(dbLoc) } From 350fa75ae7ec7466a35ed35257bc4279b03448fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?kouakou=20kouam=C3=A9=20yannick?= Date: Sun, 12 May 2024 13:04:51 +0200 Subject: [PATCH 08/10] make suggestions asked by ci --- cmd/ls.go | 2 +- cmd/reset.go | 2 +- cmd/status.go | 2 +- pkg/db/db.go | 29 +++++++++++++-------------- pkg/db/db_test.go | 40 +++++++++++++++++--------------------- pkg/ui/interactiveTable.go | 2 +- pkg/ui/tui.go | 4 ++-- 7 files changed, 37 insertions(+), 44 deletions(-) diff --git a/cmd/ls.go b/cmd/ls.go index 6b3c4f6..6c3feba 100644 --- a/cmd/ls.go +++ b/cmd/ls.go @@ -16,7 +16,7 @@ var lsCmd = &cobra.Command{ Long: `List all indexed projects along with their status Usage : pman ls `, - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { filterFlag, _ := cmd.Flags().GetString("f") oldUi, _ := cmd.Flags().GetBool("o") data, err := db.GetAllRecords(db.DBName, StatusBucket) diff --git a/cmd/reset.go b/cmd/reset.go index 1c90373..f4cd8af 100644 --- a/cmd/reset.go +++ b/cmd/reset.go @@ -11,7 +11,7 @@ import ( var resetCmd = &cobra.Command{ Use: "reset", Short: "Deletes the current indexed projects, run pman init to reindex the projects", - RunE: func(_ *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, _ []string) error { err := db.DeleteDb(db.DBName) if err != nil { fmt.Println(err) diff --git a/cmd/status.go b/cmd/status.go index 2ec84e6..ba4d671 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -11,7 +11,7 @@ import ( ) var ( - ErrBadUsageStatusCmd error = errors.New("bad usage of status command") + ErrBadUsageStatusCmd = errors.New("bad usage of status command") ) // statusCmd represents the status command diff --git a/pkg/db/db.go b/pkg/db/db.go index 52f1889..2698ae4 100644 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -29,12 +29,12 @@ var ( // WriteToDB writes the data to the specified bucket in the database func WriteToDB(dbname string, data map[string]string, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } - db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it + db, _ := bolt.Open(dbLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte(bucketName)) @@ -53,21 +53,19 @@ func WriteToDB(dbname string, data map[string]string, bucketName string) error { } func DeleteFromDb(dbname, key, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return errors.Join(ErrOpenDB, err) } - db, _ := bolt.Open(DBLoc, 0o600, nil) // create the database if it doesn't exist then open it + db, _ := bolt.Open(dbLoc, 0o600, nil) // create the database if it doesn't exist then open it defer db.Close() err = db.Update(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(bucketName)) if bucket == nil { return ErrBucketNotFound } - bucket.Delete([]byte(key)) - - return nil + return bucket.Delete([]byte(key)) }) return err } @@ -95,12 +93,12 @@ func GetDBLoc(dbname string) (string, error) { // GetRecord returns the value of the key from the specified bucket, and error if it does not exist func GetRecord(dbname, key, bucketName string) (string, error) { var rec string - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return "", err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() err = db.View(func(tx *bolt.Tx) error { @@ -123,13 +121,13 @@ func GetRecord(dbname, key, bucketName string) (string, error) { // GetAllRecords returns all the records from the specified bucket as a dictionary func GetAllRecords(dbname, bucketName string) (map[string]string, error) { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Printf("%v : %v \n", ErrOpenDB, err) return map[string]string{}, err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() records := make(map[string]string) err = db.View(func(tx *bolt.Tx) error { @@ -155,12 +153,12 @@ func GetAllRecords(dbname, bucketName string) (map[string]string, error) { // UpdateRec updates the value of the key in the specified bucket, usually used to update the status of a project func UpdateRec(dbname, key, val, bucketName string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { log.Print(err) return err } - db, _ := bolt.Open(DBLoc, 0o600, nil) + db, _ := bolt.Open(dbLoc, 0o600, nil) defer db.Close() err = db.Update(func(tx *bolt.Tx) error { @@ -179,10 +177,9 @@ func UpdateRec(dbname, key, val, bucketName string) error { } func DeleteDb(dbname string) error { - DBLoc, err := GetDBLoc(dbname) + dbLoc, err := GetDBLoc(dbname) if err != nil { return err } - os.Remove(DBLoc) - return nil + return os.Remove(dbLoc) } diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go index 7c3319b..49e6330 100644 --- a/pkg/db/db_test.go +++ b/pkg/db/db_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/theredditbandit/pman/pkg/db" bolt "go.etcd.io/bbolt" ) @@ -23,7 +24,7 @@ func Test_GetDBLoc(t *testing.T) { os.Remove(actualPath) }) - assert.Equal(t, err, nil) + assert.NoError(t, err) assert.Contains(t, actualPath, expectedWords[0]) assert.Contains(t, actualPath, expectedWords[1]) assert.Contains(t, actualPath, expectedWords[2]) @@ -39,10 +40,6 @@ func Test_GetDBLoc(t *testing.T) { assert.ErrorIs(t, err, expectedErr) assert.Empty(t, actualPath) }) - - t.Run("Test getDBLoc with panic", func(t *testing.T) { - - }) } func Test_GetRecord(t *testing.T) { @@ -72,7 +69,7 @@ func Test_GetRecord(t *testing.T) { actualValue, err := db.GetRecord(dbname, key, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) assert.Empty(t, actualValue) }) @@ -90,7 +87,7 @@ func Test_GetRecord(t *testing.T) { actualValue, err := db.GetRecord(dbname, key, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) assert.Empty(t, actualValue) }) @@ -99,7 +96,7 @@ func Test_GetRecord(t *testing.T) { actualValue, err := db.GetRecord(dbname, key, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) assert.Empty(t, actualValue) }) } @@ -158,7 +155,7 @@ func Test_WriteToDB(t *testing.T) { err = db.WriteToDB(dbname, data, bucketName) - assert.ErrorIs(t, err, db.ErrCreateBucket) + require.ErrorIs(t, err, db.ErrCreateBucket) }) t.Run("Test WriteToDB with empty map key", func(t *testing.T) { @@ -175,7 +172,7 @@ func Test_WriteToDB(t *testing.T) { err = db.WriteToDB(dbname, data, bucketName) - assert.ErrorIs(t, err, db.ErrWriteToDB) + require.ErrorIs(t, err, db.ErrWriteToDB) }) t.Run("Test WriteToDB with empty dbname value", func(t *testing.T) { @@ -189,7 +186,7 @@ func Test_WriteToDB(t *testing.T) { err := db.WriteToDB(dbname, data, bucketName) - assert.ErrorIs(t, err, db.ErrOpenDB) + require.ErrorIs(t, err, db.ErrOpenDB) }) } @@ -240,7 +237,7 @@ func Test_DeleteFromDb(t *testing.T) { err := db.DeleteFromDb(dbname, key, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) }) t.Run("Test DeleteFromDb with key not found", func(t *testing.T) { @@ -274,7 +271,7 @@ func Test_DeleteFromDb(t *testing.T) { err := db.DeleteFromDb(dbname, key, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) }) } @@ -300,7 +297,7 @@ func Test_ListAllRecords(t *testing.T) { records, err := db.GetAllRecords(dbname, bucketName) assert.NoError(t, err) - assert.Equal(t, records, data) + assert.Equal(t,data, records) }) t.Run("Test ListAllRecords with empty dbname", func(t *testing.T) { @@ -310,17 +307,16 @@ func Test_ListAllRecords(t *testing.T) { records, err := db.GetAllRecords(dbname, bucketName) - assert.ErrorIs(t, err, expectedErr) - assert.Equal(t, records, expectedValue) + require.ErrorIs(t, err, expectedErr) + assert.Equal(t, expectedValue, records) }) t.Run("Test ListAllRecords with bucket not found", func(t *testing.T) { - expectedErr := db.ErrBucketNotFound records, err := db.GetAllRecords(dbname, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) assert.Nil(t, records) }) } @@ -371,7 +367,7 @@ func Test_UpdateRec(t *testing.T) { newValue := "updatedValue" err := db.UpdateRec(dbname, key, newValue, bucketName) - assert.ErrorIs(t, err, db.ErrDBNameEmpty) + require.ErrorIs(t, err, db.ErrDBNameEmpty) }) t.Run("Test UpdateRec with key not found", func(t *testing.T) { @@ -396,7 +392,7 @@ func Test_UpdateRec(t *testing.T) { err = db.UpdateRec(dbname, key, newValue, bucketName) - assert.ErrorIs(t, err, db.ErrProjectNotFound) + require.ErrorIs(t, err, db.ErrProjectNotFound) }) t.Run("Test UpdateRec with bucket not found", func(t *testing.T) { @@ -407,7 +403,7 @@ func Test_UpdateRec(t *testing.T) { err := db.UpdateRec(dbname, key, newValue, bucketName) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) }) } @@ -434,6 +430,6 @@ func Test_DeleteDb(t *testing.T) { err := db.DeleteDb(dbname) - assert.ErrorIs(t, err, expectedErr) + require.ErrorIs(t, err, expectedErr) }) } diff --git a/pkg/ui/interactiveTable.go b/pkg/ui/interactiveTable.go index 6fc590d..98b53eb 100644 --- a/pkg/ui/interactiveTable.go +++ b/pkg/ui/interactiveTable.go @@ -104,7 +104,7 @@ func RenderInteractiveTable(data map[string]string) error { m := tableModel{t} if _, err := tea.NewProgram(m).Run(); err != nil { - return fmt.Errorf("error running program: %s", err) + return fmt.Errorf("error running program: %w", err) } return nil } diff --git a/pkg/ui/tui.go b/pkg/ui/tui.go index 0bfea63..13ec32c 100644 --- a/pkg/ui/tui.go +++ b/pkg/ui/tui.go @@ -27,7 +27,7 @@ var ( type item struct { name string status string - lastEdited string + // lastEdited string } func (i item) Title() string { return i.name } @@ -183,7 +183,7 @@ func Tui() error { } if _, err := tea.NewProgram(model, tea.WithAltScreen()).Run(); err != nil { - return fmt.Errorf("Error running program: %w", err) + return fmt.Errorf("error running program: %w", err) } return nil From 0045882d792f8adefb1f5c5ffebc4239480c6fb5 Mon Sep 17 00:00:00 2001 From: aryan <85390033+theredditbandit@users.noreply.github.com> Date: Mon, 13 May 2024 17:12:44 +0530 Subject: [PATCH 09/10] format tui.go and db_test.go with gci --- pkg/db/db_test.go | 3 ++- pkg/ui/tui.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/db/db_test.go b/pkg/db/db_test.go index fdb8600..11cbb73 100644 --- a/pkg/db/db_test.go +++ b/pkg/db/db_test.go @@ -6,8 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/theredditbandit/pman/pkg/db" bolt "go.etcd.io/bbolt" + + "github.com/theredditbandit/pman/pkg/db" ) const dbname = db.DBTestName diff --git a/pkg/ui/tui.go b/pkg/ui/tui.go index 32c5a91..94dc92d 100644 --- a/pkg/ui/tui.go +++ b/pkg/ui/tui.go @@ -25,8 +25,8 @@ var ( ) type item struct { - name string - status string + name string + status string } func (i item) Title() string { return i.name } From 0071999cb0c9fff6b4c80b7f136a740813ce9122 Mon Sep 17 00:00:00 2001 From: aryan <85390033+theredditbandit@users.noreply.github.com> Date: Tue, 14 May 2024 22:18:01 +0530 Subject: [PATCH 10/10] remove generated files --- .gitignore | 1 + .idea/modules.xml | 8 ---- .idea/pman.iml | 9 ----- .idea/vcs.xml | 6 --- .idea/workspace.xml | 96 --------------------------------------------- 5 files changed, 1 insertion(+), 119 deletions(-) delete mode 100644 .idea/modules.xml delete mode 100644 .idea/pman.iml delete mode 100644 .idea/vcs.xml delete mode 100644 .idea/workspace.xml diff --git a/.gitignore b/.gitignore index 971889a..116f2a2 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ go.work # End of https://www.toptal.com/developers/gitignore/api/go pman coverage.out +.idea/* diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 6e5838d..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/pman.iml b/.idea/pman.iml deleted file mode 100644 index 5e764c4..0000000 --- a/.idea/pman.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml deleted file mode 100644 index 8d61fef..0000000 --- a/.idea/workspace.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - - - - \ No newline at end of file