CLI To-Do List in Go

List Topics
February 18, 2025
No Comments
8 min read

Here’s how you can create a command-line application in Go to manage a to-do list with the ability to add, remove, and list tasks, and save tasks to a file (JSON or text).

Key Concepts:

  • File Handling: Saving the list of tasks to a file.
  • Structs: Representing each task using a struct.
  • Slices: Storing multiple tasks in a slice.
  • CLI Interaction: Interacting with the user via command-line arguments.

We'll use JSON file format for saving tasks as it’s more structured than plain text.

Step-by-Step Guide:

1. Define Task Struct:

Each task will have a description and a completed status.

2. Handling CLI Commands:

We'll handle commands like add, remove, and list, using the flag package for argument parsing.

3. Save and Load from File:

We'll use the encoding/json package to save and load tasks from a JSON file.

Go Code for To-Do List Application:

Go
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
)

// Define the Task struct
type Task struct {
	Description string `json:"description"`
	Completed   bool   `json:"completed"`
}

var tasks []Task

// Save tasks to a JSON file
func saveTasks(filename string) {
	file, err := os.Create(filename)
	if err != nil {
		fmt.Println("Error creating file:", err)
		return
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	err = encoder.Encode(tasks)
	if err != nil {
		fmt.Println("Error encoding tasks to file:", err)
		return
	}
	fmt.Println("Tasks saved to file successfully!")
}

// Load tasks from a JSON file
func loadTasks(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		if os.IsNotExist(err) {
			// If the file doesn't exist, return empty task list
			return
		}
		fmt.Println("Error opening file:", err)
		return
	}
	defer file.Close()

	decoder := json.NewDecoder(file)
	err = decoder.Decode(&tasks)
	if err != nil {
		fmt.Println("Error decoding tasks from file:", err)
		return
	}
}

// List all tasks
func listTasks() {
	if len(tasks) == 0 {
		fmt.Println("No tasks to show!")
		return
	}
	fmt.Println("Your To-Do List:")
	for i, task := range tasks {
		status := "Incomplete"
		if task.Completed {
			status = "Completed"
		}
		fmt.Printf("%d. %s [%s]\n", i+1, task.Description, status)
	}
}

// Add a new task
func addTask(description string) {
	task := Task{Description: description, Completed: false}
	tasks = append(tasks, task)
	fmt.Println("Task added successfully!")
}

// Remove a task by index
func removeTask(index int) {
	if index < 1 || index > len(tasks) {
		fmt.Println("Invalid task number!")
		return
	}
	tasks = append(tasks[:index-1], tasks[index:]...)
	fmt.Println("Task removed successfully!")
}

// Mark a task as completed
func completeTask(index int) {
	if index < 1 || index > len(tasks) {
		fmt.Println("Invalid task number!")
		return
	}
	tasks[index-1].Completed = true
	fmt.Println("Task marked as completed!")
}

func main() {
	// Command-line flags
	addFlag := flag.String("add", "", "Add a new task to the list")
	removeFlag := flag.Int("remove", -1, "Remove a task by its number")
	completeFlag := flag.Int("complete", -1, "Mark a task as completed")
	listFlag := flag.Bool("list", false, "List all tasks")
	fileFlag := flag.String("file", "tasks.json", "File to store tasks")

	// Parse flags
	flag.Parse()

	// Load tasks from the file when the program starts
	loadTasks(*fileFlag)

	// Handle different commands based on the flags
	if *listFlag {
		listTasks()
	} else if *addFlag != "" {
		addTask(*addFlag)
	} else if *removeFlag != -1 {
		removeTask(*removeFlag)
	} else if *completeFlag != -1 {
		completeTask(*completeFlag)
	} else {
		fmt.Println("Usage: -add <task>, -remove <task number>, -complete <task number>, -list")
	}

	// Save tasks back to the file after performing the operation
	saveTasks(*fileFlag)
}

