Skip to content

Commit 76b0bd1

Browse files
committed
Add CLI commands and improve project functionality
1 parent f4356f3 commit 76b0bd1

File tree

11 files changed

+214
-0
lines changed

11 files changed

+214
-0
lines changed

cmd/add.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"to_do_cli/todo"
6+
7+
"github.com/spf13/cobra"
8+
)
9+
10+
var addCmd = &cobra.Command{
11+
Use: "add [task description]",
12+
Short: "Add a new task to the todo list",
13+
Args: cobra.ExactArgs(1),
14+
Run: func(cmd *cobra.Command, args []string) {
15+
taskName := args[0]
16+
17+
tasks, err := todo.LoadTasks("tasks.json")
18+
if err != nil {
19+
fmt.Printf("Error loading tasks: %v\n", err)
20+
return
21+
}
22+
23+
m := todo.NewManager()
24+
for _, t := range tasks {
25+
m.AddTask(t.Name)
26+
if t.Completed {
27+
_ = m.CompletedTask(t.ID)
28+
}
29+
}
30+
31+
task := m.AddTask(taskName)
32+
err = todo.SaveTasks("tasks.json", m.GetTasks())
33+
if err != nil {
34+
fmt.Println("Error saving tasks:", err)
35+
return
36+
}
37+
38+
fmt.Println("✅ Added task:", task.Name)
39+
},
40+
}
41+
42+
func init() {
43+
rootCmd.AddCommand(addCmd)
44+
}

cmd/list.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"to_do_cli/todo"
6+
7+
"github.com/spf13/cobra"
8+
)
9+
10+
var listCmd = &cobra.Command{
11+
Use: "list",
12+
Short: "List all tasks in the todo list",
13+
Run: func(cmd *cobra.Command, args []string) {
14+
tasks, err := todo.LoadTasks("tasks.json")
15+
if err != nil {
16+
fmt.Printf("Error loading tasks: %v\n", err)
17+
return
18+
}
19+
20+
fmt.Println(tasks)
21+
},
22+
}
23+
24+
func init() {
25+
rootCmd.AddCommand(listCmd)
26+
}

cmd/root.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package cmd
2+
3+
import "github.com/spf13/cobra"
4+
5+
var rootCmd = &cobra.Command{
6+
Use: "todo",
7+
Short: "A simple command line todo application",
8+
Long: `A simple command line todo application to manage your tasks.`,
9+
Run: func(cmd *cobra.Command, args []string) {
10+
cmd.Help() // Display help if no subcommand is provided
11+
},
12+
}
13+
14+
func Execute() error {
15+
return rootCmd.Execute()
16+
}

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
module to_do_cli
22

33
go 1.24.1
4+
5+
require (
6+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
7+
github.com/spf13/cobra v1.9.1 // indirect
8+
github.com/spf13/pflag v1.0.6 // indirect
9+
)

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
2+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
3+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
4+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
5+
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
6+
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
7+
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
8+
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
9+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
10+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
11
package main
2+
3+
import (
4+
"fmt"
5+
"to_do_cli/cmd"
6+
)
7+
8+
func main() {
9+
err := cmd.Execute()
10+
if err != nil {
11+
fmt.Printf("Error executing command: %v\n", err)
12+
}
13+
}

tasks.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[
2+
{
3+
"id": 1,
4+
"name": "hello",
5+
"completed": false,
6+
"created_at": "2025-07-27T20:30:05.4113+06:30",
7+
"updated_at": "2025-07-27T20:30:05.4113+06:30"
8+
},
9+
{
10+
"id": 2,
11+
"name": "Complete project documentation",
12+
"completed": false,
13+
"created_at": "2025-07-27T20:30:05.4113+06:30",
14+
"updated_at": "2025-07-27T20:30:05.4113+06:30"
15+
}
16+
]

to_do_cli

3.74 MB
Binary file not shown.

todo/storage.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,40 @@
11
package todo
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
)
7+
8+
func SaveTasks(filename string, tasks []Task) error {
9+
data, err := json.Marshal(tasks)
10+
if err != nil {
11+
return err
12+
}
13+
return os.WriteFile(filename, data, 0644)
14+
}
15+
16+
func LoadTasks(filename string) ([]Task, error) {
17+
_, err := os.Stat(filename) // Ensure the file exists
18+
if os.IsNotExist(err) {
19+
return nil, nil // Return empty slice if file does not exist
20+
}
21+
if err != nil {
22+
return nil, err // Return error if there is another issue
23+
}
24+
25+
data, err := os.ReadFile(filename)
26+
if err != nil {
27+
return nil, err
28+
}
29+
30+
if len(data) == 0 {
31+
return []Task{}, nil // 🛠️ <- Fix: Handle empty file
32+
}
33+
34+
var tasks []Task
35+
err = json.Unmarshal(data, &tasks)
36+
if err != nil {
37+
return nil, err
38+
}
39+
return tasks, nil
40+
}

todo/storage_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,30 @@
11
package todo
2+
3+
import "testing"
4+
5+
func TestSaveTask(t *testing.T) {
6+
tasks := []Task{
7+
{ID: 1, Name: "Test Task 1", Completed: false},
8+
{ID: 2, Name: "Test Task 2", Completed: true},
9+
}
10+
11+
err := SaveTasks("test_tasks.json", tasks)
12+
if err != nil {
13+
t.Fatalf("Failed to save tasks: %v", err)
14+
}
15+
}
16+
17+
func TestLoadTask(t *testing.T) {
18+
tasks, err := LoadTasks("test_tasks.json")
19+
if err != nil {
20+
t.Fatalf("Failed to load tasks: %v", err)
21+
}
22+
23+
if len(tasks) != 2 {
24+
t.Fatalf("Expected 2 tasks, got %d", len(tasks))
25+
}
26+
27+
if tasks[0].Name != "Test Task 1" || tasks[1].Name != "Test Task 2" {
28+
t.Fatalf("Loaded tasks do not match expected values")
29+
}
30+
}

0 commit comments

Comments
 (0)