├── students └── README.md ├── .gitignore └── README.md /students/README.md: -------------------------------------------------------------------------------- 1 | # Student Examples 2 | 3 | The following are example implementations submitted by students/gophers learning from this course. 4 | 5 | The primary purposes of these examples are: 6 | 7 | 1. To provide example implementations to discuss and review when recording the screencasts for this course. 8 | 2. To provide a way for students to contribute to this course. 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | 16 | tmp/* 17 | task 18 | tasks.db 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exercise #7: CLI Task Manager 2 | 3 | [![exercise status: released](https://img.shields.io/badge/exercise%20status-released-green.svg?style=for-the-badge)](https://gophercises.com/exercises/task) 4 | 5 | ## Exercise details 6 | 7 | In this exercise we are going to be building a CLI tool that can be used to manage your TODOs in the terminal. The basic usage of the tool is going to look roughly like this: 8 | 9 | ``` 10 | $ task 11 | task is a CLI for managing your TODOs. 12 | 13 | Usage: 14 | task [command] 15 | 16 | Available Commands: 17 | add Add a new task to your TODO list 18 | do Mark a task on your TODO list as complete 19 | list List all of your incomplete tasks 20 | 21 | Use "task [command] --help" for more information about a command. 22 | 23 | $ task add review talk proposal 24 | Added "review talk proposal" to your task list. 25 | 26 | $ task add clean dishes 27 | Added "clean dishes" to your task list. 28 | 29 | $ task list 30 | You have the following tasks: 31 | 1. review talk proposal 32 | 2. some task description 33 | 34 | $ task do 1 35 | You have completed the "review talk proposal" task. 36 | 37 | $ task list 38 | You have the following tasks: 39 | 1. some task description 40 | ``` 41 | 42 | *Note: Lines prefixed with `$` are lines where we type into the terminal, and other lines are output from our program.* 43 | 44 | Your final CLI won't need to look exactly like this, but this is what I roughly expect mine to look like. In the bonus section we will also discuss a few extra features we could add, but for now we will stick with the three show above: 45 | 46 | - `add` - adds a new task to our list 47 | - `list` - lists all of our incomplete tasks 48 | - `do` - marks a task as complete 49 | 50 | In order to build this tool we are going to need to explore a few different topics. Most notably, we will need to: 51 | 52 | 1. Learn about creating command line interfaces (CLIs) 53 | 2. Interact with a database. We will be using BoltDB in this exercise so we can learn about it. 54 | 3. Figure out how to store our database file on different operating systems. This will basically boil down to learning about home directories. 55 | 4. Exit codes (briefly) 56 | 5. And probably more. I'll update this list once the exercise is done. 57 | 58 | You are welcome to tackle the problem however you see fit, but below is the order I would recommend to start. 59 | 60 | ### 1. Build the CLI shell 61 | 62 | For building the CLI, I highly recommend using a third party package (library, framework, or whatever you want to call it). You can do this exercise without one, but there are a lot of edge cases you will need to handle on your own and in this case I think it is best to just pick an existing library to use. 63 | 64 | There are a lot of CLI libraries, and you can find most of them here: 65 | 66 | When I code this exercise I intend to use [spf13/cobra](https://github.com/spf13/cobra). It isn't necessarily better than others out there, but it is one I have used in the past and I know it will serve my needs. 67 | 68 | Once you decide on a library, use it to create the original `task` command that displays all your subcommands, and then create stubbed subcommands for each of the actions we discussed above. The actions don't actually have to do anything with a database just yet, but we want to make sure the user typing each individual command will result in a different piece of code running. 69 | 70 | For instance, let's say we defined the `task list` command to run the following Go code: 71 | 72 | ```go 73 | fmt.Println("This is a fake \"list\" command") 74 | ``` 75 | 76 | Then when we used that command with our CLI we should see the following: 77 | 78 | ``` 79 | $ task list 80 | This is a fake "list" command 81 | ``` 82 | 83 | After stubbing out all 3 commands, try to also look at how to parse arguments for the `task do` and `task add` commands. 84 | 85 | ### 2. Write the BoltDB interactions 86 | 87 | After stubbing out your CLI commands, try writing code that will read, add, and delete data in a BoltDB database. You can find more information about using Bolt here: 88 | 89 | *Note: I know many people claim `bolt` is abandoned, but that is inaccurate in my opinion. Instead, I would consider it a stable, completed project that no longer needs any active development. That said, there is a fork of the library created by the CoreOS team which can be found here: * 90 | 91 | For now, don't worry about where you store the database that bolt connects to. At this stage I intend to just use whatever directory the `task` command was run from, so I will be using code roughly like this: 92 | 93 | ```go 94 | db, err := bolt.Open("tasks.db", 0600, nil) 95 | ``` 96 | 97 | Later you can dig into how to install the application so that it can be run from anywhere and it will persist our tasks regardless of where we run the CLI. 98 | 99 | ### 3. Putting it all together 100 | 101 | Finally, put the two pieces your wrote together so that when someone types `task add some task` it adds that task to the boltdb. 102 | 103 | After that, explore how to setup and install the application so that it can be run from any directory in your terminal. This might require you to look into how to find a user's home directory on any OS (Windows, Mac OS, Linux, etc). 104 | 105 | If you'd like, you can look into how to determine this on your own, but I recommend just grabbing this package: . You can read over the code to see how it works - it is only 137 lines of code - but it should take care of all the oddities between different operating systems for us. 106 | 107 | After that you will need to look into how to install a binary on your computer. The first place I suggest starting is the `go install` command. (*Hint: Try `go install --help` to see what this command does.*). This is likely to be the simplest route, but there are other options (like manually copying a binary to a directory in your `$PATH`). 108 | 109 | *Note: I suspect many users will have issues around here that are OS specific. If you do, please first check the [Github issues](https://github.com/gophercises/task/issues?utf8=%E2%9C%93&q=is%3Aissue) to see if there are any open or closed issues that are similar to your problem. I'm hoping to use that as a nice Q&A section for this exercise.* 110 | 111 | If all goes well you should have a complete CLI for managing your tasks installed once done with this section. 112 | 113 | 114 | ## Bonus 115 | 116 | As a bonus exercise, I recommend working on the following two new commands: 117 | 118 | ``` 119 | $ task rm 1 120 | You have deleted the "review talk proposal" task. 121 | 122 | $ task completed 123 | You have finished the following tasks today: 124 | - wash the dishes 125 | - clean the car 126 | ``` 127 | 128 | The `rm` command will delete a task instead of completing it. 129 | 130 | The `completed` command will list out any tasks completed in the same day. You can define this however you want (last 12hrs, last 24hrs, or the same calendar date). 131 | 132 | The first version of our CLI could get away with deleting tasks from the DB, but if you want these features to work you are likely going to need to tweak your DB design a bit. I'll leave that as an exercise for you to try out on your own, but if you need help feel free to get in touch - 133 | --------------------------------------------------------------------------------