Explanation of the Code:

  1. Task Struct:
    • Task struct has two fields: Description for the task description and Completed to track whether the task is completed or not.
  2. Save and Load Tasks:
    • saveTasks function saves the tasks to a JSON file using the json.NewEncoder.
    • loadTasks loads the tasks from a JSON file using json.NewDecoder.
  3. Task Management:
    • listTasks: Displays the list of tasks, showing their completion status.
    • addTask: Adds a new task to the list.
    • removeTask: Removes a task by its index number.
    • completeTask: Marks a task as completed by updating its Completed field to true.
  4. CLI Interaction:
    • flag package is used to define flags like -add, -remove, -complete, -list, and -file to interact with the application via the command line.
    • The flags are parsed, and the relevant operations are performed based on the flags provided by the user.
  5. File Handling:
    • Tasks are saved in a file specified by the -file flag (default is tasks.json).
    • When the application starts, it loads the tasks from the file.

Usage Example:

1. Adding a Task:

Bash
go run main.go -add "Buy groceries" -file tasks.json

2. Listing Tasks:

Bash
go run main.go -list -file tasks.json

3. Removing a Task:

Bash
go run main.go -remove 1 -file tasks.json

4. Marking a Task as Completed:

Bash
go run main.go -complete 1 -file tasks.json

Output Example:

After adding tasks:

Bash
go run main.go -add "Buy groceries" -file tasks.json
go run main.go -add "Walk the dog" -file tasks.json

Listing tasks:

Bash
go run main.go -list -file tasks.json

Output:

LESS
Your To-Do List:
1. Buy groceries [Incomplete]
2. Walk the dog [Incomplete]

After marking a task as completed:

Bash
go run main.go -complete 1 -file tasks.json
go run main.go -list -file tasks.json

Output:

LESS
Your To-Do List:
1. Buy groceries [Completed]
2. Walk the dog [Incomplete]

Conclusion:

This Go program allows you to manage a to-do list from the command line. It uses basic Go concepts like structs, slices, and file handling to provide functionalities for adding, removing, completing, and listing tasks. Tasks are saved to a JSON file, so your data persists even after the program exits.


এখানে Go ভাষায় একটি টু-ডু লিস্ট ম্যানেজমেন্ট অ্যাপ্লিকেশন তৈরি করার প্রক্রিয়া দেওয়া হলো, যার মাধ্যমে আপনি টাস্ক যোগ, মুছে ফেলা, লিস্ট করা এবং একটি ফাইলে (JSON বা টেক্সট) টাস্ক সংরক্ষণ করতে পারবেন।

মূল কনসেপ্ট:

  • ফাইল হ্যান্ডলিং: টাস্ক সংরক্ষণের জন্য ফাইল ব্যবহার।
  • স্ট্রাক্টস: প্রতিটি টাস্ককে একটি স্ট্রাক্টে উপস্থাপন করা।
  • স্লাইস: একাধিক টাস্ক সঞ্চয় করার জন্য স্লাইস ব্যবহার।
  • CLI ইন্টারঅ্যাকশন: কমান্ড-লাইন আর্গুমেন্ট দিয়ে ব্যবহারকারীর সাথে ইন্টারঅ্যাকশন।

এখানে আমরা JSON ফাইল ফরম্যাট ব্যবহার করব কারণ এটি প্লেইন টেক্সটের চেয়ে বেশি কাঠামোবদ্ধ।

স্টেপ-বাই-স্টেপ গাইড:

1. টাস্ক স্ট্রাক্ট ডিফাইন করা:

প্রতিটি টাস্কের একটি বর্ণনা এবং একটি সম্পন্ন হওয়া স্ট্যাটাস থাকবে।

2. CLI কমান্ড হ্যান্ডলিং:

আমরা add, remove, এবং list কমান্ডগুলি হ্যান্ডল করব, যার জন্য flag প্যাকেজ ব্যবহার করা হবে।

3. ফাইলে সংরক্ষণ এবং লোড করা:

টাস্কগুলি JSON ফরম্যাটে সংরক্ষণ এবং লোড করতে encoding/json প্যাকেজ ব্যবহার করা হবে।

টু-ডু লিস্ট অ্যাপ্লিকেশন এর Go কোড:

Go
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
)

