diff --git a/README.md b/README.md index c6e3f82..5d0d780 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A simple command-line Todo application written in Go. Todos are stored in a SQLi - Mark todos as completed - Remove todos by ID - Data is persisted in SQLite database +- User-friendly command-line interface with action commands ## Dependencies @@ -23,44 +24,52 @@ Build the app: go build -o todo ``` -### Add a Todo +### Command Structure + +The app uses a command-based interface where the action comes first, followed by flags: ```sh -./todo -action=add -title="Buy milk" -description="Get 2 liters of milk" +./todo [action] [flags] ``` -### List Todos +Available actions: +- `add` - Add a new todo item +- `remove` - Remove a todo item +- `complete` - Mark a todo item as completed +- `list` - List all todo items +### Flags + +- `-t, --title` - Title for the todo (required for add) +- `-d, --description` - Description for the todo (required for add) +- `-i, --id` - ID of the todo (required for remove and complete) +- `-h, --help` - Display help information + +### Examples + +Add a new todo: ```sh -./todo -action=list +./todo add -t "Buy milk" -d "Get 2 liters of milk" ``` -### Complete a Todo - +List all todos: ```sh -./todo -action=complete -id=1 +./todo list ``` -### Remove a Todo - +Complete a todo: ```sh -./todo -action=remove -id=1 +./todo complete -i 1 ``` -## Flags - -- `-action` (add, remove, list, complete) — What you want to do -- `-title` — Title for the todo (required for add) -- `-description` — Description for the todo (required for add) -- `-id` — ID of the todo (required for remove and complete) - -## Example - +Remove a todo: ```sh -./todo -action=add -title="Read Go book" -description="Finish chapter 3" -./todo -action=list -./todo -action=complete -id=1 -./todo -action=remove -id=1 +./todo remove -i 2 +``` + +Display help: +```sh +./todo -h ``` ## Next Improvements @@ -70,3 +79,6 @@ go build -o todo - Add unit tests - Improve error handling - Add binary release for different platforms and make it available through Homebrew, Winget and Apt +- Add due dates and priority levels for todos +- Implement categories/tags for better organization +- Add data export/import functionality diff --git a/main.go b/main.go index 567e597..6f22962 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "log" + "os" _ "github.com/mattn/go-sqlite3" ) @@ -96,13 +97,41 @@ func removeTodo(db *sql.DB, id int) error { } var ( - action = flag.String("action", "add", "action (add, remove, list, complete)") - title = flag.String("title", "", "title of the todo") - description = flag.String("description", "", "description of the todo") - id = flag.Int("id", 0, "ID of the todo to be actioned upon. Used for remove and complete") + title = flag.String("title", "", "Title of the todo item") + description = flag.String("description", "", "Description of the todo item") + id = flag.Int("id", 0, "ID of the todo item to remove or mark as complete") ) +func init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Todo CLI - A simple todo list manager\n\n") + fmt.Fprintf(os.Stderr, "Usage:\n %s [action] [flags]\n\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "Actions:\n") + fmt.Fprintf(os.Stderr, " add Add a new todo item\n") + fmt.Fprintf(os.Stderr, " remove Remove a todo item\n") + fmt.Fprintf(os.Stderr, " complete Mark a todo item as completed\n") + fmt.Fprintf(os.Stderr, " list List all todo items\n\n") + fmt.Fprintf(os.Stderr, "Flags:\n") + flag.PrintDefaults() + fmt.Fprintf(os.Stderr, "\nExamples:\n") + fmt.Fprintf(os.Stderr, " %s add -t \"Meeting\" -d \"Team standup at 10AM\"\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " %s complete -i 1\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " %s remove -i 2\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " %s list\n", os.Args[0]) + } + + flag.StringVar(title, "t", "", "shorthand for --title") + flag.StringVar(description, "d", "", "shorthand for --description") + flag.IntVar(id, "i", 0, "shorthand for --id") +} + func main() { + // Check for help flag before any other operations + if len(os.Args) > 1 && (os.Args[1] == "-h" || os.Args[1] == "--help") { + flag.Usage() + os.Exit(0) + } + db, err := sql.Open("sqlite3", "./todos.db") if err != nil { log.Fatal(err) @@ -114,8 +143,14 @@ func main() { log.Fatal(err) } + if len(os.Args) < 2 { + flag.Usage() + os.Exit(1) + } + action := os.Args[1] + os.Args = os.Args[1:] flag.Parse() - switch *action { + switch action { case "add": handleAdd(db) case "remove": diff --git a/todo b/todo index 5f1e7b3..45a2111 100755 Binary files a/todo and b/todo differ