// Task স্ট্রাক্ট ডিফাইন করা
type Task struct {
	Description string `json:"description"`
	Completed   bool   `json:"completed"`
}

var tasks []Task

// টাস্কগুলি JSON ফাইলে সংরক্ষণ করা
func saveTasks(filename string) {
	file, err := os.Create(filename)
	if err != nil {
		fmt.Println("ফাইল তৈরি করতে সমস্যা:", err)
		return
	}
	defer file.Close()

	encoder := json.NewEncoder(file)
	err = encoder.Encode(tasks)
	if err != nil {
		fmt.Println("টাস্ক ফাইলে কোড করতে সমস্যা:", err)
		return
	}
	fmt.Println("টাস্কগুলি সফলভাবে ফাইলে সংরক্ষিত!")
}

// JSON ফাইল থেকে টাস্ক লোড করা
func loadTasks(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		if os.IsNotExist(err) {
			// যদি ফাইল না থাকে, তাহলে খালি টাস্ক লিস্ট ফেরত দেওয়া
			return
		}
		fmt.Println("ফাইল খুলতে সমস্যা:", err)
		return
	}
	defer file.Close()

	decoder := json.NewDecoder(file)
	err = decoder.Decode(&tasks)
	if err != nil {
		fmt.Println("টাস্ক ফাইল থেকে ডিকোড করতে সমস্যা:", err)
		return
	}
}

// সমস্ত টাস্কের তালিকা দেখানো
func listTasks() {
	if len(tasks) == 0 {
		fmt.Println("দেখানোর জন্য কোন টাস্ক নেই!")
		return
	}
	fmt.Println("আপনার টু-ডু লিস্ট:")
	for i, task := range tasks {
		status := "অপূর্ণ"
		if task.Completed {
			status = "সম্পন্ন"
		}
		fmt.Printf("%d. %s [%s]\n", i+1, task.Description, status)
	}
}

// নতুন টাস্ক যোগ করা
func addTask(description string) {
	task := Task{Description: description, Completed: false}
	tasks = append(tasks, task)
	fmt.Println("টাস্ক সফলভাবে যোগ করা হয়েছে!")
}

// একটি টাস্ক তার নাম্বার দিয়ে মুছে ফেলা
func removeTask(index int) {
	if index < 1 || index > len(tasks) {
		fmt.Println("অবৈধ টাস্ক নাম্বার!")
		return
	}
	tasks = append(tasks[:index-1], tasks[index:]...)
	fmt.Println("টাস্ক সফলভাবে মুছে ফেলা হয়েছে!")
}

// একটি টাস্ক সম্পন্ন হিসেবে চিহ্নিত করা
func completeTask(index int) {
	if index < 1 || index > len(tasks) {
		fmt.Println("অবৈধ টাস্ক নাম্বার!")
		return
	}
	tasks[index-1].Completed = true
	fmt.Println("টাস্ক সম্পন্ন হিসেবে চিহ্নিত করা হয়েছে!")
}

func main() {
	// কমান্ড-লাইন ফ্ল্যাগস
	addFlag := flag.String("add", "", "একটি নতুন টাস্ক যোগ করুন")
	removeFlag := flag.Int("remove", -1, "টাস্ক নাম্বার দিয়ে মুছে ফেলুন")
	completeFlag := flag.Int("complete", -1, "টাস্ক সম্পন্ন হিসেবে চিহ্নিত করুন")
	listFlag := flag.Bool("list", false, "সব টাস্ক দেখুন")
	fileFlag := flag.String("file", "tasks.json", "টাস্কগুলি সংরক্ষণের ফাইল")

	// ফ্ল্যাগ প্যার্স করা
	flag.Parse()

	// প্রোগ্রাম চালানোর সময় ফাইল থেকে টাস্ক লোড করা
	loadTasks(*fileFlag)

	// ফ্ল্যাগ অনুযায়ী অপারেশন সম্পাদন
	if *listFlag {
		listTasks()
	} else if *addFlag != "" {
		addTask(*addFlag)
	} else if *removeFlag != -1 {
		removeTask(*removeFlag)
	} else if *completeFlag != -1 {
		completeTask(*completeFlag)
	} else {
		fmt.Println("ব্যবহার: -add <task>, -remove <task number>, -complete <task number>, -list")
	}

	// অপারেশন শেষ হওয়ার পর টাস্কগুলি আবার ফাইলে সংরক্ষণ করা
	saveTasks(*fileFlag)
}

কোডের ব্যাখ্যা:

  1. Task স্ট্রাক্ট:
    • Task স্ট্রাক্টে দুটি ফিল্ড রয়েছে: Description (টাস্কের বর্ণনা) এবং Completed (টাস্কটি সম্পন্ন হয়েছে কিনা)।
  2. টাস্ক সংরক্ষণ ও লোড করা:
    • saveTasks ফাংশনটি JSON ফাইলে টাস্কগুলি সংরক্ষণ করে।
    • loadTasks ফাংশনটি JSON ফাইল থেকে টাস্কগুলি লোড করে।
  3. টাস্ক ম্যানেজমেন্ট:
    • listTasks: টাস্কগুলির তালিকা দেখায়, তাদের সম্পন্ন স্ট্যাটাসও দেখানো হয়।
    • addTask: নতুন একটি টাস্ক যোগ করে।
    • removeTask: একটি টাস্ক তার নাম্বার দিয়ে মুছে ফেলে।
    • completeTask: একটি টাস্ক সম্পন্ন হিসেবে চিহ্নিত করে।
  4. CLI ইন্টারঅ্যাকশন:
    • flag প্যাকেজ ব্যবহার করে ফ্ল্যাগগুলি ডিফাইন করা হয়েছে, যেমন -add, -remove, -complete, -list, এবং -file
    • ফ্ল্যাগগুলি প্যার্স করে, অনুযায়ী অপারেশন কার্যকর করা হয়।
  5. ফাইল হ্যান্ডলিং:
    • টাস্কগুলি একটি ফাইলে সংরক্ষিত থাকে (ফাইল নাম tasks.json ডিফল্ট)। প্রোগ্রাম শুরু হওয়ার সময় ফাইল থেকে টাস্কগুলি লোড হয়।

ব্যবহারের উদাহরণ:

1. টাস্ক যোগ করা:

Bash
go run main.go -add "Buy groceries" -file tasks.json

2. টাস্কের তালিকা দেখানো:

Bash
go run main.go -list -file tasks.json

3. টাস্ক মুছে ফেলা:

Bash
go run main.go -remove 1 -file tasks.json

4. টাস্ক সম্পন্ন হিসেবে চিহ্নিত করা:

Bash
go run main.go -complete 1 -file tasks.json

আউটপুট উদাহরণ:

টাস্ক যোগ করার পর:

Bash
go run main.go -add "Buy groceries" -file tasks.json
go run main.go -add "Walk the dog" -file tasks.json

টাস্কের তালিকা দেখানো:

Bash
go run main.go -list -file tasks.json

আউটপুট:

LESS
Your To-Do List:
1. Buy groceries [Incomplete]
2. Walk the dog [Incomplete]

একটি টাস্ক সম্পন্ন হিসেবে চিহ্নিত করার পর:

Bash
go run main.go -complete 1 -file tasks.json
go run main.go -list -file tasks.json

আউটপুট:

LESS
Your To-Do List:
1. Buy groceries [Completed]
2. Walk the dog [Incomplete]

উপসংহার:

এই Go প্রোগ্রামটি আপনাকে কমান্ড-লাইন থেকে একটি টু-ডু লিস্ট ম্যানেজ করতে সাহায্য করবে। এতে স্লাইস, স্ট্রাক্টস, এবং ফাইল হ্যান্ডলিংয়ের মতো গুরত্বপূর্ণ Go কনসেপ্ট ব্যবহার করা হয়েছে। টাস্কগুলি একটি JSON ফাইলে সংরক্ষিত থাকে, তাই আপনার ডেটা প্রোগ্রাম বন্ধ হওয়ার পরও সঞ্চিত থাকবে।

©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.